<?php

namespace App\Http\Requests;

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

/**
 * SmsConfigurationRequest
 * 
 * Form validation request for SMS configuration data.
 * Validates all input before it reaches the controller.
 * 
 * Security Features:
 * - Validates API key format
 * - Validates sender ID format (alphanumeric only)
 * - Sanitizes input to prevent XSS attacks
 * 
 * @package App\Http\Requests
 */
class SmsConfigurationRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     * 
     * Only Super Managers can manage SMS configuration.
     *
     * @return bool
     */
    public function authorize(): bool
    {
        // Check if user has the manage sms configuration permission
        return auth()->check() && auth()->user()->can('manage sms configuration');
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'api_key' => [
                'required',
                'string',
                'min:10',
                'max:500',
            ],
            'username' => [
                'required',
                'string',
                'min:3',
                'max:191',
            ],
            'sender_id' => [
                'required',
                'string',
                'min:3',
                'max:11',
                'regex:/^[a-zA-Z0-9]+$/',
            ],
            'environment' => [
                'required',
                Rule::in(['sandbox', 'production']),
            ],
            'is_active' => [
                'nullable',
                'boolean',
            ],
        ];
    }

    /**
     * Get custom messages for validator errors.
     *
     * @return array<string, string>
     */
    public function messages(): array
    {
        return [
            'api_key.required' => 'The API key is required.',
            'api_key.min' => 'The API key must be at least 10 characters.',
            'api_key.max' => 'The API key cannot exceed 500 characters.',
            
            'username.required' => 'The username is required.',
            'username.min' => 'The username must be at least 3 characters.',
            'username.max' => 'The username cannot exceed 191 characters.',
            
            'sender_id.required' => 'The sender ID is required.',
            'sender_id.min' => 'The sender ID must be at least 3 characters.',
            'sender_id.max' => 'The sender ID cannot exceed 11 characters.',
            'sender_id.regex' => 'The sender ID must contain only alphanumeric characters (letters and numbers).',
            
            'environment.required' => 'Please select an environment.',
            'environment.in' => 'The environment must be either sandbox or production.',
            
            'is_active.boolean' => 'The active status must be true or false.',
        ];
    }

    /**
     * Get custom attributes for validator errors.
     *
     * @return array<string, string>
     */
    public function attributes(): array
    {
        return [
            'api_key' => 'API key',
            'username' => 'username',
            'sender_id' => 'sender ID',
            'environment' => 'environment',
            'is_active' => 'active status',
        ];
    }

    /**
     * Prepare the data for validation.
     * 
     * Sanitizes input before validation.
     *
     * @return void
     */
    protected function prepareForValidation(): void
    {
        // Trim whitespace from string inputs
        $this->merge([
            'api_key' => trim($this->api_key ?? ''),
            'username' => trim($this->username ?? ''),
            'sender_id' => strtoupper(trim($this->sender_id ?? '')),
        ]);
    }

    /**
     * Handle a passed validation attempt.
     *
     * @return void
     */
    protected function passedValidation(): void
    {
        // Set default value for is_active if not provided
        if (!$this->has('is_active')) {
            $this->merge(['is_active' => true]);
        }
    }

    /**
     * Get the validated data with any additional processing.
     *
     * @return array
     */
    public function validated($key = null, $default = null): array
    {
        $validated = parent::validated($key, $default);
        
        // Ensure is_active is a boolean
        $validated['is_active'] = (bool) ($validated['is_active'] ?? true);
        
        return $validated;
    }
}
