<?php

namespace App\Http\Requests;

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

/**
 * Form Request for Google Meet Configuration validation
 * 
 * Provides comprehensive validation for OAuth2 credential configuration
 * with XSS prevention and security measures.
 */
class GoogleMeetConfigurationRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize(): bool
    {
        // Only Super Manager can manage configuration
        return auth()->user()->hasRole('Super Manager');
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules(): array
    {
        return [
            'client_id' => [
                'required',
                'string',
                'max:191',
                'regex:/^[0-9]+-[a-zA-Z0-9]+\.apps\.googleusercontent\.com$/',
                function ($attribute, $value, $fail) {
                    // Additional validation for Google Client ID format
                    if (!str_contains($value, '.apps.googleusercontent.com')) {
                        $fail('The :attribute format is invalid. Expected format: xxx-xxx.apps.googleusercontent.com');
                    }
                },
            ],
            'client_secret' => [
                'required',
                'string',
                'max:191',
                'min:20',
                function ($attribute, $value, $fail) {
                    // Client secret should start with GOCSPX-
                    if (!str_starts_with($value, 'GOCSPX-')) {
                        $fail('The :attribute format appears to be invalid.');
                    }
                },
            ],
            'redirect_uri' => [
                'required',
                'url',
                'max:191',
                function ($attribute, $value, $fail) {
                    // Validate redirect URI format
                    $parsed = parse_url($value);
                    if (!isset($parsed['scheme']) || !isset($parsed['host'])) {
                        $fail('The :attribute must be a valid URL.');
                    }
                    
                    // Check if path ends with /callback
                    if (!str_ends_with($parsed['path'] ?? '', '/callback')) {
                        $fail('The :attribute should end with /callback.');
                    }
                },
            ],
        ];
    }

    /**
     * Get custom messages for validator errors.
     *
     * @return array<string, string>
     */
    public function messages(): array
    {
        return [
            'client_id.required' => 'Google Client ID is required.',
            'client_id.regex' => 'Invalid Client ID format. Expected: xxx-xxx.apps.googleusercontent.com',
            'client_id.max' => 'Client ID cannot exceed 191 characters.',
            'client_secret.required' => 'Google Client Secret is required.',
            'client_secret.min' => 'Client Secret appears to be too short.',
            'client_secret.max' => 'Client Secret cannot exceed 191 characters.',
            'redirect_uri.required' => 'Redirect URI is required.',
            'redirect_uri.url' => 'Redirect URI must be a valid URL.',
            'redirect_uri.max' => 'Redirect URI cannot exceed 191 characters.',
        ];
    }

    /**
     * Prepare the data for validation.
     *
     * @return void
     */
    protected function prepareForValidation(): void
    {
        // XSS Prevention - Strip tags from all inputs
        $this->merge([
            'client_id' => strip_tags($this->client_id),
            'client_secret' => strip_tags($this->client_secret),
            'redirect_uri' => strip_tags($this->redirect_uri),
        ]);
    }

    /**
     * Handle a passed validation attempt.
     *
     * @return void
     */
    protected function passedValidation(): void
    {
        // Log configuration save attempt
        \Illuminate\Support\Facades\Log::info('Google Meet configuration validation passed', [
            'user_id' => auth()->id(),
            'client_id_prefix' => substr($this->client_id, 0, 20) . '...',
        ]);
    }
}
