<?php

namespace App\Http\Requests;

use App\Models\User;
use App\Support\UsernamePolicy;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class UsernameRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    protected function prepareForValidation(): void
    {
        if ($this->has('username')) {
            $this->merge([
                'username' => UsernamePolicy::normalize((string) $this->input('username')),
            ]);
        }
    }

    public function rules(): array
    {
        return [
            'username' => self::rulesFor($this->resolveIgnoreUserId()),
        ];
    }

    /**
     * @return array<int, mixed>
     */
    public static function rulesFor(?int $ignoreUserId = null): array
    {
        return [
            ...self::formatRules(),
            Rule::unique(User::class, 'username')->ignore($ignoreUserId),
        ];
    }

    /**
     * @return array<int, mixed>
     */
    public static function formatRules(): array
    {
        return [
            'required',
            'string',
            'min:' . UsernamePolicy::min(),
            'max:' . UsernamePolicy::max(),
            'regex:' . UsernamePolicy::regex(),
            Rule::notIn(UsernamePolicy::reserved()),
        ];
    }

    private function resolveIgnoreUserId(): ?int
    {
        $user = $this->user();
        if ($user) {
            return (int) $user->id;
        }

        $routeUserId = $this->route('id') ?? $this->route('user');
        if (is_numeric($routeUserId)) {
            return (int) $routeUserId;
        }

        return null;
    }
}
