<?php

namespace App\Livewire\Users;

use App\Domain\Shared\Traits\UsesBranchScope;
use App\Livewire\Concerns\WithSorting;
use App\Livewire\Users\Concerns\FiltersUsersByBranch;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

#[Layout('layouts.app')]
#[Title('المستخدمين')]
class UserList extends Component
{
    use WithPagination, WithSorting, UsesBranchScope, FiltersUsersByBranch;

    #[Url]
    public string $search = '';
    public string $role = '';
    public bool $showInactive = false;

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

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

    public function toggleActive(string $uuid): void
    {
        // Deactivating an account is an update; the method was reachable from
        // the browser with no permission check at all.
        $this->authorize('users.update');

        $user = $this->findInBranch($uuid);
        $newStatus = $user->status === 'active' ? 'inactive' : 'active';
        $user->update(['status' => $newStatus]);
    }

    public function deleteUser(string $uuid): void
    {
        $this->authorize('users.delete');

        $user = $this->findInBranch($uuid);

        if ($user->person_id) {
            $user->person?->update(['user_id' => null]);
        }

        $user->delete();
        session()->flash('success', 'تم حذف المستخدم بنجاح');
    }

    /**
     * A uuid off the wire is an id like any other.
     *
     * Both actions used to resolve it against the whole academy, so a uuid
     * copied out of another branch's list deactivated or deleted that account.
     * Resolving through exactly the query that rendered the list means an
     * account this branch cannot see is an account it cannot touch.
     */
    private function findInBranch(string $uuid): \App\Models\User
    {
        return $this->branchUsers()->where('uuid', $uuid)->firstOrFail();
    }

    public function render()
    {
        $query = $this->branchUsers()
            ->with('primaryRole')
            ->when($this->search, function ($q) {
                $q->where(function ($q2) {
                    $q2->where('name_ar', 'ilike', "%{$this->search}%")
                       ->orWhere('name', 'ilike', "%{$this->search}%")
                       ->orWhere('email', 'ilike', "%{$this->search}%");
                });
            })
            ->when($this->role, fn ($q) => $q->where('role_id', $this->role))
            ->when(!$this->showInactive, fn ($q) => $q->where('status', 'active'))
            ->orderBy($this->sortBy, $this->sortDir);

        return view('livewire.users.user-list', [
            'users' => $query->paginate(20),
            'roles' => \App\Domain\Identity\Models\Role::orderBy('level', 'desc')->get(['id', 'name_ar']),
        ]);
    }
}
