<?php

namespace App\Livewire\Facilities;

use App\Domain\Facility\Enums\FacilityStatus;
use App\Domain\Facility\Enums\FacilityType;
use App\Domain\Facility\Models\Facility;
use App\Domain\Facility\Services\FacilityService;
use App\Domain\Shared\Exceptions\DomainException;
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 FacilityList extends Component
{
    use WithPagination, WithSorting, AppliesRoleScope;

    protected string $scopePermission = 'facilities.list';

    public function mount(): void
    {
        if (! request()->has('sortBy')) {
            $this->sortBy = 'name_ar';
            $this->sortDir = 'asc';
        }
    }

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

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

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

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

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

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

    /**
     * The uuid comes from wire:click, so it is browser-supplied. It needs no
     * branch clause of its own: Facility carries BranchScope, so this lookup
     * 404s on another branch's facility rather than deleting it.
     */
    public function delete(string $uuid, FacilityService $service): void
    {
        // The route only carries facilities.list, and the button is hidden by
        // @permission — but a Livewire action is callable from the browser
        // whether or not its button was rendered, so the check has to be here
        // too.
        $this->authorize('facilities.delete');

        try {
            $facility = Facility::where('uuid', $uuid)->firstOrFail();
            $service->delete($facility);
            session()->flash('success', __('تم حذف المنشأة بنجاح'));
        } catch (DomainException $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function render()
    {
        // No branch clause and no per-screen branch picker. The topbar switcher
        // is the only branch selector, and BranchScope narrows this query to it;
        // a second control here was how a user locked to one branch could list
        // another branch's facilities by setting ?branch_id= in the URL.
        $query = Facility::query()
            ->with('branch')
            ->when($this->search, function ($q) {
                $search = $this->search;
                $q->where(function ($q2) use ($search) {
                    $q2->where('name_ar', 'ilike', "%{$search}%")
                       ->orWhere('name', 'ilike', "%{$search}%")
                       ->orWhere('code', 'ilike', "%{$search}%");
                });
            })
            ->when($this->status, fn ($q) => $q->where('status', $this->status))
            ->when($this->type, fn ($q) => $q->where('type', $this->type))
            ->orderBy($this->sortBy, $this->sortDir);

        $this->applyRoleScope($query);

        return view('livewire.facilities.facility-list', [
            'facilities' => $query->paginate(20),
            'statusOptions' => collect(FacilityStatus::cases())->mapWithKeys(fn ($s) => [$s->value => $s->label()]),
            'typeOptions' => collect(FacilityType::cases())->mapWithKeys(fn ($t) => [$t->value => $t->label()]),
        ]);
    }
}
