<?php

namespace App\Livewire\Sales;

use App\Models\Customer;
use App\Models\PaymentMethod;
use App\Models\Product;
use App\Models\Sale;
use App\Models\SaleItem;
use App\Models\SaleType;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Layout;
use Livewire\Component;

#[Layout('layouts.dashboard')]
class Create extends Component
{
    // Form state
    public $customer_id = '';

    public $payment_method_id = '';

    public $sale_type_id = '';

    public $notes = '';

    public $sale;

    // Product form state
    public $product_id;

    public $quantity = 1;

    public $unit_price = 0;

    // Sale items from session
    public $subtotal = 0;

    public $total = 0;

    // Options for dropdowns
    public $customer_options = [];

    public $payment_method_options = [];

    public $sale_type_options = [];

    public $product_options = [];

    // UI state
    public bool $loading = false;
    public bool $success = false;
    public bool $error = false;
    public ?string $successMessage = null;
    public ?string $errorMessage = null;

    

    // Product form UI state
    public $product_loading = false;

    public $product_error = false;

    public $product_error_message = '';

    protected $listeners = [
        'sale-item-added' => 'handleSaleItemAdded',
    ];

    public function mount()
    {
        $this->sale = new Sale;
        $this->loadOptions();
        $this->setDefaultValues();
    }

    public function loadOptions()
    {
        $this->payment_method_options = PaymentMethod::where('status', true)
            ->where('id', '!=', \App\Models\Setting::DEFAULT_PAYMENT_METHOD_DEBT_ID)
            ->get(['id', 'name'])
            ->map(fn ($m) => (object) ['id' => $m->id, 'name' => $m->name]);

        $this->sale_type_options = SaleType::where('status', true)
            ->get(['id', 'name'])
            ->map(fn ($t) => (object) ['id' => $t->id, 'name' => $t->name]);

        $this->customer_options = Customer::where('status', 1)
            ->orderBy('name')
            ->get()
            ->map(function ($customer) {
                return (object) [
                    'id' => $customer->id,
                    'name' => $customer->name.' ('.($customer->contact?->phone ?? 'N/A').')',
                ];
            });

        $this->loadProducts();
    }

    public function loadProducts()
    {
        $this->product_options = Product::where('status', 1)
            ->with('category')
            ->orderBy('name')
            ->get()
            ->map(function ($product) {
                return (object) [
                    'id' => $product->id,
                    'name' => $product->name,
                    'generic_name' => $product->generic_name,
                    'category' => $product->category?->name,
                    'display_name' => $product->name.' ('.$product->generic_name.') - '.($product->category?->name ?? 'Sans catégorie'),
                ];
            });
    }

    public function setDefaultValues()
    {
        $this->payment_method_id = \App\Models\Setting::DEFAULT_PAYMENT_METHOD_ID;
        $this->sale_type_id = \App\Models\Setting::DEFAULT_SALE_TYPE_ID;
    }

    public function updatedCustomerId($value)
    {
        if ($value) {
            $this->payment_method_options = PaymentMethod::where('status', true)
                ->get(['id', 'name'])
                ->map(fn ($m) => (object) ['id' => $m->id, 'name' => $m->name]);
        } else {
            $this->payment_method_options = PaymentMethod::where('status', true)
                ->where('id', '!=', \App\Models\Setting::DEFAULT_PAYMENT_METHOD_DEBT_ID)
                ->get(['id', 'name'])
                ->map(fn ($m) => (object) ['id' => $m->id, 'name' => $m->name]);
        }
    }

    public function handleSaleItemAdded()
    {
        // This will be triggered when items are added via the sales-items component
        $this->calculateTotals();
    }

    public function calculateTotals()
    {
        $saleItems = session('sale_items', []);
        $this->subtotal = collect($saleItems)->sum('total_price');
        $this->total = $this->subtotal;
    }

    public function createSale()
    {
        $this->resetErrorBag();
        $this->loading = true;
        $this->success = false;
        $this->error = false;
        $this->successMessage = null;
        $this->errorMessage = null;

        $this->validate([
            'payment_method_id' => 'required|exists:payment_methods,id',
            'sale_type_id' => 'required|exists:sale_types,id',
        ]);

        $saleItems = session('sale_items', []);

        if (empty($saleItems)) {
            $this->error = true;
            $this->errorMessage = 'Veuillez ajouter au moins un produit à la vente.';
            $this->loading = false;

            return;
        }

        try {
            DB::beginTransaction();

            $sale = Sale::create([
                'user_id' => Auth::id(),
                'customer_id' => $this->customer_id ?: null,
                'sale_number' => Sale::generateUniqueSaleNumber(),
                'sale_type_id' => $this->sale_type_id,
                'payment_method_id' => $this->payment_method_id,
                'subtotal' => $this->subtotal,
                'tax_amount' => 0,
                'discount_amount' => 0,
                'total_amount' => $this->total,
                'paid_amount' => $this->total,
                'change_amount' => 0,
                'status' => Sale::STATUS_COMPLETED,
                'notes' => $this->notes,
            ]);

            foreach ($saleItems as $itemData) {
                SaleItem::create([
                    'sale_id' => $sale->id,
                    'product_id' => $itemData['product_id'],
                    'quantity' => $itemData['quantity'],
                    'unit_price' => $itemData['unit_price'],
                    'total_price' => $itemData['total_price'],
                    'cost_price' => $itemData['cost_price'],
                    'profit' => $itemData['profit'],
                ]);

                $product = Product::find($itemData['product_id']);
                if ($product) {
                    $product->decrement('current_stock', $itemData['quantity']);
                }
            }

            // Create debt record if payment method is debt
            if ($this->payment_method_id == \App\Models\Setting::DEFAULT_PAYMENT_METHOD_DEBT_ID) {
                \App\Models\Debt::create([
                    'debt_number' => \App\Models\Debt::generateUniqueDebtNumber(),
                    'customer_id' => $this->customer_id,
                    'sale_id' => $sale->id,
                    'total_debt_amount' => $sale->total_amount,
                    'paid_amount' => 0,
                    'remaining_amount' => $sale->total_amount,
                    'status' => \App\Models\Debt::STATUS_PENDING,
                    'due_date' => now()->addDays(30), // Default 30 days
                    'notes' => 'Dette créée automatiquement lors de la vente',
                ]);
            }

            DB::commit();

            session()->forget(['sale_items', 'sale_form_data']);

            // Set success message in session for toast notification
            session()->flash('success', 'Vente créée avec succès!');

            // Redirect to show page
            return redirect()->route('sales.show', $sale);

        } catch (\Exception $e) {
            DB::rollBack();
            report($e);
            $this->error = true;
            $this->errorMessage = 'Erreur lors de la création de la vente: '.$e->getMessage();
            $this->addError('general', 'Erreur lors de la création de la vente: '.$e->getMessage());
        } finally {
            $this->loading = false;
        }
    }

