<?php
/**
 * Guard Dog Customizer Base Class
 *
 * Abstract base class for all Guard Dog customizers. Provides a reusable framework
 * for creating visual customization interfaces in the WordPress admin.
 *
 * @package GuardDog
 * @since 1.8.45
 */

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

abstract class Guard_Dog_Customizer {

    /**
     * Sections registered with this customizer
     * @var array
     */
    protected $sections = [];

    /**
     * Controls registered with this customizer
     * @var array
     */
    protected $controls = [];

    /**
     * Current settings
     * @var array
     */
    protected $settings = [];

    /**
     * Available control types
     * @var array
     */
    protected $control_types = [];

    /**
     * Constructor
     */
    public function __construct() {
        $this->register_default_control_types();
        $this->load_settings();
        $this->register_controls();
        $this->init_hooks();
    }

    /**
     * Get unique ID for this customizer
     *
     * @return string
     */
    abstract public function get_customizer_id();

    /**
     * Get title for this customizer
     *
     * @return string
     */
    abstract public function get_customizer_title();

    /**
     * Get description for this customizer
     *
     * @return string
     */
    public function get_customizer_description() {
        return '';
    }

    /**
     * Register sections and controls
     * Override this method to add your sections and controls
     */
    abstract protected function register_controls();

    /**
     * Generate output based on current settings
     * Override this to generate preview HTML
     *
     * @param array $settings Settings to use for generation
     * @return string Generated HTML
     */
    abstract public function generate_output($settings);

    /**
     * Initialize hooks
     */
    protected function init_hooks() {
        // Note: Asset enqueuing is handled by Guard_Dog_Customizer_Loader::enqueue_customizer_assets()
        // This ensures assets are enqueued before the customizer instance is created

        // Register AJAX handlers
        add_action('wp_ajax_guard_dog_customizer_preview_' . $this->get_customizer_id(), [$this, 'ajax_preview']);
        add_action('wp_ajax_guard_dog_customizer_save_' . $this->get_customizer_id(), [$this, 'ajax_save']);
        add_action('wp_ajax_guard_dog_customizer_reset_' . $this->get_customizer_id(), [$this, 'ajax_reset']);
        add_action('wp_ajax_guard_dog_customizer_export_' . $this->get_customizer_id(), [$this, 'ajax_export']);
    }

    /**
     * Register default control types
     */
    protected function register_default_control_types() {
        $this->control_types = [
            'text' => 'Guard_Dog_Text_Control',
            'textarea' => 'Guard_Dog_Textarea_Control',
            'color' => 'Guard_Dog_Color_Control',
            'image' => 'Guard_Dog_Image_Control',
            'select' => 'Guard_Dog_Select_Control',
            'checkbox' => 'Guard_Dog_Checkbox_Control',
            'radio' => 'Guard_Dog_Radio_Control',
            'number' => 'Guard_Dog_Number_Control',
        ];

        // Allow plugins to register custom control types
        $this->control_types = apply_filters('guard_dog_customizer_control_types', $this->control_types);
    }

    /**
     * Add a section
     *
     * @param string $id Section ID
     * @param string $title Section title
     * @param array $args Additional arguments
     */
    public function add_section($id, $title, $args = []) {
        $this->sections[$id] = array_merge([
            'id' => $id,
            'title' => $title,
            'description' => '',
            'priority' => 10,
        ], $args);
    }

    /**
     * Add a control
     *
     * @param string $id Control ID
     * @param string $type Control type
     * @param string $section Section ID
     * @param array $args Control arguments
     */
    public function add_control($id, $type, $section, $args = []) {
        if (!isset($this->control_types[$type])) {
            return;
        }

        $control_class = $this->control_types[$type];

        if (!class_exists($control_class)) {
            return;
        }

        $this->controls[$id] = new $control_class($id, $section, array_merge([
            'type' => $type,
            'label' => '',
            'description' => '',
            'default' => '',
            'priority' => 10,
        ], $args));
    }

