<?php
declare(strict_types=1);

namespace ROITheme\Public\ContactForm\Infrastructure\Api\WordPress;

use ROITheme\Shared\Domain\Contracts\ComponentSettingsRepositoryInterface;

/**
 * ContactFormAjaxHandler - Procesa envios del formulario de contacto
 *
 * RESPONSABILIDAD: Recibir datos del formulario y enviarlos al webhook configurado
 *
 * SEGURIDAD:
 * - Verifica nonce
 * - Webhook URL NUNCA se expone al cliente
 * - Webhook URL se obtiene de BD server-side
 * - Rate limiting basico
 * - Sanitizacion de inputs
 *
 * @package ROITheme\Public\ContactForm\Infrastructure\Api\WordPress
 */
final class ContactFormAjaxHandler
{
    private const NONCE_ACTION = 'roi_contact_form_nonce';
    private const COMPONENT_NAME = 'contact-form';

    public function __construct(
        private ComponentSettingsRepositoryInterface $settingsRepository
    ) {}

    /**
     * Registrar hooks AJAX
     * Usa wp_ajax_nopriv para usuarios no logueados
     */
    public function register(): void
    {
        add_action('wp_ajax_roi_contact_form_submit', [$this, 'handleSubmit']);
        add_action('wp_ajax_nopriv_roi_contact_form_submit', [$this, 'handleSubmit']);
    }

    /**
     * Procesar envio del formulario
     */
    public function handleSubmit(): void
    {
        // 1. Verificar nonce
        $nonce = sanitize_text_field($_POST['nonce'] ?? '');
        if (!wp_verify_nonce($nonce, self::NONCE_ACTION)) {
            wp_send_json_error([
                'message' => __('Error de seguridad. Por favor recarga la pagina.', 'roi-theme')
            ], 403);
            return;
        }

        // 2. Rate limiting basico (1 envio por IP cada 30 segundos)
        if (!$this->checkRateLimit()) {
            wp_send_json_error([
                'message' => __('Por favor espera un momento antes de enviar otro mensaje.', 'roi-theme')
            ], 429);
            return;
        }

        // 3. Sanitizar y validar inputs
        $formData = $this->sanitizeFormData($_POST);
        $validation = $this->validateFormData($formData);

        if (!$validation['valid']) {
            wp_send_json_error([
                'message' => $validation['message'],
                'errors' => $validation['errors']
            ], 422);
            return;
        }

        // 4. Obtener configuracion del componente (incluye webhook URL)
        $settings = $this->settingsRepository->getComponentSettings(self::COMPONENT_NAME);

        if (empty($settings)) {
            wp_send_json_error([
                'message' => __('Error de configuracion. Contacta al administrador.', 'roi-theme')
            ], 500);
            return;
        }

        $integration = $settings['integration'] ?? [];
        $webhookUrl = $integration['webhook_url'] ?? '';
        $webhookMethod = $integration['webhook_method'] ?? 'POST';
        $includePageUrl = $this->toBool($integration['include_page_url'] ?? true);
        $includeTimestamp = $this->toBool($integration['include_timestamp'] ?? true);

        if (empty($webhookUrl)) {
            // Si no hay webhook configurado, simular exito para UX
            // pero loguear warning para admin
            error_log('ROI Theme Contact Form: No webhook URL configured');
            wp_send_json_success([
                'message' => $this->getSuccessMessage($settings)
            ]);
            return;
        }

        // 5. Preparar payload para webhook
        $payload = $this->preparePayload($formData, $includePageUrl, $includeTimestamp);

        // 6. Enviar a webhook
        $result = $this->sendToWebhook($webhookUrl, $webhookMethod, $payload);

        if ($result['success']) {
            wp_send_json_success([
                'message' => $this->getSuccessMessage($settings)
            ]);
        } else {
            error_log('ROI Theme Contact Form webhook error: ' . $result['error']);
            wp_send_json_error([
                'message' => $this->getErrorMessage($settings)
            ], 500);
        }
    }

    /**
     * Sanitizar datos del formulario
     */
    private function sanitizeFormData(array $post): array
    {
        return [
            'fullName' => sanitize_text_field($post['fullName'] ?? ''),
            'company' => sanitize_text_field($post['company'] ?? ''),
            'whatsapp' => sanitize_text_field($post['whatsapp'] ?? ''),
            'email' => sanitize_email($post['email'] ?? ''),
            'message' => sanitize_textarea_field($post['message'] ?? ''),
        ];
    }

