<?php

namespace App\Filament\Resources\Users\Schemas;

use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Schemas\Schema;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Spatie\Permission\Models\Role;

class UserForm
{
    public static function configure(Schema $schema): Schema
    {
        $user = Auth::user();
        $isSuperAdmin = $user?->isSuperAdmin() ?? false; // Verifica si es Super Admin

        // El super_admin global NO pertenece a ninguna empresa (company_id = null,
        // ver User::isSuperAdmin()). Así que la compañía es obligatoria para todos
        // los roles MENOS super_admin; si no, editar al super_admin (p.ej. cambiar su
        // contraseña) fallaba con "required" sobre un campo que debe quedar vacío.
        $superAdminRoleId = (int) (Role::where('name', 'super_admin')->value('id') ?? 0);

        return $schema
            ->components([
                // 1. CAMPO COMPANY_ID (Visible solo para Super Admin)
                Select::make('company_id')
                    ->label('Compañía Asignada')
                    ->relationship('company', 'name')
                    ->searchable()
                    ->preload()
                    ->required(fn ($get): bool => ! in_array(
                        $superAdminRoleId,
                        array_map('intval', (array) $get('roles')),
                        true,
                    ))
                    ->default(fn () => $isSuperAdmin ? null : $user->company_id)
                    ->hidden(fn () => ! $isSuperAdmin),
                // 2. CAMPO NOMBRE
                TextInput::make('name')
                    ->label('Nombre Completo')
                    ->required()
                    ->maxLength(255),
                // 3. CAMPO EMAIL
                TextInput::make('email')
                    ->label('Correo Electrónico')
                    ->email()
                    ->required()
                    ->unique(ignoreRecord: true)
                    ->maxLength(255),
                // 4. CAMPO PHONE
                TextInput::make('phone')
                    ->tel()
                    ->default(null),

                // 5. CAMPO DE ROL (CRÍTICO: SOLUCIÓN AL ARRAY TO STRING CONVERSION)
                Select::make('roles')
                    ->label('Rol')
                    ->relationship(
                        name: 'roles',
                        titleAttribute: 'name', // Usa el nombre del rol
                        // Modifica la consulta para filtrar roles no permitidos
                        modifyQueryUsing: fn (Builder $query) => $isSuperAdmin
                                ? $query
                                : $query->where('name', '!=', 'super_admin') // Company Admin no ve el Super Admin
                    )
                    // CORRECCIÓN 1: Dejarlo como MULTIPLE es la única forma de manejar la relación many-to-many de Spatie.
                    // PERO, debemos asegurarnos de que solo se guarde uno.
                    ->multiple()
                    // CORRECCIÓN 2: Mutar el estado al cargar el formulario.
                    // Al cargar (deshidratar), Filament obtiene una colección de Roles.
                    // Aquí extraemos el ID del primer rol (asumiendo que solo hay uno) para que el Select lo muestre correctamente.
                    ->dehydrateStateUsing(fn (array $state): int => $state[0] ?? null) // Cuando se guarda, toma el primer ID de rol.
                    ->getOptionLabelFromRecordUsing(fn ($record) => match ($record->name) {
                        'admin' => 'Administrador de Compañía',
                        'supervisor' => 'Supervisor',
                        'collector' => 'Cobrador',
                        'client' => 'Cliente',
                        'super_admin' => 'Super Administrador Global',
                        default => $record->name,
                    })
                    ->preload()
                    ->required(),

                // 6. TOGGLE sees_all_collectors (solo supervisors)
                // Permite a un supervisor ver todo el equipo de la empresa sin
                // necesidad de asignaciones individuales — útil cuando el admin
                // actúa también como supervisor de campo.
                Toggle::make('sees_all_collectors')
                    ->label('Ver todos los cobradores de la empresa')
                    ->helperText('Actívalo si este supervisor debe supervisar a todo el equipo, no solo a sus cobradores asignados.')
                    ->visible(fn ($record): bool => $record?->hasAnyRole(['supervisor', 'admin']) ?? false),

                // 7. CAMPO CONTRASEÑA (Hashed en Create/Edit)
                TextInput::make('password')
                    ->label('Contraseña')
                    ->password()
                    ->dehydrateStateUsing(fn (string $state): string => Hash::make($state))
                    ->dehydrated(fn (?string $state): bool => filled($state))
                    ->required(fn (string $operation): bool => $operation === 'create'),
            ]);
    }
}
