<?php
/**
 * Widget HTML universel — page autonome servie via ?slidemind_widget=1
 *
 * Compatible avec tout editeur e-learning supportant les iframes / web objects.
 *
 * @package SlideMind\Frontend
 * @since 2.7.0
 */

namespace SlideMind\Frontend;

use SlideMind\Core\ConfigRepository;
use SlideMind\Core\LearnerMemory;
use SlideMind\Core\PromptEngine;

if (!defined('ABSPATH')) {
    exit;
}

class ChatWidget {

    /**
     * @var ConfigRepository
     */
    private $config_repository;

    /**
     * @var PromptEngine
     */
    private $prompt_engine;

    /**
     * @var LearnerMemory
     */
    private $learner_memory;

    /**
     * Constructor
     *
     * @param ConfigRepository $config_repository
     * @param PromptEngine     $prompt_engine
     * @param LearnerMemory    $learner_memory
     */
    public function __construct(
        ConfigRepository $config_repository,
        PromptEngine $prompt_engine,
        LearnerMemory $learner_memory
    ) {
        $this->config_repository = $config_repository;
        $this->prompt_engine     = $prompt_engine;
        $this->learner_memory    = $learner_memory;
        add_action('template_redirect', [$this, 'maybe_render']);
    }

    /**
     * Intercepts ?slidemind_widget=1 requests and serves the widget page
     */
    public function maybe_render() {
        // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Public widget URL parameters, no nonce applicable.
        if (!isset($_GET['slidemind_widget'])) {
            return;
        }

        $config_uid  = isset($_GET['config']) ? sanitize_text_field(wp_unslash($_GET['config'])) : '';
        $url_mode    = isset($_GET['mode']) && in_array(sanitize_text_field(wp_unslash($_GET['mode'])), ['chat', 'qa'], true)
                       ? sanitize_text_field(wp_unslash($_GET['mode'])) : '';
        $url_theme   = isset($_GET['theme']) && in_array(sanitize_text_field(wp_unslash($_GET['theme'])), ['light', 'dark'], true)
                       ? sanitize_text_field(wp_unslash($_GET['theme'])) : '';
        $url_color        = isset($_GET['color']) ? sanitize_hex_color(wp_unslash($_GET['color'])) : '';
        $url_ai_color     = isset($_GET['ai_color']) ? sanitize_hex_color(wp_unslash($_GET['ai_color'])) : '';
        $url_ai_text_color = isset($_GET['ai_text_color']) ? sanitize_hex_color(wp_unslash($_GET['ai_text_color'])) : '';
        $url_header       = isset($_GET['header']) ? sanitize_text_field(wp_unslash($_GET['header'])) : '';
        $url_radius       = isset($_GET['radius']) ? sanitize_text_field(wp_unslash($_GET['radius'])) : '';
        $title            = isset($_GET['title']) ? sanitize_text_field(wp_unslash($_GET['title'])) : '';
        $slidemind_user   = isset($_GET['slidemind_user']) ? absint($_GET['slidemind_user']) : 0;
        // phpcs:enable WordPress.Security.NonceVerification.Recommended

        // Validate that the config exists
        if (empty($config_uid)) {
            $this->render_error(__('Missing config parameter.', 'slidemind'));
            return;
        }

        $config = $this->config_repository->get_by_config_uid($config_uid);

        if (!$config) {
            $this->render_error(__('Configuration not found.', 'slidemind'));
            return;
        }

        if ($config['status'] !== 'publish') {
            $this->render_error(__('This configuration is not active.', 'slidemind'));
            return;
        }

        // Resolve appearance: URL param → slide meta → settings default → hardcoded
        $slidemind_settings = get_option('slidemind_settings', []);

        $color         = $url_color    ?: ($config['widget_color'] ?: ($slidemind_settings['widget_color'] ?? '#4f46e5'));
        $ai_color      = $url_ai_color ?: ($config['widget_ai_color'] ?: ($slidemind_settings['widget_ai_color'] ?? '#f1f5f9'));
        $theme         = $url_theme    ?: ($config['widget_theme'] ?: ($slidemind_settings['widget_theme'] ?? 'light'));
        $ai_text_color = $url_ai_text_color ?: ($config['widget_ai_text_color'] ?: ($slidemind_settings['widget_ai_text_color'] ?? ''));
        $border_radius = $url_radius !== '' ? max(0, min(24, (int) $url_radius))
                       : ($config['widget_border_radius'] !== '' ? (int) $config['widget_border_radius']
                       : (int) ($slidemind_settings['widget_border_radius'] ?? 12));
        $show_header   = $url_header !== '' ? ($url_header !== '0')
                       : ($config['widget_show_header'] !== '' ? ($config['widget_show_header'] !== '0')
                       : (($slidemind_settings['widget_show_header'] ?? '1') !== '0'));

        // Mode: config > URL param > default 'qa'
        $config_mode = !empty($config['widget_mode']) ? $config['widget_mode'] : '';
        $mode = $config_mode ?: ($url_mode ?: 'qa');

        // Capture mode: no widget rendering
        if ($mode === 'capture') {
            $this->render_error(__('This slide is configured for data capture only.', 'slidemind'));
            return;
        }

        // Chat mode options
        $max_turns       = isset($config['max_turns']) ? (int) $config['max_turns'] : 0;
        $closing_message = !empty($config['closing_message']) ? $config['closing_message'] : '';
        $graceful_close  = !empty($config['graceful_close']) && $config['graceful_close'] === '1';

        // Opening message: interpolate {{variables}} and strip unresolved placeholders.
        $opening_message_raw = !empty($config['opening_message']) ? $config['opening_message'] : '';
        $opening_message = '';
        if ($mode === 'chat' && $opening_message_raw !== '') {
            $learner_context = [];
            // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Public widget URL parameters, no nonce applicable.
            if ($slidemind_user > 0 || !empty($_GET['session_id'])) {
                try {
                    $scope = $this->resolve_config_scope((int) $config['id']);
                    $session_id_hint = isset($_GET['session_id']) ? sanitize_text_field(wp_unslash($_GET['session_id'])) : '';
                    $learner_context = $this->prompt_engine->resolve_learner_context(
                        $opening_message_raw,
                        (int) $slidemind_user,
                        $scope['module_id'],
                        $scope['course_id'],
                        $this->learner_memory,
                        $slidemind_settings['allowed_profile_fields'] ?? [],
                        $session_id_hint
                    );
                } catch (\Throwable $e) {
                    // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Intentional debug logging.
                    error_log('[SlideMind] Opening message learner context resolution failed: ' . $e->getMessage());
                    $learner_context = [];
                }
            }
            // phpcs:enable WordPress.Security.NonceVerification.Recommended
            $opening_message = $this->prompt_engine->interpolate_display($opening_message_raw, $learner_context);
        }

        // Title: URL &title= -> slide meta widget_title -> config title
        if (empty($title)) {
            $title = !empty($config['widget_title']) ? $config['widget_title'] : ($config['title'] ?: 'SlideMind');
        }

        // Variables for the template
        $rest_url = rest_url('slidemind/v2/');
        $consent_enabled = !empty($slidemind_settings['widget_consent_enabled']);

        // Enqueue widget assets via WordPress API.
        wp_register_style('slidemind-widget', SLIDEMIND_PLUGIN_URL . 'public/widget.css', [], SLIDEMIND_VERSION);
        wp_enqueue_style('slidemind-widget');

        // Dynamic CSS custom properties for theming.
        $inline_css = ':root{' .
            '--sm-primary:' . esc_attr($color) . ';' .
            '--sm-primary-hover:color-mix(in srgb, var(--sm-primary) 85%, black);' .
            '--sm-radius:' . (int) $border_radius . 'px;' .
            '--sm-font:system-ui,-apple-system,\'Segoe UI\',Roboto,sans-serif;';
        if (!empty($ai_color) && $ai_color !== '#f1f5f9') {
            $inline_css .= '--sm-ai-bg-custom:' . esc_attr($ai_color) . ';';
        }
        if (!empty($ai_text_color)) {
            $inline_css .= '--sm-ai-text-custom:' . esc_attr($ai_text_color) . ';';
        }
        $inline_css .= '}';
        wp_add_inline_style('slidemind-widget', $inline_css);

        // Widget JS with configuration data.
        wp_register_script('slidemind-widget', SLIDEMIND_PLUGIN_URL . 'public/widget.js', [], SLIDEMIND_VERSION, true);
        wp_enqueue_script('slidemind-widget');

        $inline_js = 'window.SLIDEMIND_STRINGS=' . wp_json_encode([
            'unknownError'        => __('Unknown error', 'slidemind'),
            'responseParseError'  => __('Error reading the response.', 'slidemind'),
            /* translators: %s: HTTP status code */
            'httpConnectionError' => __('Connection error (HTTP %s).', 'slidemind'),
            'sessionEnded'        => __('Session ended', 'slidemind'),
        ]) . ';' .
        'window.SLIDEMIND_CONFIG=' . wp_json_encode([
            'configId'       => $config_uid,
            'restUrl'        => $rest_url,
            'mode'           => $mode,
            'learnerId'      => $slidemind_user ? (int) $slidemind_user : null,
            'sessionId'      => null,
            'maxTurns'       => (int) $max_turns,
            'closingMessage' => $closing_message,
            'gracefulClose'  => $graceful_close,
            'openingMessage' => $opening_message,
        ]) . ';';
        wp_add_inline_script('slidemind-widget', $inline_js, 'before');

        // Headers
        $this->send_frame_headers();

        // Serve the complete HTML page
        include SLIDEMIND_PLUGIN_PATH . 'templates/widget.php';
        exit;
    }