    /**
     * Validar datos del formulario
     */
    private function validateFormData(array $data): array
    {
        $errors = [];

        // Nombre requerido
        if (empty($data['fullName'])) {
            $errors['fullName'] = __('El nombre es obligatorio', 'roi-theme');
        }

        // WhatsApp requerido
        if (empty($data['whatsapp'])) {
            $errors['whatsapp'] = __('El WhatsApp es obligatorio', 'roi-theme');
        }

        // Email requerido y valido
        if (empty($data['email'])) {
            $errors['email'] = __('El email es obligatorio', 'roi-theme');
        } elseif (!is_email($data['email'])) {
            $errors['email'] = __('Por favor ingresa un email valido', 'roi-theme');
        }

        if (!empty($errors)) {
            return [
                'valid' => false,
                'message' => __('Por favor corrige los errores del formulario', 'roi-theme'),
                'errors' => $errors
            ];
        }

        return ['valid' => true, 'message' => '', 'errors' => []];
    }

    /**
     * Preparar payload para webhook
     */
    private function preparePayload(array $formData, bool $includePageUrl, bool $includeTimestamp): array
    {
        $payload = [
            'fullName' => $formData['fullName'],
            'company' => $formData['company'],
            'whatsapp' => $formData['whatsapp'],
            'email' => $formData['email'],
            'message' => $formData['message'],
        ];

        if ($includePageUrl) {
            $payload['pageUrl'] = sanitize_url($_POST['pageUrl'] ?? '');
            $payload['pageTitle'] = sanitize_text_field($_POST['pageTitle'] ?? '');
        }

        if ($includeTimestamp) {
            $payload['timestamp'] = current_time('c');
            $payload['timezone'] = wp_timezone_string();
        }

        // Metadata adicional util para el webhook
        $payload['source'] = 'contact-form';
        $payload['siteName'] = get_bloginfo('name');
        $payload['siteUrl'] = home_url();

        return $payload;
    }

    /**
     * Enviar datos al webhook
     */
    private function sendToWebhook(string $url, string $method, array $payload): array
    {
        $args = [
            'method' => strtoupper($method),
            'timeout' => 30,
            'redirection' => 5,
            'httpversion' => '1.1',
            'headers' => [
                'Content-Type' => 'application/json',
                'Accept' => 'application/json',
            ],
        ];

        if ($method === 'POST') {
            $args['body'] = wp_json_encode($payload);
        } else {
            $url = add_query_arg($payload, $url);
        }

        $response = wp_remote_request($url, $args);

        if (is_wp_error($response)) {
            return [
                'success' => false,
                'error' => $response->get_error_message()
            ];
        }

        $statusCode = wp_remote_retrieve_response_code($response);

        // Considerar 2xx como exito
        if ($statusCode >= 200 && $statusCode < 300) {
            return ['success' => true, 'error' => ''];
        }

        return [
            'success' => false,
            'error' => sprintf('HTTP %d: %s', $statusCode, wp_remote_retrieve_response_message($response))
        ];
    }

    /**
     * Rate limiting basico por IP
     */
    private function checkRateLimit(): bool
    {
        $ip = $this->getClientIP();
        $transientKey = 'roi_contact_form_' . md5($ip);
        $lastSubmit = get_transient($transientKey);

        if ($lastSubmit !== false) {
            return false;
        }

        set_transient($transientKey, time(), 30);
        return true;
    }

    /**
     * Obtener IP del cliente
     */
    private function getClientIP(): string
    {
        $ip = '';

        if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = sanitize_text_field($_SERVER['HTTP_CLIENT_IP']);
        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ip = sanitize_text_field(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]);
        } elseif (!empty($_SERVER['REMOTE_ADDR'])) {
            $ip = sanitize_text_field($_SERVER['REMOTE_ADDR']);
        }

        return $ip;
    }

    /**
     * Obtener mensaje de exito desde configuracion
     */
    private function getSuccessMessage(array $data): string
    {
        $messages = $data['messages'] ?? [];
        return $messages['success_message'] ?? __('¡Gracias por contactarnos! Te responderemos pronto.', 'roi-theme');
    }

    /**
     * Obtener mensaje de error desde configuracion
     */
    private function getErrorMessage(array $data): string
    {
        $messages = $data['messages'] ?? [];
        return $messages['error_message'] ?? __('Hubo un error al enviar el mensaje. Por favor intenta de nuevo.', 'roi-theme');
    }

    /**
     * Convertir valor a boolean
     */
    private function toBool($value): bool
    {
        return $value === true || $value === '1' || $value === 1;
    }
}
