<?php

namespace App\Livewire\Users;

use App\Models\Company;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules\Password;
use Livewire\Attributes\Layout;
use Livewire\Component;
use Spatie\Permission\Models\Role;

#[Layout('layouts.app')]
class UserForm extends Component
{
    public ?User $user = null;

    // Información personal
    public string $title = '';

    public string $lastName = '';

    public string $firstName = '';

    // Validación
    public string $userStatus = 'active';

    public string $validFrom = '';

    public string $validUntil = '';

    public string $formPassword = '';

    // Contacto
    public ?int $companyId = null;

    public string $address = '';

    public string $phone = '';

    public string $email = '';

    // Permisos
    public string $formRole = '';

    // Preferencias
    public string $locale = 'es';

    // Notas
    public string $notes = '';

    // Catálogos
    public $roles;

    public $companies;

    /** Idiomas disponibles (código => nombre + archivo de bandera). */
    public array $languages = [
        'es' => ['name' => 'Español', 'flag' => 'es.svg'],
        'en' => ['name' => 'English', 'flag' => 'gb.svg'],
        'fr' => ['name' => 'Français', 'flag' => 'fr.svg'],
        'ru' => ['name' => 'Русский', 'flag' => 'ru.svg'],
    ];

    public function mount(?User $user = null): void
    {
        abort_unless(Auth::user()->can('create users') || Auth::user()->can('edit users'), 403);

        $this->roles = Role::orderBy('name')->get();
        $this->companies = Company::where('estado', 'activo')->orderBy('name')->get();
        $this->formRole = $this->roles->first()?->name ?? '';

        if ($user && $user->exists) {
            $this->user = $user;
            $this->title = $user->title ?? '';
            $this->lastName = $user->last_name ?? '';
            $this->firstName = $user->first_name ?? '';
            $this->userStatus = $user->status ?? 'active';
            $this->validFrom = $user->valid_from?->format('Y-m-d') ?? '';
            $this->validUntil = $user->valid_until?->format('Y-m-d') ?? '';
            $this->companyId = $user->company_id;
            $this->address = $user->address ?? '';
            $this->phone = $user->phone ?? '';
            $this->email = $user->email;
            $this->notes = $user->notes ?? '';
            $this->formRole = $user->roles->first()?->name ?? $this->formRole;
            $this->locale = $user->locale ?? $this->locale;
        }
    }

    protected function rules(): array
    {
        $id = $this->user?->id ?? 'NULL';
        $rules = [
            'lastName' => 'required|string|max:100',
            'firstName' => 'required|string|max:100',
            'title' => 'nullable|string|max:20',
            'userStatus' => 'required|in:active,inactive,suspended',
            'validFrom' => 'nullable|date',
            'validUntil' => 'nullable|date|after_or_equal:validFrom',
            'companyId' => 'required|exists:companies,id',
            'address' => 'nullable|string',
            'phone' => 'nullable|string|max:30',
            'email' => "required|email|max:255|unique:users,email,{$id}",
            'formRole' => 'required|exists:roles,name',
            'locale' => 'required|in:'.implode(',', array_keys($this->languages)),
        ];

        if (! $this->user) {
            $rules['formPassword'] = ['required', Password::min(8)->letters()->mixedCase()->numbers()];
        } elseif ($this->formPassword !== '') {
            $rules['formPassword'] = [Password::min(8)->letters()->mixedCase()->numbers()];
        }

        return $rules;
    }

    protected $validationAttributes = [
        'lastName' => 'apellidos',
        'firstName' => 'nombre',
        'userStatus' => 'estado',
        'validFrom' => 'fecha de inicio',
        'validUntil' => 'fecha de fin',
        'companyId' => 'empresa',
        'formPassword' => 'contraseña',
        'formRole' => 'rol',
        'locale' => 'idioma',
    ];

    public function copyCompanyAddress(): void
    {
        if (! $this->companyId) {
            return;
        }
        $company = Company::find($this->companyId);
        if ($company?->address) {
            $this->address = $company->address;
        }
    }

    public function save(): void
    {
        $this->validate();

        if ($this->user && $this->user->id === Auth::id()
            && $this->user->hasRole('Admin') && $this->formRole !== 'Admin') {
            $this->addError('formRole', 'No puedes quitarte el rol Admin a ti mismo.');

            return;
        }

        $fullName = trim($this->firstName.' '.$this->lastName);

        $data = [
            'name' => $fullName,
            'title' => $this->title ?: null,
            'first_name' => $this->firstName,
            'last_name' => $this->lastName,
            'status' => $this->userStatus,
            'valid_from' => $this->validFrom ?: null,
            'valid_until' => $this->validUntil ?: null,
            'company_id' => $this->companyId,
            'address' => $this->address ?: null,
            'phone' => $this->phone ?: null,
            'email' => $this->email,
            'notes' => $this->notes ?: null,
            'locale' => $this->locale,
        ];

        if ($this->formPassword !== '') {
            $data['password'] = Hash::make($this->formPassword);
        }

        if ($this->user && $this->user->exists) {
            $this->user->update($data);
            $this->user->syncRoles([$this->formRole]);
            session()->flash('notify', 'Usuario actualizado correctamente.');
        } else {
            $user = User::create($data);
            $user->assignRole($this->formRole);
            session()->flash('notify', 'Usuario creado correctamente.');
        }

        $this->redirect(route('admin.users'), navigate: true);
    }

    public function render()
    {
        return view('livewire.users.user-form');
    }
}
