<?php
/**
 * Opening Screen Widget for BoostBot
 *
 * Displays configurable opening screen with 4 different modes.
 *
 * @package BoostBot
 * @since 1.0.0
 */

// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Class BoostBot_Opening_Screen_Widget
 *
 * Widget for customizable chat opening screens.
 * 
 * Modes:
 * 1. questions_ai - User-defined questions, AI answers
 * 2. questions_answers - User-defined Q&A pairs
 * 3. departments - Display departments and contacts
 */
class BoostBot_Opening_Screen_Widget extends BoostBot_Widget_Base {

    /**
     * Widget unique identifier.
     *
     * @var string
     */
    protected $id = 'opening_screen';

    /**
     * Whether widget is available in free version.
     *
     * @var bool
     */
    protected $is_free = false;

    /**
     * Mode constants.
     */
    const MODE_QUESTIONS_AI = 'questions_ai';
    const MODE_QUESTIONS_ANSWERS = 'questions_answers';
    const MODE_DEPARTMENTS = 'departments';

    /**
     * Get the widget name.
     *
     * @since 1.0.0
     * @return string Widget name.
     */
    public function get_name(): string {
        return __( 'Opening Screen', 'boostbot' );
    }

    /**
     * Get the widget description.
     *
     * @since 1.0.0
     * @return string Widget description.
     */
    public function get_description(): string {
        return __( 'Configure what is shown to customers when opening the chat', 'boostbot' );
    }

    /**
     * Get widget icon.
     *
     * @since 1.0.0
     * @return string Icon name (Lucide icon).
     */
    public function get_icon(): string {
        return 'layout-template';
    }

    /**
     * Get the widget schema (fields definition).
     *
     * @since 1.0.0
     * @return array Widget schema.
     */
    public function get_schema(): array {
        return array(
            'name'        => $this->get_name(),
            'description' => $this->get_description(),
            'singular'    => true, // Only one per bot

            'modes' => array(
                self::MODE_QUESTIONS_AI => array(
                    'name'        => __( 'Questions + AI Answers', 'boostbot' ),
                    'description' => __( 'Define questions that appear as buttons, AI answers them', 'boostbot' ),
                ),
                self::MODE_QUESTIONS_ANSWERS => array(
                    'name'        => __( 'Questions + Defined Answers', 'boostbot' ),
                    'description' => __( 'Define questions and pre-made answers', 'boostbot' ),
                ),
                self::MODE_DEPARTMENTS => array(
                    'name'        => __( 'Departments and Contacts', 'boostbot' ),
                    'description' => __( 'Display organization departments and contacts', 'boostbot' ),
                ),
            ),

            'settings' => array(
                'mode'         => self::MODE_QUESTIONS_AI,
                'welcome_text' => __( 'Hello! How can I help you?', 'boostbot' ),
                'show_welcome' => true,

                // Mode 1: Questions AI.
                'questions'       => array(),
                'ai_instructions' => '', // How AI should answer.

                // Mode 2: Questions & Answers.
                'qa_pairs' => array(),

                // Mode 3: Departments.
                'contact_list_id'    => null,
                'show_departments'   => true,
                'show_contact_cards' => true,

                // Mode 4: Custom Prompt.
                'custom_prompt'   => '',
                'attached_files'  => array(), // [{ id, name, type, url, path }].
            ),
        );
    }

    /**
     * Validate submitted data.
     *
     * @since 1.0.0
     * @param array $data Submitted data.
     * @return array Validation result with 'valid' and 'errors' keys.
     */
    public function validate( array $data ): array {
        $errors = array();

        // Validate mode.
        $valid_modes = array(
            self::MODE_QUESTIONS_AI,
            self::MODE_QUESTIONS_ANSWERS,
            self::MODE_DEPARTMENTS,
        );

        if ( isset( $data['mode'] ) && ! in_array( $data['mode'], $valid_modes, true ) ) {
            $errors['mode'] = __( 'Invalid mode', 'boostbot' );
        }

        return array(
            'valid'  => empty( $errors ),
            'errors' => $errors,
        );
    }

    /**
     * Process submitted data.
     *
     * @since 1.0.0
     * @param array $data    Submitted data.
     * @param array $context Submission context.
     * @return array Processing result.
     */
    public function process( array $data, array $context = array() ): array {
        // Opening screen doesn't process form submissions.
        // It only provides display data and handles clicks.
        return array(
            'success' => true,
            'message' => __( 'Opening screen configured successfully', 'boostbot' ),
        );
    }

