<?php

namespace App\Http\Controllers\Agency;

use App\Http\Controllers\Controller;
use App\Models\Customer\Customer;
use App\Models\Agency\AgencySalesTarget;
use App\Models\Product\Product;
use App\Models\Product\ProductType;
use App\Models\Reservation\Reservation;
use App\Models\Reservation\ReservationActivity;
use App\Models\Reservation\ReservationItem;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class SalesController extends Controller
{
    private function agencyId(): int
    {
        return Auth::user()->currentAgencyId();
    }

    // ─── INDEX ────────────────────────────────────────────────────────────────

    public function index(Request $request)
    {
        $agencyId = $this->agencyId();
        $view = $request->get('view', 'dashboard');

        $query = Reservation::byAgency($agencyId)
            ->with(['customer', 'productType', 'creator', 'assignedAgent'])
            ->orderBy('created_at', 'desc');

        // Filtreler
        if ($request->filled('status')) {
            $query->byStatus($request->status);
        }
        if ($request->filled('product_type_id')) {
            $query->byProductType($request->product_type_id);
        }
        if ($request->filled('search')) {
            $s = $request->search;
            $query->where(function ($q) use ($s) {
                $q->where('reservation_code', 'like', "%$s%")
                    ->orWhereHas('customer', fn($cq) => $cq->where('first_name', 'like', "%$s%")
                        ->orWhere('last_name', 'like', "%$s%")
                        ->orWhere('emails', 'like', "%$s%"));
            });
        }
        if ($request->filled('date_from')) {
            $query->where('start_date', '>=', $request->date_from);
        }
        if ($request->filled('date_to')) {
            $query->where('start_date', '<=', $request->date_to);
        }

        // Görünüm Moduna Göre Veri Hazırlama
        $reservations = null;
        $kanbanGroups = [];

        if ($view === 'list') {
            // Default: devam eden satışlar (status filtresi uygulanmamışsa)
            if (!$request->filled('status')) {
                $query->whereIn('status', ['potential', 'offer_sent', 'revised']);
            }
            $reservations = $query->paginate(20)->withQueryString();
        } elseif ($view === 'kanban') {
            // Kanban için aktif ve tamamlanan satışları alıyoruz (İptal ve İade hariç)
            $kanbanData = $query->whereNotIn('status', ['cancelled', 'refunded'])
                ->get();

            $kanbanGroups = $kanbanData->groupBy('status');
        }

        // İstatistikler (Filtrelere göre dinamikleşsin istiyorsak aşağıdaki gibi baz query üzerinden gidebiliriz)
        // Ancak genellikle "Genel Durum" istendiği için tüm ajans verisi kalsın, biz sadece baz istatistiği filtrelenmiş yapalım
        $baseStatsQuery = Reservation::byAgency($agencyId);
        if ($request->filled('product_type_id'))
            $baseStatsQuery->byProductType($request->product_type_id);
        if ($request->filled('date_from'))
            $baseStatsQuery->where('start_date', '>=', $request->date_from);
        if ($request->filled('date_to'))
            $baseStatsQuery->where('start_date', '<=', $request->date_to);

        $stats = [
            'total' => $baseStatsQuery->count(),
            'potential_val' => (clone $baseStatsQuery)->whereIn('status', ['potential', 'offer_sent', 'revised', 'pending'])->sum('total_amount'),
            'won_val' => (clone $baseStatsQuery)->whereIn('status', ['confirmed', 'in_progress', 'completed'])->sum('total_amount'),
            'paid_val' => (clone $baseStatsQuery)->sum('paid_amount'),
            'unpaid_val' => (clone $baseStatsQuery)->whereNotIn('status', ['cancelled', 'refunded'])->sum('remaining_amount'),
            'monthly_count' => (clone $baseStatsQuery)->whereMonth('created_at', now()->month)->count(),
            'pending_count' => (clone $baseStatsQuery)->whereIn('status', ['potential', 'offer_sent', 'revised', 'pending'])->count(),
        ];

        $productTypes = ProductType::active()->orderBy('sort_order')->get();

        // ─── SATIŞ HEDEFLERİ & FİLTRELEME ──────────────────────────────────────
        $targetPeriod = $request->get('period', 'year');
        $currentYear = $request->get('year', now()->year);
        $currentMonth = $request->get('month', now()->month);

        $targetsQuery = \App\Models\Agency\AgencySalesTarget::where('agency_id', $agencyId)
            ->where('target_year', $currentYear)
            ->where('target_period', $targetPeriod);
        
        if ($targetPeriod === 'month') {
            $targetsQuery->where('target_month', $currentMonth);
        }
        
        $targets = $targetsQuery->get();

        // Varsayılan hedef tipi: revenue (ciro)
        $targetType = $request->get('target_type', 'revenue');
        
        $achievedQuery = Reservation::byAgency($agencyId)
            ->whereIn('status', ['confirmed', 'in_progress', 'completed'])
            ->whereYear('created_at', $currentYear);

        if ($targetPeriod === 'month') {
            $achievedQuery->whereMonth('created_at', $currentMonth);
        }

        if ($targetType === 'revenue') {
            $achievedData = $achievedQuery->select('product_type_id', DB::raw('SUM(total_amount) as total'))
                ->groupBy('product_type_id')
                ->pluck('total', 'product_type_id');
        } else {
            $achievedData = $achievedQuery->select('product_type_id', DB::raw('COUNT(*) as count'))
                ->groupBy('product_type_id')
                ->pluck('count', 'product_type_id');
        }

        $salesTargets = [];
        foreach ($productTypes as $pt) {
            $target = $targets->where('product_type_id', $pt->id)->where('target_type', $targetType)->first();
            $targetValue = $target ? (float)$target->target_value : 0;
            $achievedValue = isset($achievedData[$pt->id]) ? (float)$achievedData[$pt->id] : 0;
            
            $salesTargets[$pt->id] = [
                'name' => $pt->name,
                'target' => $targetValue,
                'achieved' => $achievedValue,
                'percentage' => $targetValue > 0 ? min(100, round(($achievedValue / $targetValue) * 100, 1)) : 0,
                'color' => $pt->color ?? '#2563eb'
            ];
        }

        // Genel Hedef Hesabı
        $totalTarget = collect($salesTargets)->sum('target');
        $totalAchieved = collect($salesTargets)->sum('achieved');
        $totalPercentage = $totalTarget > 0 ? min(100, round(($totalAchieved / $totalTarget) * 100, 1)) : 0;

        // İlerleme Çizgisi Hesabı (Seçilen döneme göre)
        if ($targetPeriod === 'month') {
            $yearProgress = round((now()->day / now()->daysInMonth) * 100, 1);
        } else {
            $yearProgress = round((now()->dayOfYear() / 365) * 100, 1);
        }

        return view('agency.sales.index', compact(
            'reservations', 
            'kanbanGroups', 
            'stats', 
            'productTypes', 
            'view', 
            'salesTargets', 
            'totalTarget', 
            'totalAchieved', 
            'totalPercentage',
            'yearProgress',
            'currentYear',
            'currentMonth',
            'targetType',
            'targetPeriod'
        ));
    }

    // ─── LEADS (Müşteri Adayları) ─────────────────────────────────────────────

    public function leads(Request $request)
    {
        $agencyId = $this->agencyId();

        $query = Reservation::byAgency($agencyId)
            ->with(['customer', 'productType', 'creator', 'assignedAgent'])
            ->whereIn('status', ['potential', 'offer_sent', 'revised'])
            ->orderBy('created_at', 'desc');

        if ($request->filled('search')) {
            $s = $request->search;
            $query->where(function ($q) use ($s) {
                $q->where('reservation_code', 'like', "%$s%")
                    ->orWhereHas('customer', fn($cq) => $cq->where('first_name', 'like', "%$s%")
                        ->orWhere('last_name', 'like', "%$s%"));
            });
        }
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }
        if ($request->filled('date_from')) {
            $query->where('start_date', '>=', $request->date_from);
        }
        if ($request->filled('date_to')) {
            $query->where('start_date', '<=', $request->date_to);
        }

        $reservations = $query->paginate(20)->withQueryString();
        $productTypes = ProductType::active()->orderBy('sort_order')->get();

        return view('agency.sales.leads', compact('reservations', 'productTypes'));
    }

    // ─── DEALS (Anlaşmalar) ───────────────────────────────────────────────────

    public function deals(Request $request)
    {
        $agencyId = $this->agencyId();

        $query = Reservation::byAgency($agencyId)
            ->with(['customer', 'productType', 'creator', 'assignedAgent'])
            ->whereIn('status', ['confirmed', 'in_progress', 'completed'])
            ->orderBy('created_at', 'desc');

        if ($request->filled('search')) {
            $s = $request->search;
            $query->where(function ($q) use ($s) {
                $q->where('reservation_code', 'like', "%$s%")
                    ->orWhereHas('customer', fn($cq) => $cq->where('first_name', 'like', "%$s%")
                        ->orWhere('last_name', 'like', "%$s%"));
            });
        }
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }
        if ($request->filled('date_from')) {
            $query->where('start_date', '>=', $request->date_from);
        }
        if ($request->filled('date_to')) {
            $query->where('start_date', '<=', $request->date_to);
        }

        $reservations = $query->paginate(20)->withQueryString();
        $productTypes = ProductType::active()->orderBy('sort_order')->get();

        return view('agency.sales.deals', compact('reservations', 'productTypes'));
    }

    // ─── CANCELLATIONS (İptal ve İadeler) ─────────────────────────────────────

    public function cancellations(Request $request)
    {
        $agencyId = $this->agencyId();

        $query = Reservation::byAgency($agencyId)
            ->with(['customer', 'productType', 'creator', 'assignedAgent'])
            ->whereIn('status', ['cancelled', 'refunded'])
            ->orderBy('created_at', 'desc');

        if ($request->filled('search')) {
            $s = $request->search;
            $query->where(function ($q) use ($s) {
                $q->where('reservation_code', 'like', "%$s%")
                    ->orWhereHas('customer', fn($cq) => $cq->where('first_name', 'like', "%$s%")
                        ->orWhere('last_name', 'like', "%$s%"));
            });
        }
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }
        if ($request->filled('date_from')) {
            $query->where('start_date', '>=', $request->date_from);
        }
        if ($request->filled('date_to')) {
            $query->where('start_date', '<=', $request->date_to);
        }

        $reservations = $query->paginate(20)->withQueryString();
        $productTypes = ProductType::active()->orderBy('sort_order')->get();

        return view('agency.sales.cancellations', compact('reservations', 'productTypes'));
    }

    // ─── CREATE / STORE ───────────────────────────────────────────────────────

    public function create(Request $request)
    {
        $agencyId = $this->agencyId();

        $productTypes = ProductType::active()->orderBy('sort_order')->get();

        $customers = Customer::byAgency($agencyId)
            ->where('status', '!=', 'blocked')
            ->orderBy('first_name')
            ->get(['id', 'first_name', 'last_name', 'emails', 'phone']);

        $agents = User::byAgency($agencyId)
            ->where('is_active', true)
            ->orderBy('first_name')
            ->get(['id', 'first_name', 'last_name']);

        $products = collect();
        $selectedProductType = null;
        $extraFields = [];

        if ($request->filled('product_type_id')) {
            $selectedProductType = ProductType::find($request->product_type_id);
            if ($selectedProductType) {
                $products = Product::byAgency($agencyId)
                    ->byProductType($selectedProductType->id)
                    ->bookable()
                    ->orderBy('name')
                    ->get(['id', 'name', 'base_price', 'currency', 'slug', 'productable_type', 'productable_id']);

                $extraFields = Reservation::extraFieldsFor($selectedProductType->code);
            }
        }

        $preselectedCustomer = null;
        if ($request->filled('customer_id')) {
            $preselectedCustomer = Customer::byAgency($agencyId)->find($request->customer_id);

            // Eğer müşteri listede yoksa (örneğin engellenmişse veya filtreye takılmışsa) listeye ekliyoruz
            if ($preselectedCustomer && !$customers->contains('id', $preselectedCustomer->id)) {
                $customers->push($preselectedCustomer);
            }
        }

        return view('agency.sales.create', compact(
            'productTypes',
            'customers',
            'agents',
            'products',
            'selectedProductType',
            'extraFields',
            'preselectedCustomer'
        ));
    }

    public function store(Request $request)
    {
        $agencyId = $this->agencyId();

        $productType = null;
        $extraFields = [];

        if ($request->filled('product_type_id')) {
            $productType = ProductType::find($request->product_type_id);
            if ($productType) {
                $extraFields = Reservation::extraFieldsFor($productType->code);
            }
        }

        $rules = [
            'customer_id' => 'required|exists:customers,id',
            'product_type_id' => 'nullable|exists:product_types,id',
            'product_id' => 'nullable|exists:products,id',
            'start_date' => 'required|date',
            'end_date' => 'nullable|date|after_or_equal:start_date',
            'pickup_time' => 'nullable|date',
            'adult_count' => 'required|integer|min:1',
            'child_count' => 'nullable|integer|min:0',
            'infant_count' => 'nullable|integer|min:0',
            'unit_price' => 'nullable|numeric|min:0',
            'child_price' => 'nullable|numeric|min:0',
            'infant_price' => 'nullable|numeric|min:0',
            'discount_rate' => 'nullable|numeric|min:0|max:100',
            'discount_amount' => 'nullable|numeric|min:0',
            'tax_amount' => 'nullable|numeric|min:0',
            'currency' => 'nullable|string|max:3',
            'status' => 'required|in:pending,confirmed,in_progress,completed,cancelled,refunded',
            'payment_status' => 'required|in:unpaid,partial,paid,refunded',
            'paid_amount' => 'nullable|numeric|min:0',
            'pickup_location' => 'nullable|string|max:255',
            'dropoff_location' => 'nullable|string|max:255',
            'flight_number' => 'nullable|string|max:30',
            'source' => 'nullable|string|max:50',
            'assigned_to' => 'nullable|exists:users,id',
            'customer_note' => 'nullable|string',
            'internal_note' => 'nullable|string',
        ];

        foreach ($extraFields as $field) {
            $rules["extra_data.{$field['key']}"] = 'nullable|string|max:255';
        }

        try {
            $validated = $request->validate($rules);

            $customer = Customer::byAgency($agencyId)->findOrFail($validated['customer_id']);

            DB::beginTransaction();

            $reservation = new Reservation($validated);
            $reservation->agency_id = $agencyId;
            $reservation->remaining_amount = (string) max(0.0, (float) ($validated['total_amount'] ?? 0) - (float) ($validated['paid_amount'] ?? 0));

            if (!empty($validated['product_id'])) {
                $product = Product::find($validated['product_id']);
                if ($product?->productable_type && $product?->productable_id) {
                    $reservation->reservable_type = $product->productable_type;
                    $reservation->reservable_id = $product->productable_id;
                }
            }

            $reservation->save();
            $reservation->calculateTotals();

            // ─── YOLCULARI KAYDET ─────────────────────────────────────────────
            if ($request->has('passengers')) {
                foreach ($request->passengers as $pData) {
                    $passengerId = $pData['id'] ?? null;

                    // Eğer yolcu zaten varsa, bilgilerini güncelle
                    if ($passengerId) {
                        $p = \App\Models\CustomerPassenger::find($passengerId);
                        if ($p) {
                            $p->first_name = $pData['first_name'] ?? $p->first_name;
                            $p->last_name = $pData['last_name'] ?? $p->last_name;
                            $p->gender = $pData['gender'] ?? $p->gender;
                            $p->birth_date = !empty($pData['birth_date']) ? $pData['birth_date'] : $p->birth_date;
                            $p->national_id = $pData['national_id'] ?? $p->national_id;
                            $p->phone = $pData['phone'] ?? $p->phone;
                            $p->email = $pData['email'] ?? $p->email;
                            $p->relationship = $pData['relationship'] ?? $p->relationship;
                            $p->save();
                        }
                    }

                    // Eğer yeni yolcu ise CustomerPassenger olarak kaydet
                    if (!$passengerId && !empty($pData['first_name'])) {
                        $newP = new \App\Models\CustomerPassenger();
                        $newP->customer_id = $customer->id;
                        $newP->first_name = $pData['first_name'];
                        $newP->last_name = $pData['last_name'] ?? '';
                        $newP->gender = $pData['gender'] ?? null;
                        $newP->birth_date = $pData['birth_date'] ?? null;
                        $newP->national_id = $pData['national_id'] ?? null;
                        $newP->passport_number = $pData['passport_number'] ?? null;
                        $newP->passport_expiry = $pData['passport_expiry'] ?? null;
                        $newP->phone = $pData['phone'] ?? null;
                        $newP->email = $pData['email'] ?? null;
                        $newP->relationship = $pData['relationship'] ?? null;
                        $newP->created_by = Auth::id();
                        $newP->save();
                        $passengerId = $newP->id;
                    }

                    if ($passengerId) {
                        $reservation->passengers()->attach($passengerId, [
                            'room_number' => $pData['room_number'] ?? null,
                            'seat_number' => $pData['seat_number'] ?? null,
                            'special_request' => $pData['special_request'] ?? null,
                        ]);
                    }
                }
            }

            if ((float) $reservation->total_amount > 0) {
                $customer->recordBooking((float) $reservation->total_amount);
            } else {
                $customer->update(['last_booking_date' => today()]);
            }


            DB::commit();

            return redirect()
                ->route('agency.sales.show', $reservation)
                ->with('success', 'Rezervasyon başarıyla oluşturuldu. Kod: ' . $reservation->reservation_code);

        } catch (\Illuminate\Validation\ValidationException $e) {
            Log::warning('Reservation store validation error', ['errors' => $e->errors(), 'agency' => $agencyId]);
            throw $e;
        } catch (\Throwable $e) {
            DB::rollBack();
            Log::error('Reservation store error', ['message' => $e->getMessage(), 'agency' => $agencyId]);
            return back()->withInput()->with('error', 'Rezervasyon oluşturulurken bir hata oluştu: ' . $e->getMessage());
        }
    }

    // ─── SHOW ─────────────────────────────────────────────────────────────────

    public function show(Reservation $reservation)
    {
        $this->authorizeAgency($reservation);

        $reservation->load([
            'customer',
            'productType',
            'product',
            'reservable',
            'creator',
            'assignedAgent',
            'confirmedBy',
            'cancelledBy',
        ]);

        $productType = $reservation->productType;
        $extraFields = $productType ? Reservation::extraFieldsFor($productType->code) : [];

        return view('agency.sales.show', compact('reservation', 'extraFields', 'productType'));
    }

    // ─── EDIT / UPDATE ────────────────────────────────────────────────────────

    public function edit(Reservation $reservation)
    {
        $this->authorizeAgency($reservation);
        $agencyId = $this->agencyId();

        $productTypes = ProductType::active()->orderBy('sort_order')->get();

        $customers = Customer::byAgency($agencyId)
            ->orderBy('first_name')
            ->get(['id', 'first_name', 'last_name', 'emails', 'phone']);

        $agents = User::byAgency($agencyId)
            ->where('is_active', true)
            ->orderBy('first_name')
            ->get(['id', 'first_name', 'last_name']);

        $products = collect();
        $extraFields = [];
        $selectedProductType = $reservation->productType;

        if ($selectedProductType) {
            $products = Product::byAgency($agencyId)
                ->byProductType($selectedProductType->id)
                ->bookable()
                ->orderBy('name')
                ->get(['id', 'name', 'base_price', 'currency', 'productable_type', 'productable_id']);

            $extraFields = Reservation::extraFieldsFor($selectedProductType->code);
        }

        return view('agency.sales.edit', compact(
            'reservation',
            'productTypes',
            'customers',
            'agents',
            'products',
            'selectedProductType',
            'extraFields'
        ));
    }

    public function update(Request $request, Reservation $reservation)
    {
        $this->authorizeAgency($reservation);

        $productType = $reservation->productType;
        $extraFields = $productType ? Reservation::extraFieldsFor($productType->code) : [];

        $rules = [
            'customer_id' => 'required|exists:customers,id',
            'product_type_id' => 'nullable|exists:product_types,id',
            'product_id' => 'nullable|exists:products,id',
            'start_date' => 'required|date',
            'end_date' => 'nullable|date|after_or_equal:start_date',
            'pickup_time' => 'nullable|date',
            'adult_count' => 'required|integer|min:1',
            'child_count' => 'nullable|integer|min:0',
            'infant_count' => 'nullable|integer|min:0',
            'unit_price' => 'nullable|numeric|min:0',
            'child_price' => 'nullable|numeric|min:0',
            'infant_price' => 'nullable|numeric|min:0',
            'discount_rate' => 'nullable|numeric|min:0|max:100',
            'discount_amount' => 'nullable|numeric|min:0',
            'tax_amount' => 'nullable|numeric|min:0',
            'status' => 'required|in:pending,confirmed,in_progress,completed,cancelled,refunded',
            'payment_status' => 'required|in:unpaid,partial,paid,refunded',
            'paid_amount' => 'nullable|numeric|min:0',
            'pickup_location' => 'nullable|string|max:255',
            'dropoff_location' => 'nullable|string|max:255',
            'flight_number' => 'nullable|string|max:30',
            'assigned_to' => 'nullable|exists:users,id',
            'customer_note' => 'nullable|string',
            'internal_note' => 'nullable|string',
            'cancellation_reason' => 'nullable|string',
        ];

        foreach ($extraFields as $field) {
            $rules["extra_data.{$field['key']}"] = 'nullable';
        }

        try {
            $validated = $request->validate($rules);

            DB::beginTransaction();

            $reservation->update($validated);
            $reservation->calculateTotals();

            if ($request->has('passengers')) {
                $passengerIds = [];
                foreach ($request->passengers as $pData) {
                    $passengerId = $pData['id'] ?? null;

                    // Eğer yolcu zaten varsa, bilgilerini güncelle
                    if ($passengerId) {
                        $p = \App\Models\CustomerPassenger::find($passengerId);
                        if ($p) {
                            $p->first_name = $pData['first_name'] ?? $p->first_name;
                            $p->last_name = $pData['last_name'] ?? $p->last_name;
                            $p->gender = $pData['gender'] ?? $p->gender;
                            $p->birth_date = !empty($pData['birth_date']) ? $pData['birth_date'] : $p->birth_date;
                            $p->national_id = $pData['national_id'] ?? $p->national_id;
                            $p->phone = $pData['phone'] ?? $p->phone;
                            $p->email = $pData['email'] ?? $p->email;
                            $p->relationship = $pData['relationship'] ?? $p->relationship;
                            $p->save();
                        }
                    }

                    // Eğer yeni yolcu ise CustomerPassenger olarak kaydet
                    if (!$passengerId && !empty($pData['first_name'])) {
                        $newP = new \App\Models\CustomerPassenger();
                        $newP->customer_id = $reservation->customer_id;
                        $newP->first_name = $pData['first_name'];
                        $newP->last_name = $pData['last_name'] ?? '';
                        $newP->gender = $pData['gender'] ?? null;
                        $newP->birth_date = $pData['birth_date'] ?? null;
                        $newP->national_id = $pData['national_id'] ?? null;
                        $newP->passport_number = $pData['passport_number'] ?? null;
                        $newP->passport_expiry = $pData['passport_expiry'] ?? null;
                        $newP->phone = $pData['phone'] ?? null;
                        $newP->email = $pData['email'] ?? null;
                        $newP->relationship = $pData['relationship'] ?? null;
                        $newP->created_by = Auth::id();
                        $newP->save();
                        $passengerId = $newP->id;
                    }

                    if ($passengerId) {
                        $passengerIds[$passengerId] = [
                            'room_number' => $pData['room_number'] ?? null,
                            'seat_number' => $pData['seat_number'] ?? null,
                            'special_request' => $pData['special_request'] ?? null,
                        ];
                    }
                }
                $reservation->passengers()->sync($passengerIds);
            }

            if (!empty($validated['product_id'])) {

                $product = \App\Models\Product\Product::find($validated['product_id']);
                if ($product?->productable_type && $product?->productable_id) {
                    $reservation->reservable_type = $product->productable_type;
                    $reservation->reservable_id = $product->productable_id;
                    $reservation->save();
                }
            }

            if ($validated['status'] === 'cancelled' && !$reservation->cancelled_at) {
                $reservation->cancelled_at = now();
                $reservation->cancelled_by = auth()->id();
                $reservation->save();
            }

            DB::commit();

            return back()->with('success', 'Rezervasyon başarıyla güncellendi.');

        } catch (\Illuminate\Validation\ValidationException $e) {
            throw $e;
        } catch (\Throwable $e) {
            DB::rollBack();
            Log::error('Reservation update error', ['message' => $e->getMessage(), 'reservation' => $reservation->id]);
            return back()->withInput()->with('error', 'Güncelleme sırasında hata: ' . $e->getMessage());
        }
    }

    // ─── DELETE ───────────────────────────────────────────────────────────────

    public function destroy(Reservation $reservation)
    {
        $this->authorizeAgency($reservation);

        $code = $reservation->reservation_code;
        $reservation->delete();

        return redirect()
            ->route('agency.sales.index')
            ->with('success', "$code numaralı rezervasyon silindi.");
    }

    // ─── QUICK ACTIONS ────────────────────────────────────────────────────────

    public function confirm(Request $request, Reservation $reservation)
    {
        $this->authorizeAgency($reservation);
        $reservation->confirm();
        return back()->with('success', 'Rezervasyon onaylandı.');
    }

    public function cancel(Request $request, Reservation $reservation)
    {
        $this->authorizeAgency($reservation);
        $request->validate(['reason' => 'nullable|string|max:500']);
        $reservation->cancel($request->reason ?? '');
        return back()->with('success', 'Rezervasyon iptal edildi.');
    }

    public function addPayment(Request $request, Reservation $reservation)
    {
        $this->authorizeAgency($reservation);
        $request->validate(['amount' => 'required|numeric|min:0.01']);

        $newPaid = (float) $reservation->paid_amount + (float) $request->amount;
        $reservation->update([
            'paid_amount' => $newPaid,
            'remaining_amount' => number_format(max(0, (float) $reservation->total_amount - $newPaid), 2, '.', ''),
            'payment_status' => $newPaid >= (float) $reservation->total_amount ? 'paid'
                : ($newPaid > 0 ? 'partial' : 'unpaid'),
        ]);

        return back()->with('success', number_format($request->amount, 2) . ' ' . $reservation->currency . ' ödeme kaydedildi.');
    }

    // ─── AJAX: Ürün tipi → ürünler + extra alanlar ───────────────────────────

    public function getProductsByType(Request $request)
    {
        $agencyId = $this->agencyId();
        $productType = ProductType::find($request->product_type_id);

        if (!$productType) {
            return response()->json(['products' => [], 'extra_fields' => [], 'type_code' => null]);
        }

        $products = Product::byAgency($agencyId)
            ->byProductType($productType->id)
            ->with(['productable.departureCity'])
            ->bookable()
            ->orderBy('name')
            ->get(['id', 'name', 'base_price', 'currency', 'slug', 'productable_type', 'productable_id', 'code'])
            ->map(function($p) {
                $item = [
                    'id' => $p->id,
                    'name' => $p->name,
                    'code' => $p->code,
                    'base_price' => (float) $p->base_price,
                    'currency' => $p->currency,
                    'has_dates' => !empty($p->productable_type),
                    'productable_type' => $p->productable_type,
                    'productable_id' => $p->productable_id,
                ];

                if ($p->productable) {
                    $item['duration'] = $p->productable->duration_hours ?? ($p->productable->duration_days ?? null);
                    $item['departure_city'] = $p->productable->departureCity?->name;
                    $item['visit_locations'] = is_array($p->productable->visit_locations) ? implode(' - ', array_slice($p->productable->visit_locations, 0, 3)) : null;
                    $item['meal_included'] = $p->productable->meal_included ?? false;
                }

                return $item;
            });

        $extraFields = Reservation::extraFieldsFor($productType->code);

        return response()->json([
            'products' => $products,
            'extra_fields' => $extraFields,
            'type_code' => $productType->code,
        ]);
    }

    // ─── AJAX: Ürün → tarihler + fiyatlar ────────────────────────────────────

    public function getProductDates(Request $request)
    {
        $product = Product::find($request->product_id);

        if (!$product) {
            return response()->json(['dates' => [], 'has_dates' => false]);
        }

        $dates = [];
        $hasDates = false;

        // Polimorfik ilişkiyle bağlı modeli belirle
        $productableType = $product->productable_type ?? '';

        if (str_contains($productableType, 'Tour') && !str_contains($productableType, 'Day')) {
            // Kültür Turu → TourDate (cultural_tour_dates)
            $tourDates = \App\Models\Tour\TourDate::where('cultural_tour_id', $product->productable_id)
                ->where('is_bookable', true)
                ->where('is_active', true)
                ->where('start_date', '>=', now()->toDateString())
                ->orderBy('start_date')
                ->get(['id', 'start_date', 'end_date', 'adult_price', 'child_price', 'infant_price', 'currency', 'remaining_capacity', 'duration_days', 'season_type', 'special_discount', 'guarantee_departure']);

            $dates = $tourDates->map(function($d) {
                $startDate = $d->start_date;
                $searchText = $startDate->format('d.m.Y') . ' ' . 
                             $startDate->translatedFormat('d F Y') . ' ' . 
                             $startDate->translatedFormat('d M Y') . ' ' .
                             $startDate->format('Y-m-d');
                
                return [
                    'id' => $d->id,
                    'date_type' => 'tour_date',
                    'start_date' => $startDate->format('Y-m-d'),
                    'end_date' => $d->end_date?->format('Y-m-d'),
                    'start_date_display' => $startDate->translatedFormat('d M Y'),
                    'end_date_display' => $d->end_date?->translatedFormat('d M Y'),
                    'search_text' => strtolower($searchText),
                    'adult_price' => (float) $d->adult_price,
                    'child_price' => (float) $d->child_price,
                    'infant_price' => (float) $d->infant_price,
                    'currency' => $d->currency,
                    'remaining_capacity' => $d->remaining_capacity,
                    'duration_days' => $d->duration_days,
                    'season_type' => $d->season_type,
                    'special_discount' => (float) $d->special_discount,
                    'guarantee_departure' => $d->guarantee_departure,
                ];
            })->toArray();
            $hasDates = count($dates) > 0;

        } elseif (str_contains($productableType, 'DayTour')) {
            // Günübirlik Tur → DayTourDate
            $dayDates = \App\Models\DayTour\DayTourDate::where('day_tour_id', $product->productable_id)
                ->where('is_active', true)
                ->where('tour_date', '>=', now()->toDateString())
                ->orderBy('tour_date')
                ->get();

            $dates = $dayDates->map(function($d) {
                $tourDate = \Carbon\Carbon::parse($d->tour_date);
                $searchText = $tourDate->format('d.m.Y') . ' ' . 
                             $tourDate->translatedFormat('d F Y') . ' ' . 
                             $tourDate->translatedFormat('d M Y') . ' ' .
                             $tourDate->format('Y-m-d');

                return [
                    'id' => $d->id,
                    'date_type' => 'day_tour_date',
                    'start_date' => $tourDate->format('Y-m-d'),
                    'end_date' => $tourDate->format('Y-m-d'),
                    'start_date_display' => $tourDate->translatedFormat('d M Y'),
                    'end_date_display' => null,
                    'search_text' => strtolower($searchText),
                    'adult_price' => (float) $d->adult_price,
                    'child_price' => (float) $d->child_price,
                    'infant_price' => (float) $d->infant_price,
                    'currency' => 'TRY',
                    'remaining_capacity' => $d->remaining_capacity,
                    'duration_days' => 1,
                    'departure_time' => $d->start_time ? \Carbon\Carbon::parse($d->start_time)->format('H:i') : null,
                    'return_time' => $d->end_time ? \Carbon\Carbon::parse($d->end_time)->format('H:i') : null,
                    'guarantee_departure' => $d->is_guaranteed,
                ];
            })->toArray();
            $hasDates = count($dates) > 0;

        } elseif (str_contains($productableType, 'DayTrip')) {
            // Diğer Günübirlik Tur Versiyonu → DayTripTourDate
            $dayDates = \App\Models\Product\DayTripTourDate::where('day_trip_tour_id', $product->productable_id)
                ->where('is_bookable', true)
                ->where('is_active', true)
                ->where('tour_date', '>=', now()->toDateString())
                ->orderBy('tour_date')
                ->get();

            $dates = $dayDates->map(function($d) {
                $tourDate = \Carbon\Carbon::parse($d->tour_date);
                $searchText = $tourDate->format('d.m.Y') . ' ' . 
                             $tourDate->translatedFormat('d F Y') . ' ' . 
                             $tourDate->translatedFormat('d M Y') . ' ' .
                             $tourDate->format('Y-m-d');

                return [
                    'id' => $d->id,
                    'date_type' => 'day_trip_date',
                    'start_date' => $tourDate->format('Y-m-d'),
                    'end_date' => $tourDate->format('Y-m-d'),
                    'start_date_display' => $tourDate->translatedFormat('d M Y'),
                    'end_date_display' => null,
                    'search_text' => strtolower($searchText),
                    'adult_price' => (float) $d->price_adult,
                    'child_price' => (float) $d->price_child,
                    'infant_price' => (float) $d->price_infant,
                    'currency' => 'TRY',
                    'remaining_capacity' => $d->remaining_capacity,
                    'duration_days' => 1,
                    'departure_time' => $d->departure_time ? \Carbon\Carbon::parse($d->departure_time)->format('H:i') : null,
                    'return_time' => $d->return_time ? \Carbon\Carbon::parse($d->return_time)->format('H:i') : null,
                    'guarantee_departure' => $d->guarantee_departure,
                ];
            })->toArray();
            $hasDates = count($dates) > 0;
        }

        return response()->json([
            'has_dates' => $hasDates,
            'dates' => $dates,
            'base_price' => (float) $product->base_price,
            'currency' => $product->currency,
        ]);
    }

    // ─── AJAX: Ürün → tarihler + fiyatlar ────────────────────────────────────

    public function quickStoreCustomer(Request $request)
    {
        $agencyId = $this->agencyId();

        try {
            $validated = $request->validate([
                'first_name' => 'required|string|max:255',
                'last_name' => 'required|string|max:255',
                'email' => 'nullable|email|max:255',
                'phone' => 'nullable|string|max:20',
                'gender' => 'nullable|in:male,female,other',
            ]);

            $customer = new Customer();
            $customer->agency_id = $agencyId;
            $customer->first_name = $validated['first_name'];
            $customer->last_name = $validated['last_name'];
            $customer->phone = $validated['phone'];
            $customer->gender = $validated['gender'];

            if (!empty($validated['email'])) {
                $customer->emails = [$validated['email']];
            }

            $customer->status = 'active';
            $customer->created_by = Auth::id();
            $customer->save();

            return response()->json([
                'success' => true,
                'customer' => [
                    'id' => $customer->id,
                    'full_name' => $customer->full_name,
                    'first_name' => $customer->first_name,
                    'last_name' => $customer->last_name,
                    'phone' => $customer->phone,
                    'email' => $validated['email'] ?? '',
                    'initials' => $customer->initials,
                ]
            ]);

        } catch (\Illuminate\Validation\ValidationException $e) {
            return response()->json(['success' => false, 'errors' => $e->errors()], 422);
        } catch (\Throwable $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    public function getCustomerPassengers(Request $request)
    {
        $agencyId = $this->agencyId();
        $customerId = $request->customer_id;

        $customer = Customer::byAgency($agencyId)->findOrFail($customerId);
        $passengers = $customer->passengers()->orderBy('first_name')->get();

        return response()->json([
            'success' => true,
            'passengers' => $passengers
        ]);
    }


    // ─── YARDIMCI ─────────────────────────────────────────────────────────────

    public function storeTargets(Request $request)
    {
        $agencyId = $this->agencyId();
        $validated = $request->validate([
            'year' => 'required|integer',
            'period' => 'required|in:year,month',
            'month' => 'nullable|integer|min:1|max:12',
            'type' => 'required|in:revenue,quantity',
            'targets' => 'required|array',
            'targets.*' => 'nullable|string', // String because of formatting dots
        ]);

        $targetMonth = ($validated['period'] === 'month') ? $validated['month'] : null;

        foreach ($validated['targets'] as $productTypeId => $value) {
            $numericValue = (float)str_replace('.', '', $value);

            \App\Models\Agency\AgencySalesTarget::updateOrCreate(
                [
                    'agency_id' => $agencyId,
                    'product_type_id' => $productTypeId,
                    'target_year' => $validated['year'],
                    'target_period' => $validated['period'],
                    'target_month' => $targetMonth,
                    'target_type' => $validated['type'],
                ],
                [
                    'target_value' => $numericValue,
                ]
            );
        }

        return back()->with('success', 'Satış hedefleri başarıyla güncellendi.');
    }

    public function getTargetsJson(Request $request)
    {
        $agencyId = $this->agencyId();
        $targets = \App\Models\Agency\AgencySalesTarget::where('agency_id', $agencyId)
            ->where('target_year', $request->year)
            ->where('target_period', $request->period)
            ->where('target_type', $request->type)
            ->when($request->period === 'month', function($q) use ($request) {
                return $q->where('target_month', $request->month);
            })
            ->pluck('target_value', 'product_type_id');

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

    public function quickView(Reservation $reservation)
    {
        $this->authorizeAgency($reservation);
        $agencyId = $this->agencyId();

        $reservation->load([
            'customer',
            'productType',
            'product',
            'reservable',
            'items.product',
            'activities.performer',
            'customFields.definition',
            'passengers'
        ]);

        $productTypes = ProductType::active()->orderBy('sort_order')->get();
        $agents = User::byAgency($agencyId)->where('is_active', true)->get();
        
        return view('agency.sales.quick-view', compact('reservation', 'productTypes', 'agents'));
    }

    public function updateField(Request $request, Reservation $reservation)
    {
        $this->authorizeAgency($reservation);

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

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

        // İzin verilen alanlar
        $allowedFields = [
            'title', 'status', 'start_date', 'end_date', 'assigned_to', 
            'customer_note', 'internal_note', 'pickup_location', 'dropoff_location'
        ];

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

        try {
            DB::beginTransaction();

            $oldValue = $reservation->$field;
            $reservation->$field = $value;
            $reservation->save();

            // Daha açıklayıcı aktivite mesajı
            $subject = 'Alan Güncellendi: ' . $field;
            $desc = "'$field' alanı '$oldValue' değerinden '$value' değerine güncellendi.";

            if ($field === 'status') {
                $oldLabel = $reservation->getStatusLabel($oldValue);
                $newLabel = $reservation->status_label;
                $subject = 'Satış Durumu Değişti';
                $desc = "Satış durumu <b>$oldLabel</b> aşamasından <b>$newLabel</b> aşamasına çekildi.";
            }

            if ($field === 'assigned_to') {
                $oldUser = User::find($oldValue)?->full_name ?? 'Atanmamış';
                $newUser = User::find($value)?->full_name ?? 'Atanmamış';
                $subject = 'Sorumlu Değiştirildi';
                $desc = "Satış sorumlusu <b>$oldUser</b> yerine <b>$newUser</b> olarak güncellendi.";
            }

            // Aktivite kaydı
            ReservationActivity::create([
                'agency_id' => $reservation->agency_id,
                'reservation_id' => $reservation->id,
                'performed_by' => auth()->id(),
                'activity_type' => 'update',
                'subject' => $subject,
                'description' => $desc,
                'metadata' => ['field' => $field, 'old' => $oldValue, 'new' => $value]
            ]);

            DB::commit();

            $displayValue = $value;
            if ($field === 'status') $displayValue = $reservation->status_label;
            if ($field === 'assigned_to') $displayValue = $reservation->assignedAgent?->full_name ?? '—';

            return response()->json([
                'success' => true,
                'message' => 'Güncelleme başarılı.',
                'display_value' => $displayValue
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    public function addItem(Request $request, Reservation $reservation)
    {
        $this->authorizeAgency($reservation);

        $validated = $request->validate([
            'product_id' => 'nullable|exists:products,id',
            'product_type_id' => 'nullable|exists:product_types,id',
            'name' => 'required|string',
            'quantity' => 'required|numeric|min:0.01',
            'unit_price' => 'required|numeric',
            'currency' => 'required|string|max:3',
        ]);

        try {
            DB::beginTransaction();

            $item = $reservation->items()->create([
                'product_id' => $validated['product_id'],
                'product_type_id' => $validated['product_type_id'],
                'name' => $validated['name'],
                'quantity' => $validated['quantity'],
                'unit_price' => $validated['unit_price'],
                'total_price' => $validated['quantity'] * $validated['unit_price'],
                'currency' => $validated['currency'],
            ]);

            // Rezervasyon toplamını güncelle
            $reservation->total_amount = $reservation->items()->sum('total_price');
            $reservation->save();
            $reservation->calculateTotals(); // Bu metod remaining_amount vb. günceller

            // Aktivite
            ReservationActivity::create([
                'agency_id' => $reservation->agency_id,
                'reservation_id' => $reservation->id,
                'performed_by' => auth()->id(),
                'activity_type' => 'item_added',
                'subject' => 'Ürün Eklendi: ' . $item->name,
                'description' => "Satışa {$item->quantity} adet {$item->name} eklendi.",
                'metadata' => ['item_id' => $item->id, 'total' => $item->total_price]
            ]);

            DB::commit();

            return response()->json(['success' => true, 'message' => 'Ürün eklendi.']);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    public function removeItem(ReservationItem $item)
    {
        $reservation = $item->reservation;
        $this->authorizeAgency($reservation);

        try {
            DB::beginTransaction();

            $itemName = $item->name;
            $item->delete();

            // Rezervasyon toplamını güncelle
            $reservation->total_amount = $reservation->items()->sum('total_price');
            $reservation->save();
            $reservation->calculateTotals();

            // Aktivite
            ReservationActivity::create([
                'agency_id' => $reservation->agency_id,
                'reservation_id' => $reservation->id,
                'performed_by' => auth()->id(),
                'activity_type' => 'item_removed',
                'subject' => 'Ürün Çıkarıldı: ' . $itemName,
                'description' => "Satıştan {$itemName} çıkarıldı.",
            ]);

            DB::commit();

            return response()->json(['success' => true, 'message' => 'Ürün çıkarıldı.']);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    protected function authorizeAgency(Reservation $reservation): void
    {
        if ($reservation->agency_id !== $this->agencyId()) {
            abort(403, 'Bu rezervasyona erişim yetkiniz yok.');
        }
    }
}

