<?php

namespace App\Http\Controllers\Agency;

use App\Http\Controllers\Controller;
use App\Models\Agency\AgencyStaff;
use App\Models\Definition\GuideChamber;
use App\Models\Resource;
use App\Models\ResourceCostItem;
use App\Models\ResourceImage;
use App\Models\ResourceSchedule;
use App\Models\Supplier\Supplier;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Spatie\Permission\Models\Role;

class ResourceController extends Controller
{
    public function index(Request $request)
    {
        $agencyId = Auth::user()->currentAgencyId();

        $query = Resource::byAgency($agencyId)->with(['supplier', 'user', 'costItems', 'coverImage.diskItem']);

        // Filters
        if ($request->filled('type')) {
            $query->byType($request->type);
        }
        if ($request->filled('source_type')) {
            $query->where('source_type', $request->source_type);
        }
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('vehicle_plate', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%")
                  ->orWhere('phone', 'like', "%{$search}%");
            });
        }
        if ($request->filled('status')) {
            $query->where('is_active', $request->status === 'active');
        }

        // Sort
        $allowedSorts = ['name', 'type', 'source_type', 'is_active', 'created_at'];
        $sort = in_array($request->get('sort'), $allowedSorts, true) ? $request->get('sort') : 'name';
        $dir = $request->get('dir') === 'desc' ? 'desc' : 'asc';
        $query->orderBy($sort, $dir);

        // Pagination
        $perPage = (int) $request->input('per_page', 15);
        $perPage = in_array($perPage, [15, 30, 60, 100], true) ? $perPage : 15;
        $resources = $query->paginate($perPage)->withQueryString();

        return view('agency.resources.index', compact('resources'));
    }

    /**
     * Hızlı taslak kaynak oluşturup quick-view drawer URL'i döner
     * (global "+" ve liste "Yeni" butonu; statik create sayfası yerine).
     * ?type=guide|vehicle|captain — tip yapısal olduğundan baştan seçilir.
     */
    public function quickCreate(Request $request)
    {
        $agencyId = Auth::user()->currentAgencyId();
        $type = in_array($request->input('type'), ['guide', 'vehicle', 'captain'], true)
            ? $request->input('type') : 'guide';
        $names = ['guide' => 'Yeni Rehber', 'vehicle' => 'Yeni Araç', 'captain' => 'Yeni Kaptan'];

        $resource = Resource::create([
            'agency_id' => $agencyId,
            'type' => $type,
            'source_type' => 'internal',
            'name' => $names[$type],
            'is_active' => false,
        ]);

        return response()->json([
            'success' => true,
            'quick_view_url' => route('agency.resources.quick-view', $resource),
        ]);
    }

    public function create()
    {
        $agencyId = Auth::user()->currentAgencyId();
        $suppliers = Supplier::byAgency($agencyId)->active()->orderBy('company_name')->get();
        
        // Fetch users who belong to the current agency to link them as guide or captain accounts
        $users = User::byAgency($agencyId)->active()->orderBy('first_name')->get();
        $roles = $this->agencyRoles($agencyId);

        $languages = \App\Models\Definition\Language::orderBy('name')->pluck('name')->unique()->values();
        $costTitles = ResourceCostItem::titleSuggestions($agencyId);
        $chambers = GuideChamber::options();

        return view('agency.resources.create', compact('suppliers', 'users', 'roles', 'languages', 'costTitles', 'chambers'));
    }

    /**
     * Kaynak form doğrulama mesajları.
     *
     * Projede lang/tr/validation.php yok ve locale 'tr' — mesajlar geçilmezse
     * kullanıcıya ham "validation.required" anahtarı görünür.
     */
    private function validationMessages(): array
    {
        return [
            'type.required' => 'Kaynak tipi zorunludur.',
            'type.in' => 'Geçersiz kaynak tipi.',
            'source_type.required' => 'Tedarik şekli zorunludur.',
            'source_type.in' => 'Geçersiz tedarik şekli.',
            'name.required' => 'Ad/tanım zorunludur.',
            'name.max' => 'Ad en fazla 255 karakter olabilir.',
            'first_name.required' => 'Ad zorunludur.',
            'first_name.max' => 'Ad en fazla 255 karakter olabilir.',
            'last_name.required' => 'Soyad zorunludur.',
            'last_name.max' => 'Soyad en fazla 255 karakter olabilir.',
            'email.email' => 'Geçerli bir e-posta adresi giriniz.',
            'phone.max' => 'Telefon en fazla 30 karakter olabilir.',
            'identity_number.max' => 'Kimlik no en fazla 50 karakter olabilir.',
            'supplier_id.required' => 'Dış kaynak seçildiğinde tedarikçi zorunludur.',
            'supplier_id.exists' => 'Seçilen tedarikçi bulunamadı.',
            'user_id.exists' => 'Seçilen kullanıcı bulunamadı.',
            'cost_items.*.title.required_with' => 'Maliyet başlığı boş bırakılamaz.',
            'cost_items.*.title.max' => 'Maliyet başlığı en fazla 150 karakter olabilir.',
            'cost_items.*.amount.numeric' => 'Maliyet tutarı sayı olmalıdır.',
            'cost_items.*.amount.min' => 'Maliyet tutarı negatif olamaz.',
            'vehicle_brand.required' => 'Araç markası zorunludur.',
            'vehicle_model.required' => 'Araç modeli zorunludur.',
            'vehicle_plate.required' => 'Araç plakası zorunludur.',
            'vehicle_year.integer' => 'Araç yılı sayı olmalıdır.',
            'vehicle_year.min' => 'Araç yılı 1900\'den küçük olamaz.',
            'vehicle_year.max' => 'Araç yılı gelecekte olamaz.',
            'vehicle_km.integer' => 'Kilometre sayı olmalıdır.',
            'vehicle_km.min' => 'Kilometre negatif olamaz.',
            'vehicle_capacity.integer' => 'Kapasite sayı olmalıdır.',
            'vehicle_capacity.min' => 'Kapasite en az 1 olmalıdır.',
            'vehicle_fuel_consumption.numeric' => 'Yakıt tüketimi sayı olmalıdır.',
            'vehicle_registration_document.mimes' => 'Ruhsat yalnızca JPG, PNG, WEBP veya PDF olabilir.',
            'vehicle_registration_document.max' => 'Ruhsat dosyası en fazla 5 MB olabilir.',
            'license_number.max' => 'Lisans no en fazla 100 karakter olabilir.',
            'guide_registration_no.max' => 'Rehber sicil no en fazla 100 karakter olabilir.',
            'guide_chamber_other.required_if' => 'Oda "Diğer" seçildiğinde oda adını yazmalısınız.',
            'guide_chamber_other.max' => 'Bağlı oda en fazla 150 karakter olabilir.',
            'guide_service_info.max' => 'Hizmet bilgisi en fazla 5000 karakter olabilir.',
        ];
    }

    public function store(Request $request)
    {
        $rules = [
            'type' => 'required|in:guide,vehicle,captain',
            'source_type' => 'required|in:internal,external',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:30',
            'identity_number' => 'nullable|string|max:50',
            'supplier_id' => 'nullable|exists:suppliers,id',
            'user_id' => 'nullable|exists:users,id',
            'is_active' => 'boolean',
            'cost_items' => 'nullable|array|max:30',
            'cost_items.*.title' => 'nullable|required_with:cost_items.*.amount|string|max:150',
            'cost_items.*.amount' => 'nullable|numeric|min:0|max:99999999.99',
        ];

        // Type specific validation
        if ($request->type === 'vehicle') {
            // Araçta tek ad alanı (araç tanımı/plaka açıklaması).
            $rules['name'] = 'required|string|max:255';
            $rules['vehicle_class'] = 'nullable|in:binek,lcv,minibus,midibus,otobus';
            $rules['vehicle_brand'] = 'required|string|max:50';
            $rules['vehicle_model'] = 'required|string|max:50';
            $rules['vehicle_plate'] = 'required|string|max:30';
            $rules['vehicle_year'] = 'nullable|integer|min:1900|max:' . (date('Y') + 1);
            $rules['vehicle_km'] = 'nullable|integer|min:0';
            $rules['vehicle_capacity'] = 'nullable|integer|min:1';
            $rules['vehicle_fuel_consumption'] = 'nullable|numeric|min:0';
            $rules['vehicle_registration_document'] = 'nullable|file|mimes:jpg,jpeg,png,webp,pdf|max:5120';
        } else {
            // Rehber/kaptan: ad ve soyad ayrı; `name` model tarafından derlenir.
            $rules['first_name'] = 'required|string|max:255';
            $rules['last_name'] = 'required|string|max:255';
            $rules['license_number'] = 'nullable|string|max:100';
            if ($request->type === 'guide') {
                $rules['languages'] = 'nullable|array';
                $rules['guide_registration_no'] = 'nullable|string|max:100';
                $rules['guide_service_info'] = 'nullable|string|max:5000';
                // Oda tanımlardan seçilir; "Diğer" seçilirse serbest metin zorunlu olur.
                $rules['guide_chamber_select'] = 'nullable|string|max:20';
                $rules['guide_chamber_other'] = 'nullable|required_if:guide_chamber_select,' . GuideChamber::OTHER . '|string|max:150';
            }
        }

        // Dış kaynak her tipte (rehber/araç/kaptan) bir tedarikçiye bağlanır.
        if ($request->source_type === 'external') {
            $rules['supplier_id'] = 'required|exists:suppliers,id';
        }

        // Convert comma-separated languages string to array before validation
        if ($request->type === 'guide') {
            $langsRaw = $request->input('languages', '');
            $langsArr = is_array($langsRaw)
                ? $langsRaw
                : array_filter(array_map('trim', explode(',', $langsRaw)));
            $request->merge(['languages' => array_values($langsArr)]);
        }

        $validated = $request->validate($rules, $this->validationMessages());

        // Kişi kaynaklarında name'i ad+soyaddan derle (NOT NULL kolon güvencesi).
        if ($request->type !== 'vehicle') {
            $validated['name'] = trim(($validated['first_name'] ?? '') . ' ' . ($validated['last_name'] ?? ''));
        }

        $validated['agency_id'] = Auth::user()->currentAgencyId();
        $validated['is_active'] = $request->boolean('is_active', true);

        if ($request->type === 'guide') {
            $validated['languages'] = $request->input('languages', []);
        }

        // Tedarikçi bağlantısı yalnızca dış kaynakta anlamlı; iç kaynakta temizlenir.
        if ($request->source_type !== 'external') {
            $validated['supplier_id'] = null;
        }

        // Araç ruhsatı dosyası
        if ($request->type === 'vehicle' && $request->hasFile('vehicle_registration_document')) {
            $validated['vehicle_registration_document'] = $request->file('vehicle_registration_document')
                ->store('resources/' . $validated['agency_id'] . '/ruhsat', 'public');
        } else {
            unset($validated['vehicle_registration_document']);
        }

        unset($validated['cost_items']); // ayrı tabloda tutulur
        $validated = $this->resolveGuideChamber($request, $validated);

        $resource = Resource::create($validated);
        $this->syncCostItems($resource, $request->input('cost_items', []));

        // Quick-view modalinden geldiyse sayfa değiştirmeden JSON dön.
        if ($request->expectsJson()) {
            return response()->json([
                'success' => true,
                'message' => 'Kaynak başarıyla eklendi.',
                'resource' => $resource,
            ]);
        }

        return redirect()->route('agency.resources.index')
            ->with('success', 'Kaynak başarıyla eklendi.');
    }

    public function edit(Resource $resource)
    {
        $agencyId = Auth::user()->currentAgencyId();
        
        if ($resource->agency_id !== $agencyId) {
            abort(403);
        }

        $resource->load('costItems');

        $suppliers = Supplier::byAgency($agencyId)->active()->orderBy('company_name')->get();
        $users = User::byAgency($agencyId)->active()->orderBy('first_name')->get();
        $roles = $this->agencyRoles($agencyId);

        $languages = \App\Models\Definition\Language::orderBy('name')->pluck('name')->unique()->values();
        $costTitles = ResourceCostItem::titleSuggestions($agencyId);
        $chambers = GuideChamber::options();

        return view('agency.resources.edit', compact('resource', 'suppliers', 'users', 'roles', 'languages', 'costTitles', 'chambers'));
    }

    /** Bu acente için atanabilir roller (süper/sistem admin hariç). */
    private function agencyRoles(int $agencyId)
    {
        return Role::where(function ($q) use ($agencyId) {
                $q->where('agency_id', $agencyId)->orWhereNull('agency_id');
            })
            ->whereNotIn('name', ['super-admin', 'system-admin'])
            ->orderBy('name')
            ->get(['id', 'name']);
    }

    /**
     * Kaynak düzenleme ekranından hızlı sistem kullanıcısı oluşturur ve acenteye bağlar.
     * POST agency/resources/quick-user  → JSON
     */
    public function quickCreateUser(Request $request)
    {
        $agencyId = Auth::user()->currentAgencyId();
        abort_unless($agencyId, 403);

        $validated = $request->validate([
            'first_name' => 'required|string|max:255',
            'last_name' => 'required|string|max:255',
            'email' => 'required|email|max:255|unique:users,email',
            'phone' => 'nullable|string|max:20',
            'password' => 'required|string|min:6',
            'role_id' => 'required|integer|exists:roles,id',
        ]);

        // Rol bu acenteye ait (ya da global) ve izinli olmalı
        $role = $this->agencyRoles($agencyId)->firstWhere('id', (int) $validated['role_id']);
        abort_unless($role, 422, 'Geçersiz rol.');

        $user = DB::transaction(function () use ($validated, $agencyId, $role) {
            $user = User::create([
                'first_name' => $validated['first_name'],
                'last_name' => $validated['last_name'],
                'email' => $validated['email'],
                'phone' => $validated['phone'] ?? null,
                'password' => Hash::make($validated['password']),
                'is_active' => true,
            ]);

            // Acenteye bağla (User::byAgency bunu okur) + rol ata (team context)
            AgencyStaff::create([
                'agency_id' => $agencyId,
                'user_id' => $user->id,
                'first_name' => $validated['first_name'],
                'last_name' => $validated['last_name'],
                'email' => $validated['email'],
                'phone' => $validated['phone'] ?? null,
                'is_active' => true,
                'can_login' => true,
            ]);

            setPermissionsTeamId($agencyId);
            $roleModel = Role::find($role->id);
            if ($roleModel) {
                $user->assignRole($roleModel->name);
            }

            return $user;
        });

        return response()->json([
            'success' => true,
            'message' => 'Kullanıcı oluşturuldu ve kaynağa bağlanmaya hazır.',
            'user' => ['id' => $user->id, 'full_name' => $user->full_name],
        ]);
    }

    public function update(Request $request, Resource $resource)
    {
        $agencyId = Auth::user()->currentAgencyId();
        
        if ($resource->agency_id !== $agencyId) {
            abort(403);
        }

        $rules = [
            'type' => 'required|in:guide,vehicle,captain',
            'source_type' => 'required|in:internal,external',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:30',
            'identity_number' => 'nullable|string|max:50',
            'supplier_id' => 'nullable|exists:suppliers,id',
            'user_id' => 'nullable|exists:users,id',
            'is_active' => 'boolean',
            'cost_items' => 'nullable|array|max:30',
            'cost_items.*.title' => 'nullable|required_with:cost_items.*.amount|string|max:150',
            'cost_items.*.amount' => 'nullable|numeric|min:0|max:99999999.99',
        ];

        // Type specific validation
        if ($request->type === 'vehicle') {
            $rules['name'] = 'required|string|max:255';
            $rules['vehicle_class'] = 'nullable|in:binek,lcv,minibus,midibus,otobus';
            $rules['vehicle_brand'] = 'required|string|max:50';
            $rules['vehicle_model'] = 'required|string|max:50';
            $rules['vehicle_plate'] = 'required|string|max:30';
            $rules['vehicle_year'] = 'nullable|integer|min:1900|max:' . (date('Y') + 1);
            $rules['vehicle_km'] = 'nullable|integer|min:0';
            $rules['vehicle_capacity'] = 'nullable|integer|min:1';
            $rules['vehicle_fuel_consumption'] = 'nullable|numeric|min:0';
            $rules['vehicle_registration_document'] = 'nullable|file|mimes:jpg,jpeg,png,webp,pdf|max:5120';
        } else {
            $rules['first_name'] = 'required|string|max:255';
            $rules['last_name'] = 'required|string|max:255';
            $rules['license_number'] = 'nullable|string|max:100';
            if ($request->type === 'guide') {
                $rules['languages'] = 'nullable|array';
                $rules['guide_registration_no'] = 'nullable|string|max:100';
                $rules['guide_service_info'] = 'nullable|string|max:5000';
                // Oda tanımlardan seçilir; "Diğer" seçilirse serbest metin zorunlu olur.
                $rules['guide_chamber_select'] = 'nullable|string|max:20';
                $rules['guide_chamber_other'] = 'nullable|required_if:guide_chamber_select,' . GuideChamber::OTHER . '|string|max:150';
            }
        }

        // Dış kaynak her tipte (rehber/araç/kaptan) bir tedarikçiye bağlanır.
        if ($request->source_type === 'external') {
            $rules['supplier_id'] = 'required|exists:suppliers,id';
        }

        // Convert comma-separated languages string to array before validation
        if ($request->type === 'guide') {
            $langsRaw = $request->input('languages', '');
            $langsArr = is_array($langsRaw)
                ? $langsRaw
                : array_filter(array_map('trim', explode(',', $langsRaw)));
            $request->merge(['languages' => array_values($langsArr)]);
        }

        $validated = $request->validate($rules, $this->validationMessages());
        $validated['is_active'] = $request->boolean('is_active', true);

        // Ad/soyad: kişi tiplerinde name'i derle; araçta first/last temizlenir.
        if ($request->type !== 'vehicle') {
            $validated['name'] = trim(($validated['first_name'] ?? '') . ' ' . ($validated['last_name'] ?? ''));
        } else {
            $validated['first_name'] = null;
            $validated['last_name'] = null;
        }

        if ($request->type === 'guide') {
            $validated['languages'] = $request->input('languages', []);
        } else {
            $validated['languages'] = null;
            $validated['guide_registration_no'] = null;
            $validated['guide_chamber'] = null;
            $validated['guide_service_info'] = null;
        }

        // Reset vehicle details if changing type to non-vehicle
        if ($request->type !== 'vehicle') {
            $validated['vehicle_class'] = null;
            $validated['vehicle_brand'] = null;
            $validated['vehicle_model'] = null;
            $validated['vehicle_plate'] = null;
            $validated['vehicle_year'] = null;
            $validated['vehicle_km'] = null;
            $validated['vehicle_fuel_consumption'] = null;
            // Araç değilse ruhsat dosyasını sil
            if ($resource->vehicle_registration_document) {
                \Illuminate\Support\Facades\Storage::disk('public')->delete($resource->vehicle_registration_document);
            }
            $validated['vehicle_registration_document'] = null;
        }

        // Araç ruhsatı: yeni dosya yüklendiyse eskiyi sil, yenisini kaydet (araç dışı tipler yukarıda null'landı)
        if ($request->type === 'vehicle') {
            if ($request->hasFile('vehicle_registration_document')) {
                if ($resource->vehicle_registration_document) {
                    \Illuminate\Support\Facades\Storage::disk('public')->delete($resource->vehicle_registration_document);
                }
                $validated['vehicle_registration_document'] = $request->file('vehicle_registration_document')
                    ->store('resources/' . $resource->agency_id . '/ruhsat', 'public');
            } else {
                unset($validated['vehicle_registration_document']); // mevcut dosyayı koru
            }
        }

        // Tedarikçi bağlantısı yalnızca dış kaynakta anlamlı; iç kaynakta temizlenir.
        if ($request->source_type !== 'external') {
            $validated['supplier_id'] = null;
        }

        unset($validated['cost_items']); // ayrı tabloda tutulur
        $validated = $this->resolveGuideChamber($request, $validated);

        $resource->update($validated);
        $this->syncCostItems($resource, $request->input('cost_items', []));

        return redirect()->route('agency.resources.index')
            ->with('success', 'Kaynak başarıyla güncellendi.');
    }

    /**
     * Formdan gelen maliyet başlıklarını kaynağa yazar (tam senkron: formda
     * olmayan satırlar silinir). Başlığı boş satırlar yok sayılır — repeater
     * boş satır bırakabilir.
     */
    private function syncCostItems(Resource $resource, array $items): void
    {
        $rows = [];
        $order = 0;

        foreach ($items as $item) {
            $title = trim((string) ($item['title'] ?? ''));
            if ($title === '') {
                continue;
            }

            $rows[] = [
                'title' => $title,
                'amount' => (float) ($item['amount'] ?? 0),
                'currency' => 'TRY',
                'sort_order' => $order++,
            ];
        }

        $resource->costItems()->delete();

        if ($rows) {
            $resource->costItems()->createMany($rows);
        }
    }

    /**
     * Formdaki oda seçimini tek bir guide_chamber değerine indirger.
     * Seçim bir oda koduysa kod, "Diğer" ise serbest metin yazılır.
     * Rehber dışı tiplerde oda anlamsızdır → null.
     */
    private function resolveGuideChamber(Request $request, array $validated): array
    {
        unset($validated['guide_chamber_select'], $validated['guide_chamber_other']);

        if ($request->type !== 'guide') {
            $validated['guide_chamber'] = null;

            return $validated;
        }

        $select = $request->input('guide_chamber_select');

        $validated['guide_chamber'] = match (true) {
            $select === GuideChamber::OTHER => trim((string) $request->input('guide_chamber_other')) ?: null,
            !empty($select) => $select,
            default => null,
        };

        return $validated;
    }

    /** AJAX — daha önce kullanılmış maliyet başlıkları (autocomplete). */
    public function costTitleSuggestions(Request $request)
    {
        $titles = ResourceCostItem::titleSuggestions(
            Auth::user()->currentAgencyId(),
            $request->get('q')
        );

        return response()->json(['titles' => $titles]);
    }

    public function destroy(Resource $resource)
    {
        if ($resource->agency_id !== Auth::user()->currentAgencyId()) {
            abort(403);
        }

        $resource->delete();

        return redirect()->route('agency.resources.index')
            ->with('success', 'Kaynak başarıyla silindi.');
    }

    public function destroySchedule($id)
    {
        $schedule = ResourceSchedule::findOrFail($id);
        
        if ($schedule->agency_id !== Auth::user()->currentAgencyId()) {
            if (request()->wantsJson()) {
                return response()->json(['success' => false, 'message' => 'Yetkisiz erişim.'], 403);
            }
            abort(403);
        }

        $schedule->delete();

        if (request()->wantsJson()) {
            return response()->json([
                'success' => true,
                'message' => 'Program/Müsaitlik kaydı başarıyla silindi.'
            ]);
        }

        return back()->with('success', 'Program/Müsaitlik kaydı başarıyla silindi.');
    }

    public function calendar(Request $request)
    {
        $agencyId = Auth::user()->currentAgencyId();
        $resources = Resource::byAgency($agencyId)->active()->orderBy('type')->orderBy('name')->get();

        // Month navigation
        $monthParam = $request->input('month', now()->format('Y-m'));
        try {
            $currentMonth = \Carbon\Carbon::createFromFormat('Y-m', $monthParam)->startOfMonth();
        } catch (\Exception $e) {
            $currentMonth = now()->startOfMonth();
        }
        $monthStart = $currentMonth->copy()->startOfMonth();
        $monthEnd   = $currentMonth->copy()->endOfMonth();

        // Build schedule query
        $scheduleQuery = \App\Models\ResourceSchedule::with('resource')
            ->where('agency_id', $agencyId)
            ->where('start_date', '<=', $monthEnd->toDateString())
            ->where('end_date',   '>=', $monthStart->toDateString());

        if ($request->filled('resource_id')) {
            $scheduleQuery->where('resource_id', $request->resource_id);
        }
        if ($request->filled('type')) {
            $scheduleQuery->whereHas('resource', fn($q) => $q->where('type', $request->type));
        }

        $schedules = $scheduleQuery->get();

        // Build day-keyed map  [day_number => [schedules]]
        $daySchedules = [];
        $daysInMonth  = $monthEnd->day;

        for ($d = 1; $d <= $daysInMonth; $d++) {
            $date = $currentMonth->copy()->day($d);
            $daySchedules[$d] = $schedules->filter(function ($s) use ($date) {
                return $s->start_date->lte($date) && $s->end_date->gte($date);
            })->values();
        }

        // Calendar grid offset (weekday of month start, Mon=0)
        $startDow = ($monthStart->dayOfWeek + 6) % 7; // 0=Mon … 6=Sun

        $prevMonth = $currentMonth->copy()->subMonth()->format('Y-m');
        $nextMonth = $currentMonth->copy()->addMonth()->format('Y-m');

        return view('agency.resources.calendar', compact(
            'resources', 'currentMonth', 'daySchedules',
            'daysInMonth', 'startDow', 'prevMonth', 'nextMonth'
        ));
    }

    /**
     * API for Availability calendar events
     */
    public function events(Request $request)
    {
        \Illuminate\Support\Facades\Log::info('Events API request', [
            'user_id' => Auth::id(),
            'agency_id' => Auth::user() ? Auth::user()->currentAgencyId() : null,
            'session_agency_id' => session('active_agency_id'),
            'start' => $request->start,
            'end' => $request->end,
            'headers' => $request->headers->all(),
        ]);

        $request->validate([
            'start' => 'required|date',
            'end' => 'required|date',
        ]);

        $agencyId = Auth::user()->currentAgencyId();
        $startDate = \Carbon\Carbon::parse($request->start)->toDateString();
        $endDate = \Carbon\Carbon::parse($request->end)->toDateString();

        $query = ResourceSchedule::with('resource')
            ->byAgency($agencyId)
            ->inDateRange($startDate, $endDate);

        if ($request->filled('resource_id')) {
            $query->forResource($request->resource_id);
        }

        if ($request->filled('type')) {
            $query->whereHas('resource', function($q) use ($request) {
                $q->where('type', $request->type);
            });
        }

        $schedules = $query->get();

        $events = [];
        foreach ($schedules as $schedule) {
            $color = '#3b82f6'; // default blue
            switch ($schedule->schedule_type) {
                case 'block':
                    $color = '#ef4444'; // red
                    break;
                case 'tour_assignment':
                    // Ön atama (amber) / kesin atama (yeşil)
                    $color = $schedule->assignment_color;
                    break;
                case 'maintenance':
                    $color = '#f59e0b'; // amber
                    break;
                case 'leave':
                    $color = '#8b5cf6'; // purple
                    break;
            }

            $isAllDay = empty($schedule->start_time);
            $startStr = $schedule->start_date->format('Y-m-d') . ($schedule->start_time ? 'T' . $schedule->start_time : '');
            $endStr = $isAllDay
                ? $schedule->end_date->copy()->addDay()->format('Y-m-d')
                : $schedule->end_date->format('Y-m-d') . ($schedule->end_time ? 'T' . $schedule->end_time : '');

            $events[] = [
                'id' => $schedule->id,
                'title' => "[" . $schedule->resource->name . "] " . $schedule->title,
                'start' => $startStr,
                'end' => $endStr,
                'description' => $schedule->description,
                'color' => $color,
                'allDay' => $isAllDay,
                'extendedProps' => [
                    'resource_type' => $schedule->resource->type,
                    'resource_name' => $schedule->resource->name,
                    'schedule_type' => $schedule->schedule_type
                ]
            ];
        }

        return response()->json($events);
    }

    /**
     * Add manual schedule block via API/Ajax
     */
    public function addBlock(Request $request)
    {
        $request->validate([
            'resource_id' => 'required|exists:resources,id',
            'start_date' => 'required|date',
            'end_date' => 'required|date|after_or_equal:start_date',
            'schedule_type' => 'required|in:block,maintenance,leave',
            'title' => 'required|string|max:255',
            'description' => 'nullable|string',
        ]);

        $agencyId = Auth::user()->currentAgencyId();
        $resource = Resource::findOrFail($request->resource_id);

        if ($resource->agency_id !== $agencyId) {
            return response()->json(['success' => false, 'message' => 'Yetkisiz erişim.'], 403);
        }

        $schedule = ResourceSchedule::create([
            'resource_id' => $request->resource_id,
            'agency_id' => $agencyId,
            'start_date' => $request->start_date,
            'end_date' => $request->end_date,
            'schedule_type' => $request->schedule_type,
            'title' => $request->title,
            'description' => $request->description,
            'is_approved' => true,
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Müsaitlik kısıtlaması başarıyla eklendi.',
            'event' => [
                'id' => $schedule->id,
                'title' => "[" . $resource->name . "] " . $schedule->title,
                'start' => $schedule->start_date->format('Y-m-d'),
                'end' => $schedule->end_date->copy()->addDay()->format('Y-m-d'),
                'color' => $request->schedule_type === 'block' ? '#ef4444' : ($request->schedule_type === 'maintenance' ? '#f59e0b' : '#8b5cf6')
            ]
        ]);
    }

    /**
     * Staff personal combined calendar page
     */
    public function mySchedule(Request $request)
    {
        $user = Auth::user();
        $agencyId = Auth::user()->currentAgencyId();
        
        // Find all resources linked to this user in the current agency
        $resources = Resource::with('agency')
            ->where('user_id', $user->id)
            ->where('agency_id', $agencyId)
            ->get();

        if ($resources->isEmpty()) {
            return redirect()->route('agency.dashboard')
                ->with('error', 'Hesabınıza tanımlanmış bir rehber veya kaptan kaynağı bulunamadı.');
        }

        return view('agency.resources.my-schedule', compact('resources'));
    }

    /**
     * API for combined events
     */
    public function myEvents(Request $request)
    {
        $request->validate([
            'start' => 'required|date',
            'end' => 'required|date',
        ]);

        $user = Auth::user();
        $agencyId = Auth::user()->currentAgencyId();
        $startDate = \Carbon\Carbon::parse($request->start)->toDateString();
        $endDate = \Carbon\Carbon::parse($request->end)->toDateString();

        // Get all resource IDs linked to this user in the current agency
        $resourceIds = Resource::where('user_id', $user->id)
            ->where('agency_id', $agencyId)
            ->pluck('id')
            ->toArray();

        $schedules = ResourceSchedule::with(['resource', 'agency'])
            ->whereIn('resource_id', $resourceIds)
            ->where('agency_id', $agencyId)
            ->inDateRange($startDate, $endDate)
            ->get();

        $events = [];
        foreach ($schedules as $schedule) {
            $color = '#3b82f6';
            switch ($schedule->schedule_type) {
                case 'block':
                    $color = '#ef4444';
                    break;
                case 'tour_assignment':
                    $color = '#10b981';
                    break;
                case 'maintenance':
                    $color = '#f59e0b';
                    break;
                case 'leave':
                    $color = '#8b5cf6';
                    break;
            }

            $isAllDay = empty($schedule->start_time);
            $startStr = $schedule->start_date->format('Y-m-d') . ($schedule->start_time ? 'T' . $schedule->start_time : '');
            $endStr = $isAllDay
                ? $schedule->end_date->copy()->addDay()->format('Y-m-d')
                : $schedule->end_date->format('Y-m-d') . ($schedule->end_time ? 'T' . $schedule->end_time : '');

            $events[] = [
                'id' => $schedule->id,
                'title' => $schedule->title,
                'start' => $startStr,
                'end' => $endStr,
                'description' => $schedule->description,
                'color' => $color,
                'allDay' => $isAllDay,
                'extendedProps' => [
                    'resource_type' => $schedule->resource->type,
                    'resource_name' => $schedule->resource->name,
                    'schedule_type' => $schedule->schedule_type
                ]
            ];
        }

        return response()->json($events);
    }

    /** AJAX Quick View for Resource */
    public function quickView(Resource $resource)
    {
        if ($resource->agency_id !== Auth::user()->currentAgencyId()) {
            abort(403, 'Bu kaynağa erişim yetkiniz yok.');
        }

        $resource->load(['user', 'supplier', 'costItems', 'images.diskItem']);

        // Rehber/şoför için public takvim linki token'ını hazırla
        if (in_array($resource->type, ['guide', 'captain'], true)) {
            $resource->ensurePublicToken();
        }

        // Load all schedules (leaves, maintenance, assignments) ordered by start date
        // contract: program satırındaki sözleşme durumu chip'i için
        $schedules = $resource->schedules()
            ->with('contract')
            ->orderBy('start_date', 'asc')
            ->orderBy('start_time', 'asc')
            ->get();

        $stats = [
            'total_tasks' => $schedules->count(),
            'assignments' => $schedules->where('schedule_type', 'tour_assignment')->count(),
            'leaves' => $schedules->where('schedule_type', 'leave')->count(),
            'maintenance' => $schedules->where('schedule_type', 'maintenance')->count(),
            'blocks' => $schedules->where('schedule_type', 'block')->count(),
        ];

        // Dış kaynak tedarikçisi ve bağlı kullanıcı seçicileri için listeler
        $agencyId = Auth::user()->currentAgencyId();
        $suppliers = Supplier::byAgency($agencyId)->orderBy('company_name')->get(['id', 'company_name', 'first_name', 'last_name']);
        $users = User::byAgency($agencyId)->active()->orderBy('first_name')->get(['id', 'first_name', 'last_name']);

        return view('agency.resources.quick-view', compact('resource', 'schedules', 'stats', 'suppliers', 'users'))->render();
    }

    /** Public takvim linkini yeniden oluştur (eski link geçersiz olur) */
    public function regeneratePublicToken(Resource $resource)
    {
        if ($resource->agency_id !== Auth::user()->currentAgencyId()) {
            return response()->json(['success' => false, 'message' => 'Yetkisiz erişim.'], 403);
        }

        $resource->public_token = null;
        $resource->saveQuietly();
        $url = url('/resource-schedule/' . $resource->ensurePublicToken());

        return response()->json(['success' => true, 'url' => $url, 'message' => 'Yeni bağlantı oluşturuldu. Eski bağlantı artık geçersiz.']);
    }

    /** Public takvim linkini iptal et */
    public function revokePublicToken(Resource $resource)
    {
        if ($resource->agency_id !== Auth::user()->currentAgencyId()) {
            return response()->json(['success' => false, 'message' => 'Yetkisiz erişim.'], 403);
        }

        $resource->public_token = null;
        $resource->saveQuietly();

        return response()->json(['success' => true, 'message' => 'Bağlantı iptal edildi.']);
    }

    /** AJAX — araç ruhsatı yükle/değiştir (görsel veya PDF) */
    public function uploadRegistrationDoc(Request $request, Resource $resource)
    {
        if ($resource->agency_id !== Auth::user()->currentAgencyId()) {
            return response()->json(['success' => false, 'message' => 'Yetkisiz erişim.'], 403);
        }
        if ($resource->type !== 'vehicle') {
            return response()->json(['success' => false, 'message' => 'Ruhsat yalnızca araçlar için yüklenebilir.'], 422);
        }

        $request->validate(['document' => 'required|file|mimes:jpg,jpeg,png,webp,pdf|max:5120']);

        if ($resource->vehicle_registration_document) {
            \Illuminate\Support\Facades\Storage::disk('public')->delete($resource->vehicle_registration_document);
        }

        $path = $request->file('document')->store('resources/' . $resource->agency_id . '/ruhsat', 'public');
        $resource->update(['vehicle_registration_document' => $path]);

        return response()->json([
            'success' => true,
            // Storage::url() APP_URL'den üretir; alt dizin kurulumunda 404 verir → asset()
            'url' => asset('storage/' . ltrim($path, '/')),
            'is_pdf' => strtolower($request->file('document')->getClientOriginalExtension()) === 'pdf',
            'message' => 'Ruhsat yüklendi.',
        ]);
    }

    /** AJAX — araç ruhsatını sil */
    public function deleteRegistrationDoc(Resource $resource)
    {
        if ($resource->agency_id !== Auth::user()->currentAgencyId()) {
            return response()->json(['success' => false, 'message' => 'Yetkisiz erişim.'], 403);
        }

        if ($resource->vehicle_registration_document) {
            \Illuminate\Support\Facades\Storage::disk('public')->delete($resource->vehicle_registration_document);
            $resource->update(['vehicle_registration_document' => null]);
        }

        return response()->json(['success' => true, 'message' => 'Ruhsat silindi.']);
    }

    /** AJAX — araç/kaynak fotoğrafı yükle (çoklu). Disk modülü ile entegre. */
    public function uploadImages(Request $request, Resource $resource)
    {
        if ($resource->agency_id !== Auth::user()->currentAgencyId()) {
            return response()->json(['success' => false, 'message' => 'Yetkisiz erişim.'], 403);
        }

        $request->validate([
            'files' => 'required',
            'files.*' => 'image|mimes:jpeg,jpg,png,webp|max:10240',
        ], [
            'files.*.image' => 'Yüklenen dosya bir görsel olmalıdır.',
            'files.*.max' => 'Görsel en fazla 10 MB olabilir.',
        ]);

        $agencyId = $resource->agency_id;
        $folder = \App\Models\Disk\DiskFolder::firstOrCreate(
            ['agency_id' => $agencyId, 'slug' => 'kaynaklar-' . $agencyId],
            ['name' => 'Kaynaklar', 'folder_type' => 'resource', 'is_active' => true, 'is_public' => false, 'created_by' => Auth::id()]
        );

        $next = (int) $resource->images()->max('sort_order') + 1;
        $hasCover = $resource->images()->where('is_cover', true)->exists();
        $added = [];

        foreach ((array) $request->file('files', []) as $file) {
            $ext = $file->getClientOriginalExtension();
            $filename = \Illuminate\Support\Str::random(40) . '.' . $ext;
            $path = 'disk/' . $agencyId . '/resources';
            $filePath = $file->storeAs($path, $filename, 'public');
            $full = \Illuminate\Support\Facades\Storage::disk('public')->path($filePath);
            [$w, $h] = @getimagesize($full) ?: [null, null];

            $diskItem = \App\Models\Disk\DiskItem::create([
                'folder_id' => $folder->id,
                'original_name' => $file->getClientOriginalName(),
                'filename' => $filename,
                'file_path' => $filePath,
                'file_url' => \Illuminate\Support\Facades\Storage::url($filePath),
                'mime_type' => $file->getMimeType(),
                'extension' => $ext,
                'file_size' => $file->getSize(),
                'file_type' => 'image',
                'file_hash' => hash_file('sha256', $full),
                'width' => $w,
                'height' => $h,
                'is_active' => true,
                'is_public' => true,
                'is_approved' => true,
                'approved_at' => now(),
                'approved_by' => Auth::id(),
                'created_by' => Auth::id(),
            ]);

            $img = $resource->images()->create([
                'disk_item_id' => $diskItem->id,
                'sort_order' => $next++,
                'is_cover' => !$hasCover,
            ]);
            $hasCover = true;
            $added[] = $img->load('diskItem');
        }

        return response()->json(['success' => true, 'message' => count($added) . ' fotoğraf eklendi.', 'images' => $added]);
    }

    /** AJAX — kaynak fotoğrafını sil (disk dosyası dahil). */
    public function deleteImage(Resource $resource, ResourceImage $image)
    {
        if ($resource->agency_id !== Auth::user()->currentAgencyId() || $image->resource_id !== $resource->id) {
            return response()->json(['success' => false, 'message' => 'Yetkisiz erişim.'], 403);
        }

        $wasCover = $image->is_cover;
        if ($image->diskItem) {
            \Illuminate\Support\Facades\Storage::disk('public')->delete($image->diskItem->file_path);
            $image->diskItem->delete();
        }
        $image->delete();

        // Kapak silindiyse ilk fotoğrafı kapak yap.
        if ($wasCover) {
            $first = $resource->images()->first();
            if ($first) {
                $first->update(['is_cover' => true]);
            }
        }

        return response()->json(['success' => true, 'message' => 'Fotoğraf silindi.']);
    }

    /** AJAX — kaynak fotoğrafını kapak yap. */
    public function setCoverImage(Resource $resource, ResourceImage $image)
    {
        if ($resource->agency_id !== Auth::user()->currentAgencyId() || $image->resource_id !== $resource->id) {
            return response()->json(['success' => false, 'message' => 'Yetkisiz erişim.'], 403);
        }

        $resource->images()->update(['is_cover' => false]);
        $image->update(['is_cover' => true]);

        return response()->json(['success' => true, 'message' => 'Kapak fotoğrafı ayarlandı.']);
    }

    /** AJAX Inline Update Field for Resource */
    public function updateField(Request $request, Resource $resource)
    {
        if ($resource->agency_id !== Auth::user()->currentAgencyId()) {
            return response()->json(['success' => false, 'message' => 'Bu kaynağa erişim yetkiniz yok.'], 403);
        }

        $request->validate([
            'field' => 'required|string',
            'value' => 'nullable',
        ]);

        $field = $request->field;
        $value = $request->value;

        $allowedFields = [
            'name', 'first_name', 'last_name', 'email', 'phone', 'identity_number', 'is_active', 'source_type',
            'vehicle_class', 'vehicle_brand', 'vehicle_model', 'vehicle_plate', 'vehicle_year',
            'vehicle_km', 'vehicle_capacity', 'vehicle_fuel_consumption', 'license_number',
            // guide_chamber burada yok: artık tanımlı odalardan seçiliyor (bkz.
            // resolveGuideChamber); serbest inline düzenleme tanımları bozardı.
            'languages', 'guide_registration_no', 'guide_service_info', 'comment',
            'supplier_id', 'user_id',
        ];

        if (!in_array($field, $allowedFields)) {
            return response()->json(['success' => false, 'message' => 'Bu alan güncellenemez.'], 422);
        }

        // Dış kaynak tedarikçisi / bağlı kullanıcı: bu acenteye ait olmalı; boş → bağı kaldır
        if ($field === 'supplier_id') {
            $value = $value ?: null;
            if ($value && !Supplier::byAgency($resource->agency_id)->whereKey($value)->exists()) {
                return response()->json(['success' => false, 'message' => 'Geçersiz tedarikçi.'], 422);
            }
        }
        if ($field === 'user_id') {
            $value = $value ?: null;
            if ($value && !User::byAgency($resource->agency_id)->whereKey($value)->exists()) {
                return response()->json(['success' => false, 'message' => 'Geçersiz kullanıcı.'], 422);
            }
        }

        // Custom validation rules per field
        if ($field === 'email' && $value) {
            $request->validate(['value' => 'email|max:255']);
        }
        if (in_array($field, ['vehicle_year', 'vehicle_km', 'vehicle_capacity']) && $value !== null && $value !== '') {
            $request->validate(['value' => 'integer|min:0']);
        }
        if ($field === 'vehicle_fuel_consumption' && $value !== null && $value !== '') {
            $request->validate(['value' => 'numeric|min:0']);
        }
        if ($field === 'is_active') {
            $value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
        }

        // Handle languages array conversion if it's sent as string
        if ($field === 'languages' && $value) {
            if (is_string($value)) {
                $value = array_filter(array_map('trim', explode(',', $value)));
            }
        }

        try {
            $resource->update([$field => $value]);

            $displayValue = $value;
            if ($field === 'is_active') {
                $displayValue = $resource->is_active ? 'Aktif' : 'Pasif';
            } elseif ($field === 'source_type') {
                $displayValue = $resource->source_type === 'internal' ? 'İç Kaynak' : 'Dış Kaynak';
            } elseif ($field === 'vehicle_capacity') {
                $displayValue = $value ? $value . ' Kişilik' : '—';
            } elseif ($field === 'vehicle_fuel_consumption') {
                $displayValue = $value ? number_format($value, 1) . ' km/lt' : '—';
            } elseif ($field === 'languages') {
                $displayValue = is_array($value) ? implode(', ', $value) : ($value ?: '—');
            }

            return response()->json([
                'success' => true,
                'message' => 'Kaynak başarıyla güncellendi.',
                'value' => $value,
                'display_value' => $displayValue
            ]);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Güncelleme sırasında hata oluştu: ' . $e->getMessage()], 500);
        }
    }
}