    /**
     * Get opening screen data for chat.
     *
     * @since 1.0.0
     * @param int $widget_id The widget ID (or bot_id for getting settings).
     * @return array Opening screen data.
     */
    public function get_opening_data( int $widget_id ): array {
        $widget   = $this->get_widget_data( $widget_id );
        $settings = $widget['settings'] ?? array();
        $mode     = $settings['mode'] ?? self::MODE_QUESTIONS_AI;

        $data = array(
            'mode'         => $mode,
            'welcome_text' => ! empty( $settings['show_welcome'] ) ? ( $settings['welcome_text'] ?? '' ) : null,
        );

        switch ( $mode ) {
            case self::MODE_QUESTIONS_AI:
                $data['questions']       = $this->format_questions( $settings['questions'] ?? array() );
                $data['ai_instructions'] = $settings['ai_instructions'] ?? '';
                break;

            case self::MODE_QUESTIONS_ANSWERS:
                $data['qa_pairs'] = $this->format_qa_pairs( $settings['qa_pairs'] ?? array() );
                break;

            case self::MODE_DEPARTMENTS:
                $data['departments'] = $this->get_departments_data( $settings );
                break;
        }

        return $data;
    }

    /**
     * Get widget data from database.
     *
     * @since 1.0.0
     * @param int $widget_id Widget ID.
     * @return array Widget data.
     */
    protected function get_widget_data( int $widget_id ): array {
        global $wpdb;

        $table = self::sanitize_identifier( $wpdb->prefix . 'boostbot_widgets' );

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table identifier sanitized via sanitize_identifier(); values bind via prepare().
        $widget = $wpdb->get_row(
            // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
            $wpdb->prepare(
                "SELECT * FROM {$table} WHERE id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                $widget_id
            ),
            ARRAY_A
        );

        if ( ! $widget ) {
            return array( 'settings' => $this->get_schema()['settings'] );
        }

        // Config can be in 'config' or 'settings' field depending on DB schema
        $config_json = ! empty( $widget['config'] ) ? $widget['config'] : ( $widget['settings'] ?? '' );
        $settings = ! empty( $config_json ) ? json_decode( $config_json, true ) : array();

        return array(
            'id'       => $widget['id'],
            'settings' => array_merge( $this->get_schema()['settings'], $settings ),
        );
    }

    /**
     * Format questions for display.
     *
     * @since 1.0.0
     * @param array $questions Raw questions array.
     * @return array Formatted questions.
     */
    private function format_questions( array $questions ): array {
        return array_map(
            function ( $q, $idx ) {
                return array(
                    'id'   => $idx,
                    'text' => is_array( $q ) ? ( $q['text'] ?? '' ) : $q,
                    'icon' => is_array( $q ) ? ( $q['icon'] ?? null ) : null,
                );
            },
            $questions,
            array_keys( $questions )
        );
    }

    /**
     * Format Q&A pairs for display.
     *
     * @since 1.0.0
     * @param array $pairs Raw Q&A pairs.
     * @return array Formatted pairs.
     */
    private function format_qa_pairs( array $pairs ): array {
        return array_map(
            function ( $pair, $idx ) {
                return array(
                    'id'       => $idx,
                    'question' => $pair['question'] ?? '',
                    'answer'   => $pair['answer'] ?? '',
                    'icon'     => $pair['icon'] ?? null,
                );
            },
            $pairs,
            array_keys( $pairs )
        );
    }

    /**
     * Get departments and contacts data.
     *
     * @since 1.0.0
     * @param array $settings Widget settings.
     * @return array Departments data.
     */
    private function get_departments_data( array $settings ): array {
        $contact_list_id = $settings['contact_list_id'] ?? null;

        if ( ! $contact_list_id ) {
            // Get primary contact list.
            $list_model = new BoostBot_Contact_List_Model();
            $primary    = $list_model->get_primary();
            $contact_list_id = $primary ? $primary->id : null;
        }

        if ( ! $contact_list_id ) {
            return array();
        }

        $contact_model = new BoostBot_Contact_Model();
        $contacts      = $contact_model->get_by_list( $contact_list_id );

        // Group by department.
        $departments = array();
        foreach ( $contacts as $contact ) {
            $dept = $contact->department ?? __( 'General', 'boostbot' );

            if ( ! isset( $departments[ $dept ] ) ) {
                $departments[ $dept ] = array(
                    'name'     => $dept,
                    'contacts' => array(),
                );
            }

            $departments[ $dept ]['contacts'][] = array(
                'id'    => $contact->id,
                'name'  => $contact->name,
                'role'  => $contact->title ?? '',
                'email' => $contact->email ?? '',
                'phone' => $contact->phone ?? '',
                'image' => '', // Image URL if available.
            );
        }

        return array_values( $departments );
    }

