<?php

namespace App\Livewire\Inventory;

use App\Domain\Financial\Models\InvoiceItem;
use App\Domain\Inventory\Models\Product;
use App\Domain\Shared\Traits\UsesBranchScope;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

#[Layout('layouts.app')]
#[Title('تسليم المنتجات الأساسية')]
class EssentialDeliveries extends Component
{
    use WithPagination, UsesBranchScope;

    #[Url]
    public ?int $product_id = null;

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

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

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

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

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

    public function markDelivered(int $itemId): void
    {
        $this->authorize('inventory.update');

        $item = InvoiceItem::findOrFail($itemId);

        $item->update([
            'is_delivered' => true,
            'delivered_at' => now(),
            'delivered_by' => auth()->id(),
        ]);

        session()->flash('success', __('تم تسجيل الاستلام بنجاح'));
    }

    public function markUndelivered(int $itemId): void
    {
        $this->authorize('inventory.update');

        $item = InvoiceItem::findOrFail($itemId);

        $item->update([
            'is_delivered' => false,
            'delivered_at' => null,
            'delivered_by' => null,
        ]);
    }

    public function render()
    {
        // Product carries BelongsToBranch in shared mode, so this already reads
        // "this branch's products plus the academy-wide ones" — the hand-written
        // branch-or-NULL predicate that used to be here said the same thing twice.
        $essentialProductIds = Product::where('is_essential', true)
            ->where('is_active', true)
            ->pluck('id');

        // Branch isolation comes from InvoiceItem's ScopedThroughBranch('invoice'):
        // the item is in the branch its invoice is in. The old participant-branch
        // filter that used to stand here was both redundant and too narrow — being
        // a whereHasMorph on Participant, it silently dropped every invoice billed
        // to anything else, and the pendingCount below never had it, so the KPI and
        // the table disagreed.
        $query = InvoiceItem::with(['invoice.billable.person', 'deliveredBy'])
            ->whereIn('itemable_id', $essentialProductIds)
            ->where('itemable_type', Product::class)
            ->whereHas('invoice', fn ($q) => $q->whereIn('status', ['sent', 'paid', 'partially_paid']))
            ->when($this->product_id, fn ($q) => $q->where('itemable_id', $this->product_id))
            ->when($this->status === 'pending', fn ($q) => $q->where('is_delivered', false))
            ->when($this->status === 'delivered', fn ($q) => $q->where('is_delivered', true))
            ->when($this->search, function ($q) {
                $q->whereHas('invoice.billable.person', fn ($pq) =>
                    $pq->where('name_ar', 'ilike', "%{$this->search}%")
                       ->orWhere('name', 'ilike', "%{$this->search}%")
                       ->orWhere('national_id', 'ilike', "%{$this->search}%")
                );
            })
            ->orderBy('is_delivered')
            ->orderByDesc('created_at');

        return view('livewire.inventory.essential-deliveries', [
            'items' => $query->paginate(25),
            'essentialProducts' => Product::where('is_essential', true)->where('is_active', true)->get(['id', 'name_ar']),
            'pendingCount' => InvoiceItem::whereIn('itemable_id', $essentialProductIds)
                ->where('itemable_type', Product::class)
                ->where('is_delivered', false)
                ->whereHas('invoice', fn ($q) => $q->whereIn('status', ['sent', 'paid', 'partially_paid']))
                ->count(),
        ]);
    }
}
