<?php

namespace App\Filament\Pages\Auth;

use Filament\Auth\Pages\EditProfile as BaseEditProfile;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Schemas\Components\Component;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Schema;
use Illuminate\Support\Facades\Hash;

class EditProfile extends BaseEditProfile
{
    protected int $maxPinLength = 8;

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                $this->getNameFormComponent(),
                $this->getEmailFormComponent(),
                $this->getPasswordFormComponent(),
                $this->getPasswordConfirmationFormComponent(),
                $this->getCurrentPasswordFormComponent(),
                $this->getAdminPinFormComponent(),
                $this->getRemoveAdminPinFormComponent(),
            ]);
    }

    protected function getAdminPinFormComponent(): Component
    {
        return TextInput::make('admin_pin')
            ->label('Admin PIN')
            ->password()
            ->revealable()
            ->afterStateHydrated(function (TextInput $component): void {
                $component->state(null);
            })
            ->disabled(fn (Get $get): bool => (bool) $get('remove_admin_pin'))
            ->helperText('Leave blank to keep the current PIN. Use only digits.')
            ->rule('regex:/^\\d+$/')
            ->minLength(4)
            ->maxLength($this->maxPinLength);
    }

    protected function getRemoveAdminPinFormComponent(): Component
    {
        return Toggle::make('remove_admin_pin')
            ->label('Remove admin PIN')
            ->helperText('Clears the PIN so this user no longer appears on the kiosk login.')
            ->default(false);
    }

    /**
     * @param  array<string, mixed>  $data
     * @return array<string, mixed>
     */
    protected function mutateFormDataBeforeSave(array $data): array
    {
        $pin = (string) ($data['admin_pin'] ?? '');
        $removePin = (bool) ($data['remove_admin_pin'] ?? false);

        if ($removePin) {
            $data['admin_pin_hash'] = null;
        } elseif ($pin !== '') {
            $data['admin_pin_hash'] = Hash::make($pin);
        }

        unset($data['admin_pin'], $data['remove_admin_pin']);

        return $data;
    }
}
