<?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\Sale\Sale;
use App\Models\Sale\SaleActivity;
use App\Models\Sale\SaleItem;
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 = Sale::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('sale_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
        $sales = 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']);
            }
            $sales = $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 = Sale::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 = Sale::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(
            'sales', 
            '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 = Sale::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('sale_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);
        }

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

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

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

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

        $query = Sale::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('sale_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);
        }

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

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

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

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

        $query = Sale::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('sale_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);
        }

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

        return view('agency.sales.cancellations', compact('sales', '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 = Sale::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 quickCreate()
    {
        $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 = Product::byAgency($agencyId)
            ->with('productType')
            ->bookable()
            ->orderBy('name')
            ->get(['id', 'name', 'base_price', 'currency', 'product_type_id']);

        $activeCurrencies = auth()->user()->agency->getActiveCurrencies();
        return view('agency.sales.quick-create', compact('productTypes', 'customers', 'agents', 'products', 'activeCurrencies'));
    }

    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 = Sale::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:potential,offer_sent,revised,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();

            $sale = new Sale($validated);
            $sale->agency_id = $agencyId;
            $sale->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) {
                    $sale->reservable_type = $product->productable_type;
                    $sale->reservable_id = $product->productable_id;
                }
            }

            $sale->save();

            // ─── ÜRÜNLERİ KAYDET ─────────────────────────────────────────────
            if ($request->has('items') && is_array($request->items)) {
                foreach ($request->items as $itemData) {
                    if (empty($itemData['name'])) continue;
                    $taxRate = (float) ($itemData['tax_rate'] ?? 0);
                    $qty     = (float) ($itemData['quantity'] ?? 1);
                    $price   = (float) ($itemData['unit_price'] ?? 0);
                    $taxAmt  = round($qty * $price * ($taxRate / 100), 2);
                    $total   = round($qty * $price + $taxAmt, 2);

                    SaleItem::create([
                        'sale_id'    => $sale->id,
                        'product_id' => !empty($itemData['product_id']) ? $itemData['product_id'] : null,
                        'name'       => $itemData['name'],
                        'quantity'   => $qty,
                        'unit_price' => $price,
                        'tax_rate'   => $taxRate,
                        'tax_amount' => $taxAmt,
                        'total_price'=> $total,
                        'currency'   => $itemData['currency'] ?? 'TRY',
                    ]);
                }
            }

            $sale->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) {
                        $sale->passengers()->attach($passengerId, [
                            'room_number' => $pData['room_number'] ?? null,
                            'seat_number' => $pData['seat_number'] ?? null,
                            'special_request' => $pData['special_request'] ?? null,
                        ]);
                    }
                }
            }

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


            DB::commit();

            if ($request->expectsJson()) {
                return response()->json([
                    'success' => true,
                    'message' => 'Rezervasyon başarıyla oluşturuldu.',
                    'sale_id' => $sale->id,
                    'sale_code' => $sale->sale_code
                ]);
            }

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

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

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

    public function show(Sale $sale)
    {
        $this->authorizeAgency($sale);

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

        $productType = $sale->productType;
        $extraFields = $productType ? Sale::extraFieldsFor($productType->code) : [];

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

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

    public function edit(Sale $sale)
    {
        $this->authorizeAgency($sale);
        $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 = $sale->productType;

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

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

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

    public function update(Request $request, Sale $sale)
    {
        $this->authorizeAgency($sale);

        $productType = $sale->productType;
        $extraFields = $productType ? Sale::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();

            $sale->update($validated);
            $sale->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 = $sale->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,
                        ];
                    }
                }
                $sale->passengers()->sync($passengerIds);
            }

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

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

            if ($validated['status'] === 'cancelled' && !$sale->cancelled_at) {
                $sale->cancelled_at = now();
                $sale->cancelled_by = auth()->id();
                $sale->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('Sale update error', ['message' => $e->getMessage(), 'sale_id' => $sale->id]);
            return back()->withInput()->with('error', 'Güncelleme sırasında hata: ' . $e->getMessage());
        }
    }

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

    public function destroy(Sale $sale)
    {
        $this->authorizeAgency($sale);

        $code = $sale->sale_code;
        $sale->delete();

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

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

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

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

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

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

        return back()->with('success', number_format($request->amount, 2) . ' ' . $sale->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 = Sale::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(Sale $sale)
    {
        $this->authorizeAgency($sale);
        $agencyId = $this->agencyId();

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

        $productTypes = ProductType::active()->orderBy('sort_order')->get();
        $agents = User::byAgency($agencyId)->where('is_active', true)->get();
        $products = \App\Models\Product\Product::where('agency_id', $agencyId)->where('is_active', true)->orderBy('name')->get();
        $customFieldDefinitions = \App\Models\Sale\SaleFieldDefinition::where('agency_id', $agencyId)->where('is_active', true)->orderBy('sort_order')->get();
        
        $activeCurrencies = auth()->user()->agency->getActiveCurrencies();
        return view('agency.sales.quick-view', compact('sale', 'productTypes', 'agents', 'products', 'customFieldDefinitions', 'activeCurrencies'));
    }

    public function updateField(Request $request, Sale $sale)
    {
        $this->authorizeAgency($sale);

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

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

        if (str_starts_with($field, 'custom_field_')) {
            $defId = (int) str_replace('custom_field_', '', $field);
            $definition = \App\Models\Sale\SaleFieldDefinition::where('id', $defId)
                ->where('agency_id', $sale->agency_id)
                ->first();
            if (!$definition) {
                return response()->json(['success' => false, 'message' => 'Geçersiz özel alan.'], 422);
            }
            
            try {
                DB::beginTransaction();
                
                $oldValueRecord = \App\Models\Sale\SaleFieldValue::where('sale_id', $sale->id)
                    ->where('field_definition_id', $defId)
                    ->first();
                $oldValue = $oldValueRecord?->value ?? '—';
                
                \App\Models\Sale\SaleFieldValue::updateOrCreate(
                    ['sale_id' => $sale->id, 'field_definition_id' => $defId],
                    ['value' => $value]
                );
                
                SaleActivity::create([
                    'agency_id' => $sale->agency_id,
                    'sale_id' => $sale->id,
                    'performed_by' => auth()->id(),
                    'activity_type' => 'update',
                    'subject' => 'Özel Alan Güncellendi: ' . $definition->label,
                    'description' => "<b>{$definition->label}</b> özel alanı '{$oldValue}' değerinden '{$value}' değerine güncellendi.",
                    'metadata' => ['field' => $field, 'old' => $oldValue, 'new' => $value]
                ]);
                
                DB::commit();
                
                return response()->json([
                    'success' => true,
                    'message' => 'Özel alan güncellendi.',
                    'display_value' => $value
                ]);
            } catch (\Exception $e) {
                DB::rollBack();
                return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
            }
        }

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

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

        try {
            DB::beginTransaction();

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

            if ($field === 'currency') {
                $sale->calculateTotals();
            }

            // 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 = $sale->getStatusLabel($oldValue);
                $newLabel = $sale->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ı
            SaleActivity::create([
                'agency_id' => $sale->agency_id,
                'sale_id' => $sale->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 = $sale->status_label;
            if ($field === 'assigned_to') $displayValue = $sale->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, Sale $sale)
    {
        $this->authorizeAgency($sale);

        $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',
            'tax_rate' => 'nullable|numeric|min:0|max:100',
            'currency' => 'required|string|max:3',
        ]);

        try {
            DB::beginTransaction();

            $taxRate = isset($validated['tax_rate']) ? (float)$validated['tax_rate'] : 20.0;
            $subtotalPrice = $validated['quantity'] * $validated['unit_price'];
            $taxAmount = $subtotalPrice * ($taxRate / 100);
            $totalPrice = $subtotalPrice + $taxAmount;

            $item = $sale->items()->create([
                'product_id' => $validated['product_id'] ?? null,
                'product_type_id' => $validated['product_type_id'] ?? ($validated['product_id'] ? \App\Models\Product\Product::find($validated['product_id'])->product_type_id : null),
                'name' => $validated['name'],
                'quantity' => $validated['quantity'],
                'unit_price' => $validated['unit_price'],
                'tax_rate' => $taxRate,
                'tax_amount' => $taxAmount,
                'total_price' => $totalPrice,
                'currency' => $validated['currency'],
            ]);

            // Rezervasyon toplamını güncelle
            $sale->calculateTotals(); // Bu metod subtotal, tax_amount ve total_amount'u günceller

            // Aktivite
            SaleActivity::create([
                'agency_id' => $sale->agency_id,
                'sale_id' => $sale->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(SaleItem $item)
    {
        $sale = $item->sale;
        $this->authorizeAgency($sale);

        try {
            DB::beginTransaction();

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

            // Rezervasyon toplamını güncelle
            $sale->calculateTotals();

            // Aktivite
            SaleActivity::create([
                'agency_id' => $sale->agency_id,
                'sale_id' => $sale->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);
        }
    }

    public function getActivities(Sale $sale)
    {
        $this->authorizeAgency($sale);
        
        $sale->load([
            'activities' => function ($q) {
                $q->orderBy('is_pinned', 'desc')->orderBy('created_at', 'desc');
            },
            'activities.performer'
        ]);

        $html = view('agency.sales.partials.activities-feed', compact('sale'))->render();

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

    public function storeActivity(Request $request, Sale $sale)
    {
        $this->authorizeAgency($sale);

        $validated = $request->validate([
            'activity_type' => 'required|string|in:' . implode(',', \App\Enums\ActivityType::values()),
            'subject' => 'nullable|string|max:255',
            'description' => 'nullable|string',
            'due_date' => 'nullable|date',
            'is_pinned' => 'boolean',
            'is_important' => 'boolean',
            'attachment' => 'nullable|file|max:10240',
        ]);

        $validated['agency_id'] = $this->agencyId();
        $validated['sale_id'] = $sale->id;
        $validated['performed_by'] = auth()->id();
        $validated['status'] = $validated['activity_type'] === 'task' ? 'pending' : 'completed';
        $validated['activity_date'] = now();

        if ($request->hasFile('attachment')) {
            $file = $request->file('attachment');
            $path = $file->store('sales/activities/' . $sale->id, 'public');
            
            $validated['attachments'] = [
                [
                    'name' => $file->getClientOriginalName(),
                    'path' => $path,
                    'size' => $file->getSize(),
                    'mime' => $file->getMimeType(),
                    'uploaded_at' => now()->toDateTimeString(),
                ]
            ];
        }

        $activity = SaleActivity::create($validated);

        $sale->load([
            'activities' => function ($q) {
                $q->orderBy('is_pinned', 'desc')->orderBy('created_at', 'desc');
            },
            'activities.performer'
        ]);

        $html = view('agency.sales.partials.activities-feed', compact('sale'))->render();

        return response()->json([
            'success' => true,
            'message' => 'Aktivite başarıyla kaydedildi.',
            'html' => $html
        ]);
    }

    public function togglePinActivity(Sale $sale, SaleActivity $activity)
    {
        $this->authorizeAgency($sale);
        
        if ($activity->sale_id !== $sale->id) {
            return response()->json(['success' => false, 'message' => 'Geçersiz aktivite.'], 404);
        }

        $activity->is_pinned = !$activity->is_pinned;
        $activity->save();

        $sale->load([
            'activities' => function ($q) {
                $q->orderBy('is_pinned', 'desc')->orderBy('created_at', 'desc');
            },
            'activities.performer'
        ]);

        $html = view('agency.sales.partials.activities-feed', compact('sale'))->render();

        return response()->json([
            'success' => true,
            'message' => $activity->is_pinned ? 'Aktivite sabitlendi.' : 'Sabitleme kaldırıldı.',
            'html' => $html
        ]);
    }

    public function destroyActivity(Sale $sale, SaleActivity $activity)
    {
        $this->authorizeAgency($sale);

        if ($activity->sale_id !== $sale->id) {
            return response()->json(['success' => false, 'message' => 'Geçersiz aktivite.'], 404);
        }

        $activity->delete();

        $sale->load([
            'activities' => function ($q) {
                $q->orderBy('is_pinned', 'desc')->orderBy('created_at', 'desc');
            },
            'activities.performer'
        ]);

        $html = view('agency.sales.partials.activities-feed', compact('sale'))->render();

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

    public function storeFieldDefinition(Request $request)
    {
        $agencyId = $this->agencyId();
        
        $validated = $request->validate([
            'label' => 'required|string|max:120',
            'field_type' => 'required|string|in:text,select,textarea,number,date',
            'options' => 'nullable|string',
            'is_required' => 'nullable|boolean',
        ]);
        
        $optionsArray = null;
        if ($validated['field_type'] === 'select' && !empty($validated['options'])) {
            $optionsArray = array_filter(array_map('trim', explode(',', $validated['options'])));
        }
        
        $fieldKey = \Str::slug($validated['label'], '_');
        $origKey = $fieldKey;
        $counter = 1;
        while (\App\Models\Sale\SaleFieldDefinition::where('agency_id', $agencyId)->where('field_key', $fieldKey)->exists()) {
            $fieldKey = $origKey . '_' . $counter;
            $counter++;
        }
        
        $definition = \App\Models\Sale\SaleFieldDefinition::create([
            'agency_id' => $agencyId,
            'field_key' => $fieldKey,
            'label' => $validated['label'],
            'field_type' => $validated['field_type'],
            'options' => $optionsArray,
            'is_required' => (bool)($request->is_required ?? false),
            'is_active' => true,
            'sort_order' => 0,
        ]);
        
        return response()->json([
            'success' => true,
            'message' => 'Özel alan tanımlandı.',
            'definition' => $definition
        ]);
    }

    public function updateFieldDefinition(Request $request, \App\Models\Sale\SaleFieldDefinition $definition)
    {
        if ($definition->agency_id !== $this->agencyId()) {
            return response()->json(['success' => false, 'message' => 'Yetkisiz erişim.'], 403);
        }
        
        $validated = $request->validate([
            'label' => 'required|string|max:120',
            'field_type' => 'required|string|in:text,select,textarea,number,date',
            'options' => 'nullable|string',
            'is_required' => 'nullable|boolean',
        ]);
        
        $optionsArray = null;
        if ($validated['field_type'] === 'select' && !empty($validated['options'])) {
            $optionsArray = array_filter(array_map('trim', explode(',', $validated['options'])));
        }
        
        $definition->update([
            'label' => $validated['label'],
            'field_type' => $validated['field_type'],
            'options' => $optionsArray,
            'is_required' => (bool)($request->is_required ?? false),
        ]);
        
        return response()->json([
            'success' => true,
            'message' => 'Özel alan tanımı güncellendi.',
            'definition' => $definition
        ]);
    }

    public function storeDocument(Request $request, Sale $sale)
    {
        $this->authorizeAgency($sale);

        $request->validate([
            'file' => 'required|file|max:10240', // 10MB limit
            'notes' => 'nullable|string|max:1000',
        ]);

        $file = $request->file('file');
        $originalName = $file->getClientOriginalName();
        $mimeType = $file->getMimeType();
        $fileSize = $file->getSize();

        $path = $file->store("agency/{$sale->agency_id}/sales/{$sale->id}/documents", 'public');

        $document = \App\Models\Sale\SaleDocument::create([
            'agency_id' => $sale->agency_id,
            'sale_id' => $sale->id,
            'file_name' => $originalName,
            'file_path' => $path,
            'file_size' => $fileSize,
            'mime_type' => $mimeType,
            'notes' => $request->notes,
            'created_by' => auth()->id(),
        ]);

        SaleActivity::create([
            'agency_id' => $sale->agency_id,
            'sale_id' => $sale->id,
            'performed_by' => auth()->id(),
            'activity_type' => 'document',
            'subject' => 'Yeni Belge Yüklendi',
            'description' => "Satışa <b>{$originalName}</b> adlı yeni bir belge yüklendi.",
            'metadata' => ['document_id' => $document->id, 'file_name' => $originalName]
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Belge başarıyla yüklendi.',
            'document' => [
                'id' => $document->id,
                'file_name' => $document->file_name,
                'size' => $document->formatted_size,
                'created_at' => $document->created_at->format('d.m.Y H:i'),
            ]
        ]);
    }

    public function destroyDocument(Sale $sale, \App\Models\Sale\SaleDocument $document)
    {
        $this->authorizeAgency($sale);

        if ($document->sale_id !== $sale->id) {
            return response()->json(['success' => false, 'message' => 'Geçersiz belge.'], 404);
        }

        \Storage::disk('public')->delete($document->file_path);
        
        $document->delete();

        SaleActivity::create([
            'agency_id' => $sale->agency_id,
            'sale_id' => $sale->id,
            'performed_by' => auth()->id(),
            'activity_type' => 'document',
            'subject' => 'Belge Silindi',
            'description' => "<b>{$document->file_name}</b> adlı belge silindi.",
            'metadata' => ['document_id' => $document->id, 'file_name' => $document->file_name]
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Belge başarıyla silindi.'
        ]);
    }

    public function updateItems(Request $request, Sale $sale)
    {
        $this->authorizeAgency($sale);
        
        $validated = $request->validate([
            'items' => 'present|array',
            'items.*.id' => 'nullable|integer',
            'items.*.product_id' => 'nullable|integer',
            'items.*.name' => 'required|string|max:255',
            'items.*.quantity' => 'required|numeric|min:0',
            'items.*.unit_price' => 'required|numeric|min:0',
            'items.*.tax_rate' => 'required|numeric|min:0|max:100',
            'items.*.currency' => 'required|string|max:3',
        ]);
        
        try {
            DB::beginTransaction();
            
            $sentIds = collect($validated['items'])->pluck('id')->filter()->toArray();
            
            $sale->items()->whereNotIn('id', $sentIds)->delete();
            
            foreach ($validated['items'] as $itemData) {
                $subtotalPrice = $itemData['quantity'] * $itemData['unit_price'];
                $taxAmount = $subtotalPrice * ($itemData['tax_rate'] / 100);
                $totalPrice = $subtotalPrice + $taxAmount;
                
                $data = [
                    'product_id' => $itemData['product_id'] ?? null,
                    'product_type_id' => $itemData['product_id'] ? \App\Models\Product\Product::find($itemData['product_id'])->product_type_id : null,
                    'name' => $itemData['name'],
                    'quantity' => $itemData['quantity'],
                    'unit_price' => $itemData['unit_price'],
                    'tax_rate' => $itemData['tax_rate'],
                    'tax_amount' => $taxAmount,
                    'total_price' => $totalPrice,
                    'currency' => $itemData['currency'],
                ];
                
                if (!empty($itemData['id'])) {
                    $sale->items()->where('id', $itemData['id'])->update($data);
                } else {
                    $sale->items()->create($data);
                }
            }
            
            $sale->calculateTotals();
            
            SaleActivity::create([
                'agency_id' => $sale->agency_id,
                'sale_id' => $sale->id,
                'performed_by' => auth()->id(),
                'activity_type' => 'update',
                'subject' => 'Ürünler Güncellendi',
                'description' => 'Satış ürün listesi ve fiyat hesaplamaları güncellendi.',
            ]);
            
            DB::commit();
            
            return response()->json([
                'success' => true,
                'message' => 'Ürünler başarıyla güncellendi.',
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 500);
        }
    }

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

