<?php

namespace App\Services\Administracion\Crud;

use App\Models\Usuario;
use App\Rules\UserRules;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;

class UsersCrudService extends CrudEntityService
{
    protected string $entity = 'users';

    protected string $modelClass = Usuario::class;

    protected array $entityLabels = [
        'singular' => 'Personal',
        'plural' => 'Personal',
        'create' => 'Nuevo Personal',
    ];

    protected array $tableColumns = ['nombre', 'cedula', 'cargo'];

    protected array $tableLabels = [
        'nombre' => 'Nombre',
        'cedula' => 'Cédula',
        'cargo' => 'Cargo',
        'tipo' => 'Acceso del sistema',
    ];

    protected array $formLabels = [
        'codigo' => 'Código',
        'cedula' => 'Cédula',
        'password' => 'Clave',
        'nombre' => 'Nombre',
        'cargo' => 'Cargo',
        'dependencia' => 'Dependencia',
        'ficha' => 'Ficha',
        'fechaIngreso' => 'Fecha de Ingreso',
    ];

    protected bool $showRowNumber = true;

    protected function validationRules(bool $isUpdate = false, ?int $id = null): array
    {
        return UserRules::rules($isUpdate, $id);
    }

    protected function fieldOptions(): array
    {
        return [
            'tipo' => Usuario::roleOptions(),
            'cargo' => Usuario::cargoOptions(),
            'dependencia' => $this->buildUserDependenciaOptions(),
        ];
    }

    protected function applyEntityDefaultValues(array &$defaults): void
    {
        if (array_key_exists('tipo', $defaults)) {
            $defaults['tipo'] = Usuario::ROLE_TYPE_MAP[Usuario::ROLE_GESTOR];
        }

        if (array_key_exists('cargo', $defaults)) {
            $defaults['cargo'] = Usuario::ROLE_LABELS[Usuario::ROLE_GESTOR];
        }
    }

    protected function applyEntityPayloadMutations(array &$payload, bool $isUpdate): void
    {
        $codigo = trim((string) ($payload['codigo'] ?? ''));
        $cedula = trim((string) ($payload['cedula'] ?? ''));

        if ($codigo === '' && $cedula !== '') {
            $payload['codigo'] = $cedula;
        }

        $roleKey = Usuario::resolveRoleKey(
            isset($payload['cargo']) ? (string) $payload['cargo'] : null,
            $payload['tipo'] ?? null,
        );

        if ($roleKey !== null) {
            $payload['cargo'] = Usuario::roleLabelFromKey($roleKey);
            $payload['tipo'] = Usuario::roleTypeFromKey($roleKey);
        }
    }

    protected function afterSave(Request $request, Model $record, bool $isUpdate): void
    {
        $this->storeUsuarioPhoto($request, $record);
    }

    protected function requiresPasswordOnImport(): bool
    {
        return true;
    }

    protected function resolveEditableColumns(Model $model): array
    {
        $columns = array_values(array_filter(
            $this->getEditableColumns($model),
            static fn (string $column): bool => ! in_array($column, [
                'name',
                'email',
                'clave',
                'tipo',
                'cedulaEditor',
                'tallaCamisa',
                'tallaChaqueta',
                'tallaPantalon',
                'tallaBotas',
                'tallaZapatos',
            ], true)
        ));

        usort($columns, static function (string $left, string $right): int {
            $priority = ['cedula' => 1, 'password' => 2];
            $leftPriority = $priority[$left] ?? 999;
            $rightPriority = $priority[$right] ?? 999;

            return $leftPriority === $rightPriority
                ? strcmp($left, $right)
                : $leftPriority <=> $rightPriority;
        });

        return $columns;
    }
}