<?php

namespace App\Livewire\Products;

use App\Models\Category;
use App\Models\Product;
use App\Models\Unit;
use Livewire\Attributes\Layout;
use Livewire\Component;

#[Layout('layouts.dashboard')]
class Edit extends Component
{
    public Product $product;

    // General Information
    public string $name = '';

    public ?string $generic_name = null;

    public ?int $category_id = null;

    public ?string $brand = null;

    public ?string $sku = null;

    // Unit Information
    public ?int $purchase_unit_id = null;

    public ?int $sale_unit_id = null;

    public ?float $conversion_factor = null;

    // Stock Information
    public ?float $selling_price = null;

    public ?float $purchase_price = null;

    public ?int $reorder_level = null;

    public ?int $current_stock = null;

    // Options
    public array $categories = [];

    public array $units = [];

    // UI
    public bool $loading = false;

    public bool $successGeneral = false;

    public bool $successUnits = false;

    public bool $successStock = false;

    public function mount(Product $product): void
    {
        $this->product = $product->load(['category', 'purchaseUnit', 'saleUnit']);

        // General Information
        $this->name = (string) $product->name;
        $this->generic_name = $product->generic_name;
        $this->category_id = $product->category_id;
        $this->brand = $product->brand;
        $this->sku = $product->sku;

        // Unit Information
        $this->purchase_unit_id = $product->purchase_unit_id;
        $this->sale_unit_id = $product->sale_unit_id;
        $this->conversion_factor = $product->conversion_factor;
        $this->reorder_level = $product->reorder_level ?? 1;

        // Stock Information
        $this->selling_price = $product->selling_price;
        $this->purchase_price = $product->purchase_price;
        $this->current_stock = $product->current_stock;

        // Load options
        $this->loadCategories();
        $this->loadUnits();
    }

    public function loadCategories(): void
    {
        $this->categories = Category::orderBy('name')
            ->get(['id', 'name'])
            ->map(fn ($c) => ['id' => $c->id, 'name' => $c->name])
            ->toArray();
    }

    public function loadUnits(): void
    {
        $this->units = Unit::orderBy('name')
            ->get(['id', 'name'])
            ->map(fn ($u) => ['id' => $u->id, 'name' => $u->name])
            ->toArray();
    }

    public function saveGeneral(): void
    {
        $this->resetErrorBag();
        $this->loading = true;
        try {
            $this->validate([
                'name' => ['required', 'string', 'max:255'],
                'generic_name' => ['nullable', 'string', 'max:255'],
                'category_id' => ['nullable', 'exists:categories,id'],
                'brand' => ['nullable', 'string', 'max:255'],
                'sku' => ['nullable', 'string', 'max:255', 'unique:products,sku,'.$this->product->id],
            ]);

            $data = [
                'name' => $this->name,
                'generic_name' => $this->generic_name,
                'category_id' => $this->category_id,
                'brand' => $this->brand,
                'sku' => $this->sku,
            ];

            if ($this->name !== $this->product->name && method_exists($this->product, 'generateSlug')) {
                $data['slug'] = Product::generateSlug($this->name);
            }

            $this->product->update($data);
            $this->successGeneral = true;
        } catch (\Throwable $e) {
            report($e);
            $this->addError('error_general', "Une erreur est survenue lors de l'enregistrement des informations générales.");
        } finally {
            $this->loading = false;
        }
    }

    public function saveUnits(): void
    {
        $this->resetErrorBag();
        $this->loading = true;
        try {
            $this->validate([
                'purchase_unit_id' => ['required', 'exists:units,id'],
                'sale_unit_id' => ['required', 'exists:units,id'],
                'conversion_factor' => ['required', 'numeric', 'min:0.0001'],
                'reorder_level' => ['nullable', 'integer', 'min:0'],
            ]);

            $data = [
                'purchase_unit_id' => $this->purchase_unit_id,
                'sale_unit_id' => $this->sale_unit_id,
                'conversion_factor' => $this->conversion_factor,
                'reorder_level' => $this->reorder_level,
            ];

            $this->product->update($data);
            $this->successUnits = true;
        } catch (\Throwable $e) {
            report($e);
            $this->addError('error_units', "Une erreur est survenue lors de l'enregistrement des unités.");
        } finally {
            $this->loading = false;
        }
    }

    public function saveStock(): void
    {
        $this->resetErrorBag();
        $this->loading = true;
        try {
            $this->validate([
                'selling_price' => ['required', 'numeric', 'min:0'],
                'purchase_price' => ['required', 'numeric', 'min:0'],
            ]);

            $data = [
                'selling_price' => $this->selling_price,
                'purchase_price' => $this->purchase_price,
            ];

            $this->product->update($data);
            $this->successStock = true;
        } catch (\Throwable $e) {
            report($e);
            $this->addError('error_stock', "Une erreur est survenue lors de l'enregistrement des informations de stock.");
        } finally {
            $this->loading = false;
        }
    }

    public function generateSKU(): void
    {
        $this->sku = Product::generateUniqueSKU($this->name);
    }

    public function render(): \Illuminate\Contracts\View\View
    {
        return view('livewire.products.edit');
    }
}
