<?php
/**
 * Widget Manager for BoostBot
 *
 * Manages registration and rendering of interactive widgets.
 *
 * @package BoostBot
 * @since 1.0.0
 */

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

/**
 * Class BoostBot_Widget_Manager
 *
 * Central registry for all BoostBot widgets.
 */
class BoostBot_Widget_Manager {

    /**
     * Registered widgets.
     *
     * @var array
     */
    private static $widgets = array();

    /**
     * Whether the manager has been initialized.
     *
     * @var bool
     */
    private static $initialized = false;

    /**
     * Initialize the widget manager.
     *
     * @since 1.0.0
     */
    public static function init() {
        if ( self::$initialized ) {
            return;
        }

        // Register built-in widgets
        self::register_builtin_widgets();

        // Allow plugins/themes to register custom widgets
        do_action( 'boostbot_register_widgets' );

        self::$initialized = true;

        BoostBot_Logger::debug( 'Widget Manager initialized', array(
            'widget_count' => count( self::$widgets ),
        ) );
    }

    /**
     * Register built-in widgets.
     *
     * @since 1.0.0
     */
    private static function register_builtin_widgets() {
        // Lead Form Widget
        self::register( 'lead_form', 'BoostBot_Lead_Form_Widget' );

        // Contact Card Widget (used by AI via [WIDGET:contact_card:<contact_id>])
        self::register( 'contact_card', 'BoostBot_Contact_Card_Widget' );

        // Product Card Widget
        self::register( 'product_card', 'BoostBot_Product_Card_Widget' );

        // Calendar Widget
        self::register( 'calendar', 'BoostBot_Calendar_Widget' );

        // Survey Widget
        self::register( 'survey', 'BoostBot_Survey_Widget' );
    }

    /**
     * Register a widget.
     *
     * @since 1.0.0
     * @param string $widget_id    Unique widget identifier.
     * @param string $widget_class Widget class name.
     * @throws Exception If widget class doesn't exist or doesn't extend base.
     */
    public static function register( string $widget_id, string $widget_class ) {
        // Validate class exists
        if ( ! class_exists( $widget_class ) ) {
            BoostBot_Logger::warning( "Widget class not found: {$widget_class}" );
            return;
        }

        // Validate class extends base
        if ( ! is_subclass_of( $widget_class, 'BoostBot_Widget_Base' ) ) {
            BoostBot_Logger::error( "Widget must extend BoostBot_Widget_Base: {$widget_class}" );
            return;
        }

        self::$widgets[ $widget_id ] = $widget_class;

        BoostBot_Logger::debug( "Widget registered: {$widget_id}" );
    }

    /**
     * Get a widget instance.
     *
     * @since 1.0.0
     * @param string $widget_id Widget identifier.
     * @return BoostBot_Widget_Base|null Widget instance or null.
     */
    public static function get_widget( string $widget_id ): ?BoostBot_Widget_Base {
        if ( ! isset( self::$widgets[ $widget_id ] ) ) {
            return null;
        }

        $class = self::$widgets[ $widget_id ];
        return new $class();
    }

    /**
     * Check if a widget is registered.
     *
     * @since 1.0.0
     * @param string $widget_id Widget identifier.
     * @return bool True if registered.
     */
    public static function has_widget( string $widget_id ): bool {
        return isset( self::$widgets[ $widget_id ] );
    }

    /**
     * Get all registered widgets with their metadata.
     *
     * @since 1.0.0
     * @return array Widget metadata array.
     */
    public static function get_all_widgets(): array {
        $widgets = array();

        foreach ( self::$widgets as $id => $class ) {
            $instance = new $class();
            $widgets[ $id ] = array(
                'id'          => $id,
                'name'        => $instance->get_name(),
                'description' => $instance->get_description(),
                'icon'        => $instance->get_icon(),
                'schema'      => $instance->get_schema(),
                'free'        => $instance->is_free(),
            );
        }

        return $widgets;
    }

    /**
     * Render a widget.
     *
     * @since 1.0.0
     * @param string $widget_id Widget identifier.
     * @param array  $data      Widget data.
     * @return array|null Render result or null.
     */
    public static function render( string $widget_id, array $data = array() ): ?array {
        $widget = self::get_widget( $widget_id );

        if ( ! $widget ) {
            BoostBot_Logger::warning( "Widget not found for render: {$widget_id}" );
            return null;
        }

        return array(
            'type'    => $widget_id,
            'config'  => $widget->get_config( $data ),
            'schema'  => $widget->get_schema(),
            'scripts' => $widget->get_scripts(),
            'styles'  => $widget->get_styles(),
        );
    }

    /**
     * Handle widget submission.
     *
     * @since 1.0.0
     * @param string $widget_id Widget identifier.
     * @param array  $data      Submitted data.
     * @param array  $context   Submission context (conversation_id, visitor_id, etc.).
     * @return array Submission result.
     */
    public static function handle_submission( string $widget_id, array $data, array $context = array() ): array {
        $widget = self::get_widget( $widget_id );

        if ( ! $widget ) {
            return array(
                'success' => false,
                'errors'  => array( 'widget' => __( 'Widget not found', 'boostbot' ) ),
            );
        }

        // Validate data
        $validation = $widget->validate( $data );

        if ( ! $validation['valid'] ) {
            BoostBot_Logger::debug( 'Widget validation failed', array(
                'widget_id' => $widget_id,
                'errors'    => $validation['errors'],
            ) );

            return array(
                'success' => false,
                'errors'  => $validation['errors'],
            );
        }

        // Process submission
        try {
            $result = $widget->process( $data, $context );

            BoostBot_Logger::info( 'Widget submission processed', array(
                'widget_id' => $widget_id,
            ) );

            return array(
                'success' => true,
                'data'    => $result,
            );

        } catch ( Exception $e ) {
            BoostBot_Logger::error( 'Widget processing failed', array(
                'widget_id' => $widget_id,
                'error'     => $e->getMessage(),
            ) );

            return array(
                'success' => false,
                'errors'  => array( 'processing' => $e->getMessage() ),
            );
        }
    }

    /**
     * Get widget types for frontend.
     *
     * @since 1.0.0
     * @param bool $include_pro Include Pro widgets.
     * @return array Widget types.
     */
    public static function get_widget_types( bool $include_pro = true ): array {
        $widgets = self::get_all_widgets();

        if ( ! $include_pro ) {
            $widgets = array_filter( $widgets, function( $widget ) {
                return $widget['free'];
            } );
        }

        return $widgets;
    }
}