    /**
     * Handle question click (Mode 1).
     *
     * @since 1.0.0
     * @param int   $widget_id    Widget ID.
     * @param int   $question_idx Question index.
     * @param array $context      Context data.
     * @return array Response data.
     */
    public function handle_question_click( int $widget_id, int $question_idx, array $context = array() ): array {
        $widget    = $this->get_widget_data( $widget_id );
        $settings  = $widget['settings'] ?? array();
        $questions = $settings['questions'] ?? array();

        if ( ! isset( $questions[ $question_idx ] ) ) {
            return array(
                'success' => false,
                'error'   => __( 'Question not found', 'boostbot' ),
            );
        }

        $question = is_array( $questions[ $question_idx ] )
            ? ( $questions[ $question_idx ]['text'] ?? '' )
            : $questions[ $question_idx ];

        // Add AI instructions if provided.
        $ai_instructions = $settings['ai_instructions'] ?? '';

        return array(
            'success'        => true,
            'action'         => 'send_to_ai',
            'message'        => $question,
            'system_context' => $ai_instructions,
        );
    }

    /**
     * Handle Q&A click (Mode 2).
     *
     * @since 1.0.0
     * @param int $widget_id Widget ID.
     * @param int $qa_idx    Q&A index.
     * @return array Response data.
     */
    public function handle_qa_click( int $widget_id, int $qa_idx ): array {
        $widget   = $this->get_widget_data( $widget_id );
        $settings = $widget['settings'] ?? array();
        $qa_pairs = $settings['qa_pairs'] ?? array();

        if ( ! isset( $qa_pairs[ $qa_idx ] ) ) {
            return array(
                'success' => false,
                'error'   => __( 'Question and answer not found', 'boostbot' ),
            );
        }

        return array(
            'success'  => true,
            'action'   => 'show_answer',
            'question' => $qa_pairs[ $qa_idx ]['question'] ?? '',
            'answer'   => $qa_pairs[ $qa_idx ]['answer'] ?? '',
        );
    }

    /**
     * Get available modes for UI.
     *
     * @since 1.0.0
     * @return array Modes with metadata.
     */
    public static function get_modes(): array {
        return array(
            self::MODE_QUESTIONS_AI => array(
                'id'          => self::MODE_QUESTIONS_AI,
                'name'        => __( 'Questions + AI Answers', 'boostbot' ),
                'description' => __( 'Define questions that appear as buttons, AI answers them', 'boostbot' ),
                'icon'        => 'sparkles',
            ),
            self::MODE_QUESTIONS_ANSWERS => array(
                'id'          => self::MODE_QUESTIONS_ANSWERS,
                'name'        => __( 'Questions + Defined Answers', 'boostbot' ),
                'description' => __( 'Define questions and pre-made answers', 'boostbot' ),
                'icon'        => 'list-checks',
            ),
            self::MODE_DEPARTMENTS => array(
                'id'          => self::MODE_DEPARTMENTS,
                'name'        => __( 'Departments and Contacts', 'boostbot' ),
                'description' => __( 'Display organization departments and contacts', 'boostbot' ),
                'icon'        => 'users',
            ),
        );
    }

    /**
     * Restrict a SQL identifier to [A-Za-z0-9_] characters.
     *
     * DDL cannot use $wpdb->prepare() for identifiers, so any identifier
     * that ends up interpolated into a query first passes through this
     * allow-list.
     *
     * @param string $identifier Raw identifier.
     * @return string Identifier with disallowed characters removed.
     */
    private static function sanitize_identifier( $identifier ) {
        return preg_replace( '/[^A-Za-z0-9_]/', '', (string) $identifier );
    }
}
