<?php

namespace App\Livewire\Inventory;

use App\Domain\Inventory\Models\Product;
use App\Domain\Inventory\Models\Warehouse;
use App\Domain\Shared\Exceptions\DomainException;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.app')]
#[Title('تسوية المخزون')]
class StockAdjustment extends Component
{
    public ?int $product_id = null;
    public ?int $warehouse_id = null;
    public int $quantity = 0;
    public string $adjustment_type = 'adjustment_up';
    public string $reason = '';
    public string $reference_number = '';

    public function mount(): void
    {
        $this->authorize('inventory.adjust');
    }

    public function rules(): array
    {
        return [
            'product_id' => 'required|exists:products,id',
            'warehouse_id' => 'required|exists:warehouses,id',
            'quantity' => 'required|integer|min:1',
            'adjustment_type' => 'required|in:adjustment_up,adjustment_down',
            'reason' => 'required|string|max:500',
            'reference_number' => 'nullable|string|max:50',
        ];
    }

    public function messages(): array
    {
        return [
            'product_id.required' => 'يجب اختيار المنتج',
            'product_id.exists' => 'المنتج غير موجود',
            'warehouse_id.required' => 'يجب اختيار المستودع',
            'warehouse_id.exists' => 'المستودع غير موجود',
            'quantity.required' => 'الكمية مطلوبة',
            'quantity.integer' => 'الكمية يجب أن تكون عددًا صحيحًا',
            'quantity.min' => 'الكمية يجب أن تكون 1 على الأقل',
            'adjustment_type.required' => 'نوع التسوية مطلوب',
            'adjustment_type.in' => 'نوع التسوية غير صالح',
            'reason.required' => 'سبب التسوية مطلوب',
            'reason.max' => 'سبب التسوية يجب ألا يتجاوز 500 حرف',
        ];
    }

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

        try {
            DB::transaction(function () {
                $direction = $this->adjustment_type === 'adjustment_up' ? 'in' : 'out';

                // Get or create inventory level
                $level = DB::table('inventory_levels')
                    ->where('product_id', $this->product_id)
                    ->where('warehouse_id', $this->warehouse_id)
                    ->lockForUpdate()
                    ->first();

                $quantityBefore = $level ? $level->quantity_on_hand : 0;

                if ($direction === 'out' && $quantityBefore < $this->quantity) {
                    throw new DomainException(__('الكمية المتاحة غير كافية. المتاح: ') . $quantityBefore);
                }

                $quantityAfter = $direction === 'in'
                    ? $quantityBefore + $this->quantity
                    : $quantityBefore - $this->quantity;

                // Update or create inventory level
                if ($level) {
                    DB::table('inventory_levels')
                        ->where('id', $level->id)
                        ->update([
                            'quantity_on_hand' => $quantityAfter,
                            'quantity_available' => $quantityAfter - ($level->quantity_reserved ?? 0),
                            'last_movement_at' => now(),
                            'updated_at' => now(),
                        ]);
                } else {
                    DB::table('inventory_levels')->insert([
                        'academy_id' => app('current_academy')?->id ?? auth()->user()->academy_id,
                        'product_id' => $this->product_id,
                        'warehouse_id' => $this->warehouse_id,
                        'quantity_on_hand' => $quantityAfter,
                        'quantity_reserved' => 0,
                        'quantity_available' => $quantityAfter,
                        'last_movement_at' => now(),
                        'created_at' => now(),
                        'updated_at' => now(),
                    ]);
                }

                // Create movement record
                DB::table('inventory_movements')->insert([
                    'academy_id' => app('current_academy')?->id ?? auth()->user()->academy_id,
                    'product_id' => $this->product_id,
                    'warehouse_id' => $this->warehouse_id,
                    'movement_type' => $this->adjustment_type,
                    'direction' => $direction,
                    'quantity' => $this->quantity,
                    'quantity_before' => $quantityBefore,
                    'quantity_after' => $quantityAfter,
                    'reference_number' => $this->reference_number ?: null,
                    'reason' => $this->reason,
                    'created_by' => auth()->id(),
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);
            });

            session()->flash('success', __('تمت التسوية بنجاح'));
            $this->reset(['product_id', 'warehouse_id', 'quantity', 'reason', 'reference_number']);
            $this->adjustment_type = 'adjustment_up';
        } catch (DomainException $e) {
            session()->flash('error', $e->getMessage());
        } catch (\Exception $e) {
            session()->flash('error', __('حدث خطأ أثناء التسوية'));
        }
    }

    public function render()
    {
        return view('livewire.inventory.stock-adjustment', [
            'products' => Product::active()
                ->where('track_inventory', true)
                ->orderBy('name_ar')
                ->get(['id', 'name_ar', 'sku']),
            'warehouses' => Warehouse::active()->orderBy('name_ar')->get(['id', 'name_ar', 'code']),
        ]);
    }
}
