<?php

namespace App\Http\Requests\Auth;

use Illuminate\Foundation\Http\FormRequest;
use App\Support\PasswordRules;

// ══════════════════════════════════════════════════════════════════
//  InPractice — StoreRegisterRequest
//  Location: app/Http/Requests/Auth/StoreRegisterRequest.php
//
//  Handles ALL validation for the registration form.
//  The controller never sees unvalidated data.
//
//  Security layers validated here:
//    1. Honeypot  — _hp must be empty (bots fill it, humans don't)
//    2. Time guard — _ft must be at least 3 seconds ago (bots are fast)
//    3. Email verification — handled by Laravel after user is created
//
//  Business rules validated here:
//    - nickname must be unique, no spaces, 3–30 chars
//    - at least one hub must be selected
//    - hubs must be valid slugs (finance / marketing / sales)
//    - experience level must be a valid enum value
//    - password minimum 8 chars with letters and numbers
// ══════════════════════════════════════════════════════════════════

class StoreRegisterRequest extends FormRequest
{
    // Anyone can attempt to register
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [

            // ── Security fields ────────────────────────────────

            // Honeypot — must be empty. If a bot fills it, we fail silently.
            '_hp' => ['present', 'max:0'],

            // Time guard — must be a valid timestamp (milliseconds)
            // Minimum 3 seconds must have passed since the form loaded.
            '_ft' => ['required', 'integer', 'min:1'],

            // ── Identity ───────────────────────────────────────
            'name'     => ['required', 'string', 'min:2', 'max:100'],
            'email'    => ['required', 'string', 'email', 'max:255', 'unique:users,email'],

            // Nickname: public display name — unique, no spaces, letters/numbers/underscores only
            'nickname' => [
                'required',
                'string',
                'min:3',
                'max:30',
                'unique:users,nickname',
                'regex:/^[a-zA-Z0-9_\-\.]+$/',
            ],

            // ── Professional info ──────────────────────────────
            'profession'       => ['nullable', 'string', 'max:100'],
            'experience_level' => [
                'required',
                'string',
                'in:student,fresh,junior,mid,senior,senior_10,senior_15',
            ],

            // ── Hub selection ──────────────────────────────────
            // At least one hub required. Each must be a valid slug.
            'hubs'   => ['required', 'array', 'min:1', 'max:3'],
            'hubs.*' => ['string', 'in:finance,marketing,sales'],

            // ── Preferences ───────────────────────────────────
            'language' => ['nullable', 'string', 'in:en,ar'],
            'theme'    => ['nullable', 'string', 'in:navy,dark'],

            // ── Password ───────────────────────────────────────
            'password' => [
                'required',
                'confirmed',
                PasswordRules::defaults(),
            ],
        ];
    }

    // ── Custom validation — runs after rules() pass ────────────────
    public function withValidator($validator): void
    {
        $validator->after(function ($validator) {

            // ── Time guard check ───────────────────────────────
            // _ft is the timestamp (ms) when the form was rendered.
            // We check that at least 3000ms (3 seconds) have passed.
            // Bots submit instantly — real humans always take longer.
            $ft = $this->input('_ft');

            if ($ft && is_numeric($ft)) {
                $elapsedMs = now()->timestamp * 1000 - (int) $ft;

                if ($elapsedMs < 3000) {
                    // Fail silently with a generic error — don't tell bots
                    // what the real check is
                    $validator->errors()->add(
                        'email',
                        __('auth.failed')
                    );
                }
            }
        });
    }

    // ── Custom error messages ──────────────────────────────────────
    public function messages(): array
    {
        return [
            // Honeypot — generic message, never expose what this field is
            '_hp.max' => __('auth.failed'),

            // Nickname
            'nickname.required' => __('validation.required', ['attribute' => 'nickname']),
            'nickname.unique'   => 'This nickname is already taken. Please choose another.',
            'nickname.regex'    => 'Nickname can only contain letters, numbers, underscores, hyphens, and dots.',
            'nickname.min'      => 'Nickname must be at least 3 characters.',
            'nickname.max'      => 'Nickname cannot exceed 30 characters.',

            // Hubs
            'hubs.required' => 'Please select at least one hub to join.',
            'hubs.min'      => 'Please select at least one hub to join.',
            'hubs.*.in'     => 'Invalid hub selected.',

            // Experience
            'experience_level.in' => 'Please select a valid experience level.',

            // Password
            'password.confirmed' => 'The passwords do not match.',
        ];
    }

    // ── Sanitise input before validation ───────────────────────────
    protected function prepareForValidation(): void
    {
        $this->merge([
            // Trim whitespace from text fields
            'name'       => trim($this->name ?? ''),
            'nickname'   => trim($this->nickname ?? ''),
            'email'      => strtolower(trim($this->email ?? '')),
            'profession' => trim($this->profession ?? '') ?: null,

            // Default language and theme if not provided
            'language'   => $this->language ?? 'en',
            'theme'      => $this->theme    ?? 'navy',
        ]);
    }
}
