<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class SubmitEmployeeRegistrationRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true; // Public endpoint, no auth required
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            // Company resolved from invite token (generated by admin per company)
            'token' => [
                'required',
                'string',
                'size:64',
                function ($attribute, $value, $fail) {
                    $company = \App\Models\Company::where('registration_token', $value)->first();
                    if (! $company) {
                        $fail('Invalid registration link. Please contact your company administrator.');
                    } elseif ($company->status !== 'active') {
                        $fail('This company is not currently accepting registrations.');
                    }
                },
            ],

            // BIO-DATA INFORMATION
            'title' => ['nullable', 'string', 'max:20'],
            'first_name' => ['required', 'string', 'max:100'],
            'last_name' => ['required', 'string', 'max:100'],
            'middle_name' => ['nullable', 'string', 'max:100'],
            'gender' => ['nullable', 'string', Rule::in(['Male', 'Female', 'Other'])],
            'date_of_birth' => ['required', 'date', 'before:today'],
            'nationality' => ['required', 'string', 'max:100'],
            'phone_number' => ['required', 'string', 'max:20'],
            'confirm_phone_number' => ['required', 'string', 'same:phone_number'],
            'foreign_number' => ['nullable', 'string', 'max:20'],
            'email_address' => [
                'required',
                'string',
                'email',
                'max:255',
                function ($attribute, $value, $fail) {
                    // Check if email already exists
                    $emailExists = \DB::table('companies')->where('email', $value)->exists()
                        || \DB::table('portal_users')->where('email', $value)->exists()
                        || \DB::table('company_employees')->where('email', $value)->exists();

                    if ($emailExists) {
                        $fail('This email already has an account. Please reach out to the admin for assistance.');
                    }
                },
            ],
            'confirm_email_address' => ['required', 'string', 'email', 'same:email_address'],
            'country' => ['required', 'string', 'max:100'],
            'state' => ['required', 'string', 'max:100'],
            'city' => ['required', 'string', 'max:100'],
            'chn' => ['nullable', 'string', 'max:50'],
            'house_address' => ['required', 'string'],
            'previous_address' => ['nullable', 'string'],

            // BANK INFORMATION
            // RSA-OAEP encrypted BVN (encrypted with server public key)
            'encrypted_bvn' => ['required', 'string'],
            'bank_name' => ['nullable', 'string', 'max:100'],
            'bank_account_number' => ['nullable', 'string', 'max:20'],
            'tin_or_pin' => ['nullable', 'string', 'max:50'],
            'bank_details_consent' => ['nullable', 'boolean'],

            // IDENTITY INFORMATION
            'identity_card_type' => [
                'required',
                'string',
                Rule::in([
                    'National Identity Number',
                    'National ID',
                    'International Passport',
                    'Driver\'s License',
                    'Voter\'s Card',
                    'Permanent Voter\'s Card',
                ]),
            ],
            // For non-NIN identity cards (plain text)
            'identity_card_number' => [
                'required_unless:identity_card_type,National Identity Number',
                'nullable',
                'string',
                'max:50',
            ],
            // RSA-OAEP encrypted NIN — required if identity_card_type is NIN, otherwise optional (can be submitted later)
            'encrypted_nin' => [
                'required_if:identity_card_type,National Identity Number',
                'nullable',
                'string',
                'min:300',
                'max:400',
                'regex:/^[A-Za-z0-9+\/]*={0,2}$/',
            ],

            // Beneficiaries — optional at registration, can be submitted later via submission link
            'beneficiaries' => ['nullable', 'array', 'min:1'],
            'beneficiaries.*.first_name' => ['required_with:beneficiaries', 'string', 'max:100'],
            'beneficiaries.*.last_name' => ['required_with:beneficiaries', 'string', 'max:100'],
            'beneficiaries.*.date_of_birth' => ['required_with:beneficiaries', 'date', 'before:today'],
            'beneficiaries.*.address' => ['required_with:beneficiaries', 'string', 'max:255'],
            'beneficiaries.*.percentage_allocation' => ['required_with:beneficiaries', 'numeric', 'min:1', 'max:100'],

            // File uploads
            'identity_card' => [
                'required',
                'file',
                'mimes:pdf,jpg,jpeg,png',
                'max:5120', // 5MB
            ],
            'scanned_signature' => [
                'required',
                'file',
                'mimes:pdf,jpg,jpeg,png',
                'max:5120',
            ],
            'passport_photograph' => [
                'required',
                'file',
                'mimes:jpg,jpeg,png',
                'max:5120',
            ],
            'nin_document' => [ // NEW: NIN document upload
                'required_if:identity_card_type,National Identity Number',
                'nullable',
                'file',
                'mimes:pdf,jpg,jpeg,png',
                'max:5120',
            ],

            // Consent
            'consent_checkbox' => ['required', 'accepted'],
        ];
    }

    /**
     * Get custom messages for validator errors.
     *
     * @return array<string, string>
     */
    public function withValidator($validator): void
    {
        $validator->after(function ($validator) {
            $beneficiaries = $this->input('beneficiaries');
            if (! empty($beneficiaries) && is_array($beneficiaries)) {
                $total = collect($beneficiaries)->sum('percentage_allocation');
                if (round($total, 2) !== 100.00) {
                    $validator->errors()->add(
                        'beneficiaries',
                        'Total beneficiary percentage allocation must equal 100%. Current total: ' . $total . '%.'
                    );
                }
            }
        });
    }

    public function messages(): array
    {
        return [
            'token.required' => 'A registration link token is required.',
            'token.size' => 'Invalid registration link.',
            'first_name.required' => 'First name is required.',
            'last_name.required' => 'Last name is required.',
            'date_of_birth.required' => 'Date of birth is required.',
            'date_of_birth.before' => 'Date of birth must be before today.',
            'nationality.required' => 'Nationality is required.',
            'phone_number.required' => 'Phone number is required.',
            'confirm_phone_number.required' => 'Please confirm your phone number.',
            'confirm_phone_number.same' => 'Phone numbers do not match.',
            'email_address.required' => 'Email address is required.',
            'email_address.email' => 'Please provide a valid email address.',
            'confirm_email_address.required' => 'Please confirm your email address.',
            'confirm_email_address.same' => 'Email addresses do not match.',
            'country.required' => 'Country is required.',
            'state.required' => 'State is required.',
            'city.required' => 'City is required.',
            'house_address.required' => 'House address is required.',
            'encrypted_bvn.required' => 'Encrypted BVN is required.',
            'identity_card_type.required' => 'Identity card type is required.',
            'identity_card_type.in' => 'Invalid identity card type selected.',
            'identity_card_number.required_unless' => 'Identity card number is required.',
            'encrypted_nin.required_if' => 'Encrypted NIN is required for NIN identity card type.',
            'encrypted_nin.min' => 'Invalid encrypted NIN format.',
            'encrypted_nin.max' => 'Invalid encrypted NIN format.',
            'encrypted_nin.regex' => 'Invalid encrypted NIN format.',
            'beneficiaries.min' => 'At least one beneficiary is required if submitting beneficiaries.',
            'beneficiaries.*.first_name.required_with' => 'Beneficiary first name is required.',
            'beneficiaries.*.last_name.required_with' => 'Beneficiary last name is required.',
            'beneficiaries.*.date_of_birth.required_with' => 'Beneficiary date of birth is required.',
            'beneficiaries.*.date_of_birth.before' => 'Beneficiary date of birth must be in the past.',
            'beneficiaries.*.address.required_with' => 'Beneficiary address is required.',
            'beneficiaries.*.percentage_allocation.required_with' => 'Beneficiary percentage allocation is required.',
            'beneficiaries.*.percentage_allocation.min' => 'Percentage allocation must be at least 1.',
            'beneficiaries.*.percentage_allocation.max' => 'Percentage allocation cannot exceed 100.',
            'identity_card.required' => 'Identity card document is required.',
            'identity_card.file' => 'Identity card must be a file.',
            'identity_card.mimes' => 'Identity card must be a PDF, JPG, JPEG, or PNG file.',
            'identity_card.max' => 'Identity card file size must not exceed 5MB.',
            'scanned_signature.required' => 'Scanned signature is required.',
            'scanned_signature.mimes' => 'Scanned signature must be a PDF, JPG, JPEG, or PNG file.',
            'scanned_signature.max' => 'Scanned signature file size must not exceed 5MB.',
            'passport_photograph.required' => 'Passport photograph is required.',
            'passport_photograph.mimes' => 'Passport photograph must be a JPG, JPEG, or PNG file.',
            'passport_photograph.max' => 'Passport photograph file size must not exceed 5MB.',
            'nin_document.required_if' => 'NIN document is required when identity card type is National Identity Number.',
            'nin_document.mimes' => 'NIN document must be a PDF, JPG, JPEG, or PNG file.',
            'nin_document.max' => 'NIN document file size must not exceed 5MB.',
            'consent_checkbox.required' => 'You must agree to the terms and conditions.',
            'consent_checkbox.accepted' => 'You must agree to the terms and conditions.',
        ];
    }
}