    /**
     * Sends headers allowing iframe display
     */
    private function send_frame_headers() {
        // Remove restrictive X-Frame-Options
        header_remove('X-Frame-Options');

        // frame-ancestors: respect configured CORS domains, or site_url() by default
        $settings = get_option('slidemind_settings', []);
        $allowed_raw = $settings['cors_allowed_origins'] ?? '';

        if (!empty(trim($allowed_raw))) {
            $domains = array_filter(array_map('trim', explode("\n", $allowed_raw)));
        } else {
            $parsed = wp_parse_url(site_url());
            $default = $parsed['scheme'] . '://' . $parsed['host'];
            if (!empty($parsed['port'])) {
                $default .= ':' . $parsed['port'];
            }
            $domains = [$default];
        }

        header('Content-Security-Policy: frame-ancestors ' . implode(' ', $domains));

        // Anti-cache
        header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
        header('Pragma: no-cache');
    }

    /**
     * Resolve module_id and course_id for a slide.
     *
     * NOTE: Intentional duplication of ChatEndpoint::resolve_config_scope().
     * Keep in sync until a third caller justifies extracting to a shared helper.
     *
     * @param int $post_id
     * @return array ['module_id' => ?int, 'course_id' => ?int]
     */
    private function resolve_config_scope(int $post_id): array {
        $module_id = (int) get_post_meta($post_id, '_slidemind_parent_module_id', true) ?: null;
        if ($module_id && get_post_status($module_id) === false) {
            $module_id = null;
        }
        $course_id = (int) get_post_meta($post_id, '_slidemind_parent_course_id', true) ?: null;
        if (!$course_id && $module_id) {
            $course_id = (int) get_post_meta($module_id, '_slidemind_parent_course_id', true) ?: null;
        }
        if ($course_id && get_post_status($course_id) === false) {
            $course_id = null;
        }
        return ['module_id' => $module_id, 'course_id' => $course_id];
    }

    /**
     * Renders a minimalist error page
     *
     * @param string $message
     */
    private function render_error(string $message) {
        $this->send_frame_headers();
        header('Content-Type: text/html; charset=utf-8');

        wp_register_style('slidemind-widget-error', false, [], SLIDEMIND_VERSION);
        wp_add_inline_style('slidemind-widget-error', 'body{font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;background:#f8fafc;color:#64748b;text-align:center;padding:24px;}');

        echo '<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">';
        wp_print_styles(['slidemind-widget-error']);
        echo '</head><body><div><p style="font-size:48px;margin:0 0 16px;">&#9888;</p><p>' . esc_html($message) . '</p></div></body></html>';
        exit;
    }
}
