<?php

namespace App\Http\Requests;

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

/**
 * EmailConfigurationRequest
 * 
 * Form request for validating email configuration data.
 * Handles both create and update operations.
 * 
 * Security Features:
 * - XSS prevention through string sanitization
 * - Email validation
 * - Port range validation
 * - Encryption type validation
 * 
 * @package App\Http\Requests
 */
class EmailConfigurationRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize(): bool
    {
        // Only Super Manager can manage email configuration
        return auth()->user()->can('manage email configuration');
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array|string>
     */
    public function rules(): array
    {
        return [
            // SMTP Configuration
            'smtp_host' => [
                'required',
                'string',
                'max:191',
                'regex:/^[\w\.\-]+$/',
            ],
            'smtp_port' => [
                'required',
                'integer',
                'min:1',
                'max:65535',
            ],
            'smtp_username' => [
                'nullable',
                'string',
                'max:191',
            ],
            'smtp_password' => [
                'nullable',
                'string',
                'max:191',
            ],
            'smtp_encryption' => [
                'required',
                Rule::in(['tls', 'ssl', 'none']),
            ],

            // IMAP Configuration
            'imap_host' => [
                'nullable',
                'string',
                'max:191',
                'regex:/^[\w\.\-]+$/',
            ],
            'imap_port' => [
                'nullable',
                'integer',
                'min:1',
                'max:65535',
                'required_with:imap_host',
            ],
            'imap_username' => [
                'nullable',
                'string',
                'max:191',
                'required_with:imap_host',
            ],
            'imap_password' => [
                'nullable',
                'string',
                'max:191',
                'required_with:imap_username',
            ],
            'imap_encryption' => [
                'nullable',
                Rule::in(['tls', 'ssl', 'none']),
            ],

            // Sender Information
            'from_address' => [
                'nullable',
                'email',
                'max:191',
            ],
            'from_name' => [
                'nullable',
                'string',
                'max:191',
            ],

            // Status
            'is_active' => [
                'boolean',
            ],
        ];
    }

    /**
     * Get custom messages for validator errors.
     *
     * @return array
     */
    public function messages(): array
    {
        return [
            // SMTP Messages
            'smtp_host.required' => 'The SMTP host is required.',
            'smtp_host.max' => 'The SMTP host cannot exceed 191 characters.',
            'smtp_host.regex' => 'The SMTP host format is invalid.',
            'smtp_port.required' => 'The SMTP port is required.',
            'smtp_port.integer' => 'The SMTP port must be a number.',
            'smtp_port.min' => 'The SMTP port must be at least 1.',
            'smtp_port.max' => 'The SMTP port cannot exceed 65535.',
            'smtp_encryption.required' => 'Please select an encryption type.',
            'smtp_encryption.in' => 'Invalid encryption type selected.',

            // IMAP Messages
            'imap_host.max' => 'The IMAP host cannot exceed 191 characters.',
            'imap_host.regex' => 'The IMAP host format is invalid.',
            'imap_port.integer' => 'The IMAP port must be a number.',
            'imap_port.min' => 'The IMAP port must be at least 1.',
            'imap_port.max' => 'The IMAP port cannot exceed 65535.',
            'imap_port.required_with' => 'The IMAP port is required when IMAP host is provided.',
            'imap_username.required_with' => 'IMAP username is required when IMAP host is provided.',
            'imap_password.required_with' => 'IMAP password is required when IMAP username is provided.',
            'imap_encryption.in' => 'Invalid IMAP encryption type selected.',

            // Sender Messages
            'from_address.email' => 'Please enter a valid email address.',
            'from_address.max' => 'The from address cannot exceed 191 characters.',
            'from_name.max' => 'The from name cannot exceed 191 characters.',

            // Status
            'is_active.boolean' => 'The active status must be true or false.',
        ];
    }

    /**
     * Prepare the data for validation.
     *
     * @return void
     */
    protected function prepareForValidation(): void
    {
        // Trim whitespace from string fields
        $this->merge([
            'smtp_host' => trim($this->smtp_host ?? ''),
            'smtp_username' => trim($this->smtp_username ?? ''),
            'imap_host' => trim($this->imap_host ?? ''),
            'imap_username' => trim($this->imap_username ?? ''),
            'from_address' => trim($this->from_address ?? ''),
            'from_name' => trim($this->from_name ?? ''),
        ]);

        // Set is_active default
        if (!$this->has('is_active')) {
            $this->merge(['is_active' => true]);
        }
    }

    /**
     * Handle a passed validation attempt.
     *
     * @return void
     */
    protected function passedValidation(): void
    {
        // XSS Prevention: Sanitize string fields
        $this->sanitizeInput();
    }

    /**
     * Sanitize input data for XSS prevention.
     *
     * @return void
     */
    protected function sanitizeInput(): void
    {
        $sanitized = [];

        // Fields that need XSS sanitization
        $textFields = ['from_name'];

        foreach ($textFields as $field) {
            if ($this->has($field)) {
                $sanitized[$field] = strip_tags($this->$field);
            }
        }

        // Don't sanitize passwords - they may contain special characters
        // Don't sanitize usernames - they're encrypted anyway
        // Don't sanitize hosts - validated by regex

        if (!empty($sanitized)) {
            $this->merge($sanitized);
        }
    }

    /**
     * Get validated data with additional processing.
     *
     * @return array
     */
    public function getValidatedData(): array
    {
        $data = $this->validated();

        // Ensure IMAP fields are null if IMAP is not configured
        if (empty($data['imap_host'])) {
            $data['imap_host'] = null;
            $data['imap_port'] = null;
            $data['imap_username'] = null;
            $data['imap_password'] = null;
            $data['imap_encryption'] = null;
        }

        return $data;
    }
}
