<?php

namespace App\Livewire\Users;

use App\Models\Inspection;
use App\Models\Issue;
use App\Models\Project;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\Layout;
use Livewire\Component;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\PermissionRegistrar;

#[Layout('layouts.app')]
class UserView extends Component
{
    public User $user;

    public string $activeTab = 'ficha';

    // Projects tab
    public ?int $addProjectId = null;

    public string $addProjectRole = '';

    public $availableProjects;

    // Notes tab
    public string $notes = '';

    public bool $editingNotes = false;

    // Recent activity (loaded once)
    public $recentInspections;

    public $recentIssues;

    public function mount(User $user): void
    {
        abort_unless(Auth::user()->can('view users'), 403);

        $this->user = $user->load(['roles', 'company', 'projects.phases']);
        $this->notes = $user->notes ?? '';

        $this->loadAvailableProjects();
        $this->loadActivity();
    }

    private function loadAvailableProjects(): void
    {
        $assignedIds = $this->user->projects->pluck('id');
        $this->availableProjects = Project::whereNotIn('id', $assignedIds)
            ->orderBy('name')->get();
    }

    private function loadActivity(): void
    {
        $this->recentInspections = Inspection::where('user_id', $this->user->id)
            ->with(['feature.layer.phase.project', 'template'])
            ->latest()->take(8)->get();

        $this->recentIssues = Issue::where('reported_by', $this->user->id)
            ->with(['feature', 'project'])
            ->latest()->take(8)->get();
    }

    // ── Tabs ─────────────────────────────────────────────────────────────────

    public function setTab(string $tab): void
    {
        $this->activeTab = $tab;
    }

    // ── Projects ──────────────────────────────────────────────────────────────

    public function assignProject(): void
    {
        $this->validate([
            'addProjectId' => 'required|exists:projects,id',
            'addProjectRole' => 'nullable|string|max:100',
        ], [], ['addProjectId' => 'proyecto', 'addProjectRole' => 'rol en proyecto']);

        $this->user->projects()->attach($this->addProjectId, [
            'role_in_project' => $this->addProjectRole ?: null,
        ]);

        $this->user->load('projects.phases');
        $this->addProjectId = null;
        $this->addProjectRole = '';
        $this->loadAvailableProjects();
        $this->dispatch('notify', 'Proyecto asignado.');
    }

    public function removeProject(int $projectId): void
    {
        $this->user->projects()->detach($projectId);
        $this->user->load('projects.phases');
        $this->loadAvailableProjects();
        $this->dispatch('notify', 'Proyecto desasignado.');
    }

    // ── Permissions (direct, per user) ─────────────────────────────────────────

    public function togglePermission(string $name): void
    {
        if ($this->user->hasDirectPermission($name)) {
            $this->user->revokePermissionTo($name);
        } else {
            $this->user->givePermissionTo($name);
        }
        app(PermissionRegistrar::class)->forgetCachedPermissions();
        $this->user->load('roles', 'permissions');
        $this->dispatch('notify', 'Permisos del usuario actualizados');
    }

    public function setUserGroup(string $group, bool $enabled): void
    {
        foreach (Permission::where('group', $group)->pluck('name') as $name) {
            if ($enabled) {
                if (! $this->user->hasPermissionTo($name)) {
                    $this->user->givePermissionTo($name);
                }
            } elseif ($this->user->hasDirectPermission($name)) {
                $this->user->revokePermissionTo($name);
            }
        }
        app(PermissionRegistrar::class)->forgetCachedPermissions();
        $this->user->load('roles', 'permissions');
        $this->dispatch('notify', $enabled ? 'Permisos del grupo concedidos' : 'Permisos directos del grupo quitados');
    }

    // ── Notes ─────────────────────────────────────────────────────────────────

    public function saveNotes(): void
    {
        $this->validate(['notes' => 'nullable|string']);
        $this->user->update(['notes' => $this->notes ?: null]);
        $this->editingNotes = false;
        $this->dispatch('notify', 'Notas guardadas.');
    }

    public function render()
    {
        $order = [
            'Proyectos', 'Fases y progreso', 'Capas y elementos', 'Inspecciones',
            'Incidencias', 'Empresas', 'Usuarios', 'Roles', 'Informes', 'Archivos', 'General',
        ];

        $grouped = Permission::orderBy('name')->get()
            ->groupBy(fn ($perm) => $perm->group ?: 'General')
            ->sortBy(function ($perms, $section) use ($order) {
                $i = array_search($section, $order, true);

                return $i === false ? 999 : $i;
            });

        return view('livewire.users.user-view', [
            'grouped' => $grouped,
            'directPerms' => $this->user->getDirectPermissions()->pluck('name')->toArray(),
            'rolePerms' => $this->user->getPermissionsViaRoles()->pluck('name')->toArray(),
        ]);
    }
}