    public function clearSaleItems()
    {
        session()->forget(['sale_items', 'sale_form_data']);
        $this->calculateTotals();
    }

    public function deleteSessionItem($index)
    {
        $saleItems = session('sale_items', []);
        if (isset($saleItems[$index])) {
            unset($saleItems[$index]);
            $saleItems = array_values($saleItems); // Re-index array
            session(['sale_items' => $saleItems]);
            $this->calculateTotals();
        }
    }

    // Product form methods
    public function updatedProductId()
    {
        if ($this->product_id) {
            $product = Product::find($this->product_id);
            if ($product) {
                $this->unit_price = $product->selling_price ?? 0;
            }
        }
    }

    public function addProduct()
    {
        $this->validate([
            'product_id' => 'required|exists:products,id',
            'quantity' => 'required|numeric|min:1',
            'unit_price' => 'required|numeric|min:0',
        ]);

        $this->product_loading = true;
        $this->product_error = false;
        $this->product_error_message = '';

        try {
            // Prevent duplicates
            $existingItems = session('sale_items', []);
            $alreadyExists = collect($existingItems)->contains(fn ($i) => (int) ($i['product_id'] ?? 0) === (int) $this->product_id);

            if ($alreadyExists) {
                $this->product_error = true;
                $this->product_error_message = 'Ce produit est déjà ajouté à la vente.';
                $this->product_loading = false;

                return;
            }

            // Check stock availability
            $available = $this->getProductStock($this->product_id);
            if ($available < $this->quantity) {
                $this->product_error = true;
                $this->product_error_message = "Stock insuffisant: disponible {$available}, demandé {$this->quantity}.";
                $this->product_loading = false;

                return;
            }

            // Add to session
            $product = Product::find($this->product_id);
            $costPrice = $product->cost_price ?? 0;
            $totalPrice = $this->quantity * $this->unit_price;
            $profit = $totalPrice - $this->quantity * $costPrice;

            $saleItem = [
                'product_id' => $this->product_id,
                'quantity' => $this->quantity,
                'unit_price' => $this->unit_price,
                'total_price' => $totalPrice,
                'cost_price' => $costPrice,
                'profit' => $profit,
            ];

            $existingItems[] = $saleItem;
            session(['sale_items' => $existingItems]);

            // Reset form
            $this->reset(['product_id', 'quantity', 'unit_price']);
            $this->quantity = 1;
            $this->unit_price = 0;

            // Recalculate totals
            $this->calculateTotals();

        } catch (\Exception $e) {
            $this->product_error = true;
            $this->product_error_message = 'Erreur lors de l\'ajout du produit: '.$e->getMessage();
        } finally {
            $this->product_loading = false;
        }
    }

    public function getProductStock($productId)
    {
        if (! $productId) {
            return 0;
        }
        $product = Product::find($productId);

        return $product ? $product->current_stock ?? 0 : 0;
    }

    public function getProductReorderLevel($productId)
    {
        if (! $productId) {
            return 0;
        }
        $product = Product::find($productId);

        return $product ? $product->reorder_level ?? 0 : 0;
    }

    public function getProductSellingPrice($productId)
    {
        if (! $productId) {
            return 0;
        }
        $product = Product::find($productId);

        return $product ? $product->selling_price ?? 0 : 0;
    }

    public function getProductUnitName($productId)
    {
        if (! $productId) {
            return 'N/A';
        }
        $product = Product::find($productId);

        return $product ? $product->saleUnit?->name ?? 'N/A' : 'N/A';
    }

    public function getStockStatusClasses($productId, $neededQty)
    {
        $stock = $this->getProductStock($productId);
        $reorder = $this->getProductReorderLevel($productId);

        if ($stock <= 0 || $stock < $neededQty) {
            return 'bg-red-50 border border-red-200';
        }
        if ($stock <= $reorder) {
            return 'bg-yellow-50 border border-yellow-200';
        }

        return 'bg-green-50 border border-green-200';
    }

    public function render()
    {
        $this->calculateTotals();

        return view('livewire.sales.create');
    }
}