    /**
     * Get option name for storing settings
     *
     * @return string
     */
    protected function get_option_name() {
        return 'guard_dog_customizer_' . $this->get_customizer_id();
    }

    /**
     * Load settings from database
     *
     * @since 1.9.1 Changed from protected to public to allow external use
     */
    public function load_settings() {
        $this->settings = get_option($this->get_option_name(), []);
    }

    /**
     * Get all settings
     *
     * @return array
     */
    public function get_settings() {
        return $this->settings;
    }

    /**
     * Get a specific setting value
     *
     * @param string $key Setting key
     * @param mixed $default Default value
     * @return mixed
     */
    public function get_setting($key, $default = null) {
        if (isset($this->settings[$key])) {
            return $this->settings[$key];
        }

        // Get default from control if available
        if (isset($this->controls[$key])) {
            return $this->controls[$key]->get_default();
        }

        return $default;
    }

    /**
     * Save settings to database
     *
     * @param array $settings Settings to save
     * @return bool
     */
    protected function save_settings($settings) {
        // Sanitize all settings through their respective controls
        $sanitized = [];
        foreach ($settings as $key => $value) {
            if (isset($this->controls[$key])) {
                $sanitized[$key] = $this->controls[$key]->sanitize($value);
            } else {
                $sanitized[$key] = sanitize_text_field($value);
            }
        }

        // Apply filter for additional validation
        $sanitized = apply_filters(
            'guard_dog_customizer_settings_' . $this->get_customizer_id(),
            $sanitized,
            $settings
        );

        // Update settings
        $this->settings = $sanitized;
        return update_option($this->get_option_name(), $sanitized);
    }

    /**
     * Reset settings to defaults
     */
    protected function reset_settings() {
        $defaults = [];
        foreach ($this->controls as $id => $control) {
            $defaults[$id] = $control->get_default();
        }
        $this->save_settings($defaults);
    }

    /**
     * Check if theme override exists
     *
     * @return bool
     */
    protected function has_theme_override() {
        return false; // Override in child class if needed
    }

    /**
     * Enqueue customizer assets
     *
     * @param string $hook Current admin page hook
     */
    public function enqueue_assets($hook) {
        // Only load on customizer page
        if (!$this->is_customizer_page($hook)) {
            return;
        }

        // Enqueue WordPress color picker
        wp_enqueue_style('wp-color-picker');
        wp_enqueue_script('wp-color-picker');

        // Enqueue WordPress media library
        wp_enqueue_media();

        // Enqueue customizer CSS
        wp_enqueue_style(
            'guard-dog-customizer',
            GUARD_DOG_URL . 'assets/css/guard-dog-customizer.css',
            [],
            GUARD_DOG_VERSION,
			true
        );

        // Enqueue customizer JS
        wp_enqueue_script(
            'guard-dog-customizer',
            GUARD_DOG_URL . 'assets/js/guard-dog-customizer.js',
            ['jquery', 'wp-color-picker'],
            GUARD_DOG_VERSION,
            true
        );

        // Localize script
        wp_localize_script('guard-dog-customizer', 'guardDogCustomizer', [
            'ajaxUrl' => admin_url('admin-ajax.php'),
            'customizerId' => $this->get_customizer_id(),
            'nonces' => [
                'preview' => wp_create_nonce('guard_dog_customizer_preview_' . $this->get_customizer_id()),
                'save' => wp_create_nonce('guard_dog_customizer_save_' . $this->get_customizer_id()),
                'reset' => wp_create_nonce('guard_dog_customizer_reset_' . $this->get_customizer_id()),
                'export' => wp_create_nonce('guard_dog_customizer_export_' . $this->get_customizer_id()),
            ],
            'strings' => [
                'saving' => __('Saving...', 'guard-dog'),
                'saved' => __('Settings saved!', 'guard-dog'),
                'saveFailed' => __('Failed to save settings.', 'guard-dog'),
                'resetConfirm' => __('Are you sure you want to reset all settings to defaults? This cannot be undone.', 'guard-dog'),
                'resetting' => __('Resetting...', 'guard-dog'),
                'resetComplete' => __('Settings reset to defaults.', 'guard-dog'),
                'exportSuccess' => __('Template exported successfully!', 'guard-dog'),
                'exportFailed' => __('Failed to export template.', 'guard-dog'),
            ],
        ]);

        // Allow child classes to enqueue additional assets
        $this->enqueue_additional_assets();
    }

