<?php

namespace App\Livewire\Inventory;

use App\Domain\Inventory\Enums\ProductType;
use App\Domain\Inventory\Models\Product;
use App\Domain\Inventory\Models\ProductCategory;
use App\Domain\Shared\Exceptions\DomainException;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.app')]
#[Title('المنتجات')]
class ProductForm extends Component
{
    public ?Product $product = null;
    public bool $editing = false;

    public string $name_ar = '';
    public string $name = '';
    public string $sku = '';
    public string $barcode = '';
    public ?int $category_id = null;
    public string $type = 'physical';
    public string $selling_price = '';
    public string $cost_price = '';
    public bool $track_inventory = true;
    public ?int $min_stock_level = null;
    public ?int $max_stock_level = null;
    public string $tax_rate = '0';
    public bool $is_active = true;
    public string $description_ar = '';

    public function mount(?Product $product = null): void
    {
        $this->authorize('inventory.create');

        if ($product && $product->exists) {
            $this->authorize('inventory.update');
            $this->product = $product;
            $this->editing = true;

            $this->name_ar = $product->name_ar ?? '';
            $this->name = $product->name ?? '';
            $this->sku = $product->sku ?? '';
            $this->barcode = $product->barcode ?? '';
            $this->category_id = $product->category_id;
            $this->type = $product->type->value ?? 'physical';
            $this->selling_price = $product->selling_price ? (string) ($product->selling_price / 100) : '';
            $this->cost_price = $product->cost_price ? (string) ($product->cost_price / 100) : '';
            $this->track_inventory = $product->track_inventory;
            $this->min_stock_level = $product->min_stock_level;
            $this->max_stock_level = $product->max_stock_level;
            $this->tax_rate = (string) ($product->tax_rate ?? 0);
            $this->is_active = $product->is_active;
            $this->description_ar = $product->description_ar ?? '';
        }
    }

    public function rules(): array
    {
        $uniqueSku = $this->editing
            ? 'unique:products,sku,' . $this->product->id
            : 'unique:products,sku';

        return [
            'name_ar' => 'required|string|max:255',
            'name' => 'nullable|string|max:255',
            'sku' => ['nullable', 'string', 'max:50', $uniqueSku],
            'barcode' => 'nullable|string|max:50',
            'category_id' => 'nullable|exists:product_categories,id',
            'type' => 'required|in:physical,digital,service',
            'selling_price' => 'required|numeric|min:0',
            'cost_price' => 'nullable|numeric|min:0',
            'track_inventory' => 'boolean',
            'min_stock_level' => 'nullable|integer|min:0',
            'max_stock_level' => 'nullable|integer|min:0',
            'tax_rate' => 'nullable|numeric|min:0|max:100',
            'is_active' => 'boolean',
            'description_ar' => 'nullable|string|max:1000',
        ];
    }

    public function messages(): array
    {
        return [
            'name_ar.required' => 'اسم المنتج بالعربية مطلوب',
            'name_ar.max' => 'اسم المنتج يجب ألا يتجاوز 255 حرف',
            'sku.required' => 'رمز المنتج (SKU) مطلوب',
            'sku.unique' => 'رمز المنتج مستخدم بالفعل',
            'sku.max' => 'رمز المنتج يجب ألا يتجاوز 50 حرف',
            'type.required' => 'نوع المنتج مطلوب',
            'type.in' => 'نوع المنتج غير صالح',
            'selling_price.required' => 'سعر البيع مطلوب',
            'selling_price.numeric' => 'سعر البيع يجب أن يكون رقمًا',
            'selling_price.min' => 'سعر البيع يجب ألا يكون سالبًا',
            'cost_price.numeric' => 'سعر التكلفة يجب أن يكون رقمًا',
            'cost_price.min' => 'سعر التكلفة يجب ألا يكون سالبًا',
            'min_stock_level.integer' => 'الحد الأدنى يجب أن يكون عددًا صحيحًا',
            'max_stock_level.integer' => 'الحد الأقصى يجب أن يكون عددًا صحيحًا',
            'tax_rate.numeric' => 'نسبة الضريبة يجب أن تكون رقمًا',
            'tax_rate.max' => 'نسبة الضريبة يجب ألا تتجاوز 100%',
            'category_id.exists' => 'التصنيف غير موجود',
        ];
    }

    public function save(): void
    {
        $this->validate();

        try {
            $data = [
                'name_ar' => $this->name_ar,
                'name' => $this->name ?: null,
                'sku' => $this->sku ?: $this->generateSku(),
                'barcode' => $this->barcode ?: null,
                'category_id' => $this->category_id,
                'type' => $this->type,
                'selling_price' => (int) round((float) $this->selling_price * 100),
                'cost_price' => $this->cost_price ? (int) round((float) $this->cost_price * 100) : null,
                'track_inventory' => $this->track_inventory,
                'min_stock_level' => $this->min_stock_level,
                'max_stock_level' => $this->max_stock_level,
                'tax_rate' => (int) $this->tax_rate,
                'is_active' => $this->is_active,
                'description_ar' => $this->description_ar ?: null,
            ];

            if ($this->editing) {
                $this->product->update($data);
                session()->flash('success', __('تم تحديث المنتج بنجاح'));
            } else {
                $data['created_by'] = auth()->id();
                $data['branch_id'] = session('active_branch_id');
                Product::create($data);
                session()->flash('success', __('تم إنشاء المنتج بنجاح'));
            }

            $this->redirect(route('inventory.products'), navigate: true);
        } catch (DomainException $e) {
            session()->flash('error', $e->getMessage());
        } catch (\Illuminate\Database\QueryException $e) {
            if (str_contains($e->getMessage(), 'unique')) {
                session()->flash('error', __('رمز المنتج (SKU) مستخدم بالفعل'));
            } else {
                session()->flash('error', __('حدث خطأ أثناء حفظ المنتج'));
            }
        }
    }

    private function generateSku(): string
    {
        $prefix = match ($this->type) {
            'service' => 'SRV',
            'digital' => 'DIG',
            default => 'PRD',
        };
        $count = Product::withoutGlobalScopes()->count() + 1;
        return $prefix . '-' . str_pad($count, 4, '0', STR_PAD_LEFT);
    }

    public function render()
    {
        return view('livewire.inventory.product-form', [
            'categories' => ProductCategory::active()->orderBy('name_ar')->get(['id', 'name_ar']),
            'typeOptions' => [
                'physical' => 'منتج مادي',
                'digital' => 'منتج رقمي',
                'service' => 'خدمة',
            ],
        ]);
    }
}
