<?php

namespace App\Livewire\Inventory;

use App\Domain\Inventory\Enums\PurchaseOrderStatus;
use App\Domain\Inventory\Models\PurchaseOrder;
use App\Domain\Inventory\Services\PurchaseOrderService;
use App\Domain\Shared\Exceptions\DomainException;
use App\Domain\Shared\Exceptions\InvalidStatusTransitionException;
use App\Domain\Shared\Traits\UsesBranchScope;
use App\Livewire\Concerns\AppliesRoleScope;
use App\Livewire\Concerns\WithSorting;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

#[Layout('layouts.app')]
#[Title('أوامر الشراء')]
class PurchaseOrderList extends Component
{
    use WithPagination, WithSorting, UsesBranchScope, AppliesRoleScope;

    protected string $scopePermission = 'inventory.manage';

    #[Url]
    public string $search = '';

    #[Url]
    public string $status = '';

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

    public function updatedSearch(): void
    {
        $this->resetPage();
    }

    public function updatedStatus(): void
    {
        $this->resetPage();
    }

    public function receive(int $purchaseOrderId): void
    {
        try {
            $po = PurchaseOrder::with('items')->findOrFail($purchaseOrderId);

            // Auto-receive all remaining quantities
            $receivedItems = $po->items
                ->filter(fn ($item) => $item->quantity_received < $item->quantity_ordered)
                ->map(fn ($item) => [
                    'item_id' => $item->id,
                    'quantity_received' => $item->quantity_ordered - $item->quantity_received,
                ])
                ->values()
                ->toArray();

            if (empty($receivedItems)) {
                session()->flash('error', __('جميع الأصناف مستلمة بالفعل'));
                return;
            }

            app(PurchaseOrderService::class)->receive($po, $receivedItems, auth()->user());

            session()->flash('success', __('تم استلام أمر الشراء بنجاح'));
        } catch (DomainException $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function cancel(int $purchaseOrderId): void
    {
        try {
            $po = PurchaseOrder::findOrFail($purchaseOrderId);
            app(PurchaseOrderService::class)->cancel($po, auth()->user());

            session()->flash('success', __('تم إلغاء أمر الشراء'));
        } catch (InvalidStatusTransitionException|DomainException $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function render()
    {
        $branchId = $this->getActiveBranchId();

        $query = PurchaseOrder::query()
            ->withCount('items')
            ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
            ->when($this->search, function ($q) {
                $search = $this->search;
                $q->where(function ($q2) use ($search) {
                    $q2->where('order_number', 'ilike', "%{$search}%")
                       ->orWhere('supplier_name', 'ilike', "%{$search}%");
                });
            })
            ->when($this->status, fn ($q) => $q->where('status', $this->status))
            ->orderBy($this->sortBy, $this->sortDir);

        $this->applyRoleScope($query);

        return view('livewire.inventory.purchase-order-list', [
            'purchaseOrders' => $query->paginate(20),
            'statuses' => PurchaseOrderStatus::cases(),
        ]);
    }
}
