<?php

namespace App\Support;

use Illuminate\Validation\Rules\Password;

/**
 * Single source of truth for password validation rules and messages.
 * Used by: first-login set password, forgot-password reset, profile update, registration.
 */
class PasswordPolicy
{
    /**
     * Base validation rules for the password field (without 'confirmed').
     * Use: 'password' => array_merge(PasswordPolicy::rules(), ['confirmed'])
     *
     * @return array<int, mixed>
     */
    public static function rules(): array
    {
        $min = (int) config('auth.password_min_length', 10);
        $rule = Password::min($min)->letters()->numbers();

        if (config('auth.password_require_mixed_case', false)) {
            $rule = $rule->mixedCase();
        }
        if (config('auth.password_require_symbols', false)) {
            $rule = $rule->symbols();
        }
        if (config('auth.password_uncompromised', false)) {
            $rule = $rule->uncompromised();
        }

        return ['required', 'string', $rule];
    }

    /**
     * Custom validation messages for password and confirmation.
     *
     * @return array<string, string>
     */
    public static function messages(): array
    {
        $min = (int) config('auth.password_min_length', 10);

        return [
            'password.required' => 'Password is required.',
            'password.min' => "Password must be at least {$min} characters.",
            'password.letters' => 'Password must include at least one letter.',
            'password.numbers' => 'Password must include at least one number.',
            'password.mixed' => 'Password must include both uppercase and lowercase letters.',
            'password.symbols' => 'Password must include at least one symbol.',
            'password.uncompromised' => 'This password has appeared in a data breach. Please choose a different password.',
            'password.confirmed' => 'Passwords do not match.',
        ];
    }

    /**
     * Short hint text for UI (e.g. under password field).
     */
    public static function hintText(): string
    {
        $min = (int) config('auth.password_min_length', 10);
        $parts = ["At least {$min} characters", 'including a letter and a number'];

        if (config('auth.password_require_mixed_case', false)) {
            $parts[] = 'with both upper and lower case';
        }
        if (config('auth.password_require_symbols', false)) {
            $parts[] = 'and at least one symbol';
        }

        return implode(', ', $parts) . '.';
    }
}