    /**
     * Enqueue additional assets
     * Override this in child class if needed
     */
    protected function enqueue_additional_assets() {
        // Override in child class
    }

    /**
     * Check if current page is the customizer page
     *
     * @param string $hook Current admin page hook
     * @return bool
     */
    protected function is_customizer_page($hook) {
        return false; // Override in child class
    }

    /**
     * AJAX handler for preview
     */
    public function ajax_preview() {
        check_ajax_referer('guard_dog_customizer_preview_' . $this->get_customizer_id(), 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Permission denied.', 'guard-dog')]);
        }

        $settings = isset($_POST['settings']) ? wp_unslash($_POST['settings']) : [];

        // Sanitize settings
        $sanitized = [];
        foreach ($settings as $key => $value) {
            if (isset($this->controls[$key])) {
                $sanitized[$key] = $this->controls[$key]->sanitize($value);
            }
        }

        // Generate preview
        $html = $this->generate_output($sanitized);

        // Apply filter
        $html = apply_filters(
            'guard_dog_customizer_preview_' . $this->get_customizer_id(),
            $html,
            $sanitized
        );

        wp_send_json_success(['html' => $html]);
    }

    /**
     * AJAX handler for save
     */
    public function ajax_save() {
        check_ajax_referer('guard_dog_customizer_save_' . $this->get_customizer_id(), 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Permission denied.', 'guard-dog')]);
        }

        $settings = isset($_POST['settings']) ? wp_unslash($_POST['settings']) : [];

        if ($this->save_settings($settings)) {
            do_action('guard_dog_customizer_saved_' . $this->get_customizer_id(), $settings);
            wp_send_json_success(['message' => __('Settings saved successfully!', 'guard-dog')]);
        } else {
            wp_send_json_error(['message' => __('Failed to save settings.', 'guard-dog')]);
        }
    }

    /**
     * AJAX handler for reset
     */
    public function ajax_reset() {
        check_ajax_referer('guard_dog_customizer_reset_' . $this->get_customizer_id(), 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Permission denied.', 'guard-dog')]);
        }

        $this->reset_settings();

        do_action('guard_dog_customizer_reset_' . $this->get_customizer_id());

        wp_send_json_success([
            'message' => __('Settings reset to defaults.', 'guard-dog'),
            'settings' => $this->get_settings()
        ]);
    }

    /**
     * AJAX handler for export
     */
    public function ajax_export() {
        check_ajax_referer('guard_dog_customizer_export_' . $this->get_customizer_id(), 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Permission denied.', 'guard-dog')]);
        }

        $result = $this->export_to_theme();

        if ($result['success']) {
            wp_send_json_success($result);
        } else {
            wp_send_json_error($result);
        }
    }

    /**
     * Export settings to theme file
     * Override this in child class
     *
     * @return array Result with success status and message
     */
    protected function export_to_theme() {
        return [
            'success' => false,
            'message' => __('Export not implemented for this customizer.', 'guard-dog')
        ];
    }

    /**
     * Render the customizer page
     */
    public function render() {
        if (!current_user_can('manage_options')) {
            wp_die(__('You do not have sufficient permissions to access this page.', 'guard-dog'));
        }

        ?>
        <div class="wrap guard-dog-customizer" data-customizer-id="<?php echo esc_attr($this->get_customizer_id()); ?>">
            <h1><?php echo esc_html($this->get_customizer_title()); ?></h1>

            <?php if ($this->get_customizer_description()): ?>
                <p class="description"><?php echo esc_html($this->get_customizer_description()); ?></p>
            <?php endif; ?>

            <div class="customizer-container">
                <div class="customizer-controls">
                    <?php $this->render_controls(); ?>
                </div>

                <div class="customizer-preview">
                    <?php $this->render_preview(); ?>
                </div>
            </div>

            <div class="customizer-actions">
                <?php $this->render_actions(); ?>
            </div>

            <?php $this->render_status(); ?>
        </div>
        <?php
    }

    /**
     * Render controls panel
     */
    protected function render_controls() {
        // Group controls by section
        $controls_by_section = [];
        foreach ($this->controls as $control) {
            $section_id = $control->get_section();
            if (!isset($controls_by_section[$section_id])) {
                $controls_by_section[$section_id] = [];
            }
            $controls_by_section[$section_id][] = $control;
        }

        // Render sections and their controls
        foreach ($this->sections as $section_id => $section) {
            ?>
            <div class="customizer-section" data-section-id="<?php echo esc_attr($section_id); ?>">
                <h3 class="customizer-section-title"><?php echo esc_html($section['title']); ?></h3>

                <?php if (!empty($section['description'])): ?>
                    <p class="description"><?php echo esc_html($section['description']); ?></p>
                <?php endif; ?>

                <div class="customizer-section-controls">
                    <?php
                    if (isset($controls_by_section[$section_id])) {
                        foreach ($controls_by_section[$section_id] as $control) {
                            $value = $this->get_setting($control->get_id(), $control->get_default());
                            $control->render($value);
                        }
                    }
                    ?>
                </div>
            </div>
            <?php
        }
    }

    /**
     * Render preview panel
     */
    protected function render_preview() {
        ?>
        <div class="customizer-preview-header">
            <h3><?php esc_html_e('Preview', 'guard-dog'); ?></h3>
            <div class="preview-device-buttons">
                <button class="button preview-device" data-device="desktop" title="<?php esc_attr_e('Desktop View', 'guard-dog'); ?>">
                    <span class="dashicons dashicons-desktop"></span>
                </button>
                <button class="button preview-device" data-device="tablet" title="<?php esc_attr_e('Tablet View', 'guard-dog'); ?>">
                    <span class="dashicons dashicons-tablet"></span>
                </button>
                <button class="button preview-device active" data-device="mobile" title="<?php esc_attr_e('Mobile View', 'guard-dog'); ?>">
                    <span class="dashicons dashicons-smartphone"></span>
                </button>
            </div>
        </div>

        <div class="customizer-preview-frame" data-device="mobile">
            <iframe id="customizer-preview-iframe"></iframe>
        </div>

        <div class="customizer-preview-actions">
            <?php $this->render_preview_actions(); ?>
        </div>
        <?php
    }

    /**
     * Render preview-specific actions
     * Override in child class
     */
    protected function render_preview_actions() {
        // Override in child class
    }

    /**
     * Render action buttons
     */
    protected function render_actions() {
        ?>
        <button type="button" class="button button-primary customizer-save">
            <span class="dashicons dashicons-yes"></span>
            <?php esc_html_e('Save Changes', 'guard-dog'); ?>
        </button>

        <button type="button" class="button customizer-reset">
            <span class="dashicons dashicons-image-rotate"></span>
            <?php esc_html_e('Reset to Defaults', 'guard-dog'); ?>
        </button>

        <button type="button" class="button customizer-export">
            <span class="dashicons dashicons-download"></span>
            <?php esc_html_e('Export to Theme File', 'guard-dog'); ?>
        </button>
        <?php
    }

    /**
     * Render status indicator
     */
    protected function render_status() {
        $using_theme = $this->has_theme_override();
        ?>
        <div class="customizer-status">
            <?php if ($using_theme): ?>
                <span class="status-indicator theme-override">
                    <span class="dashicons dashicons-admin-appearance"></span>
                    <?php esc_html_e('Using theme file override', 'guard-dog'); ?>
                </span>
            <?php else: ?>
                <span class="status-indicator database-settings">
                    <span class="dashicons dashicons-database"></span>
                    <?php esc_html_e('Using database settings', 'guard-dog'); ?>
                </span>
            <?php endif; ?>
        </div>
        <?php
    }
}
