<?php
/**
 * View Loader Class
 *
 * @package GuardDog
 * @since 1.8.0
 */

if (!defined('ABSPATH')) exit; // Exit if accessed directly

class Guard_Dog_View_Loader {

    /**
     * Load a partial view file.
     *
     * @since 1.8.0
     * @param string $partial_name The name of the partial file (without .php extension).
     * @param array $args Variables to extract and make available in the partial.
     * @param string $directory The directory to look for partials (default: includes/views/partials).
     * @return string The rendered partial content.
     */
    public static function load_partial($partial_name, $args = [], $directory = 'includes/views/partials') {

        // Extract variables to make them available in the partial
        if (!empty($args)) {
            // Handle $this variable specially to avoid conflicts
            $this_instance = null;
            if (isset($args['this'])) {
                $this_instance = $args['this'];
                unset($args['this']);
            }
            
            extract($args);
            
            // Make the instance available as $guard_dog_this to avoid conflicts
            $guard_dog_this = $this_instance;
        }

        // Determine the file path
        $file_path = GUARD_DOG_PATH . $directory . '/' . $partial_name . '.php';

        // Check if file exists
        if (!file_exists($file_path)) {
            if (function_exists('Guard_Dog') && Guard_Dog()->debug && Guard_Dog()->debug->is_enabled()) {
                Guard_Dog()->debug->error('Guard Dog: Partial file not found: ' . esc_html($file_path));
            }
            return '';
        }

        // Start output buffering
        ob_start();

        // Include the partial file
        include $file_path;

        // Return the buffered content
        return ob_get_clean();
    }

    /**
     * Echo a partial view file.
     *
     * @since 1.8.0
     * @param string $partial_name The name of the partial file (without .php extension).
     * @param array $args Variables to extract and make available in the partial.
     * @param string $directory The directory to look for partials (default: includes/views/partials).
     */
    public static function render_partial($partial_name, $args = [], $directory = 'includes/views/partials') {

        // Use custom allowed HTML for form elements and admin interface
        $allowed_html = wp_kses_allowed_html('post');

        // Add form elements that are commonly needed in admin interfaces
        $allowed_html['form'] = array(
            'name' => true,
            'id' => true,
            'action' => true,
            'method' => true,
            'class' => true,
            'style' => true,
            'enctype' => true,
            'target' => true,
        );

        $allowed_html['input'] = array(
            'type' => true,
            'id' => true,
            'name' => true,
            'value' => true,
            'size' => true,
            'maxlength' => true,
            'autocomplete' => true,
            'required' => true,
            'disabled' => true,
            'readonly' => true,
            'placeholder' => true,
            'class' => true,
            'style' => true,
        );

        $allowed_html['select'] = array(
            'id' => true,
            'name' => true,
            'required' => true,
            'disabled' => true,
            'class' => true,
            'style' => true,
        );

        $allowed_html['option'] = array(
            'value' => true,
            'selected' => true,
            'disabled' => true,
        );

        $allowed_html['textarea'] = array(
            'id' => true,
            'name' => true,
            'rows' => true,
            'cols' => true,
            'required' => true,
            'disabled' => true,
            'readonly' => true,
            'placeholder' => true,
            'class' => true,
            'style' => true,
        );

        $allowed_html['label'] = array(
            'for' => true,
            'class' => true,
            'style' => true,
        );

        $allowed_html['div'] = array(
            'id' => true,
            'class' => true,
            'style' => true,
            // CAPTCHA provider attributes
            'data-sitekey' => true,
            'data-theme' => true,
            'data-size' => true,
            'data-action' => true,
            'data-callback' => true,
            'data-expired-callback' => true,
            'data-error-callback' => true,
            'data-tabindex' => true,
            'data-badge' => true,
            'data-language' => true,
            'data-recaptcha' => true,
        );

        $allowed_html['span'] = array(
            'class' => true,
            'style' => true,
        );

        $allowed_html['p'] = array(
            'id' => true,
            'class' => true,
            'style' => true,
        );

        $allowed_html['a'] = array(
            'href' => true,
            'id' => true,
            'class' => true,
            'style' => true,
            'target' => true,
            'rel' => true,
        );

        echo wp_kses(self::load_partial($partial_name, $args, $directory), $allowed_html);
    }

    /**
     * Load an email template with customizer and theme override support.
     *
     * Template hierarchy (in priority order):
     * 1. Customized theme file (exported from customizer): {theme}/guard-dog/emails/{template_name}.php
     * 2. Customizer database settings (if customized): Rendered dynamically
     * 3. Default plugin template: {plugin}/includes/views/emails/{template_name}.php
     *
     * @since 1.8.5
     * @param string $template_name The name of the email template (without .php extension).
     * @param array $args Variables to extract and make available in the template.
     * @return string The rendered template content.
     */
    public static function load_email_template($template_name, $args = []) {
        $template_source = '';
        $content = '';

        // Determine if this is a plain text template
        $is_plain_template = (substr($template_name, -6) === '-plain');
        $template_subdir = $is_plain_template ? 'plain/' : '';
        $theme_subdir = $is_plain_template ? 'plain/' : '';

        // Check for theme override first (highest priority)
        $theme_template_path = get_stylesheet_directory() . '/guard-dog/emails/' . $theme_subdir . $template_name . '.php';
        $parent_theme_template_path = get_template_directory() . '/guard-dog/emails/' . $theme_subdir . $template_name . '.php';
        $plugin_template_path = GUARD_DOG_PATH . 'includes/views/emails/' . $template_subdir . $template_name . '.php';

        // Determine which template file exists (if any)
        $template_path = null;
        if (file_exists($theme_template_path)) {
            $template_path = $theme_template_path;
            $template_source = 'child_theme';
        } elseif (file_exists($parent_theme_template_path)) {
            $template_path = $parent_theme_template_path;
            $template_source = 'parent_theme';
        }

        // Allow plugins to filter the template path
        $template_path = apply_filters('guard_dog_email_template_path', $template_path, $template_name, $args);

        // If theme override exists, use it
        if ($template_path && file_exists($template_path)) {
            // Extract variables to make them available in the template
            if (!empty($args)) {
                extract($args);
            }

            // Start output buffering
            ob_start();

            // Allow themes/plugins to modify variables before template is loaded
            do_action('guard_dog_before_email_template', $template_name, $args);

            // Include the template file
            include $template_path;

            // Get the buffered content
            $content = ob_get_clean();

            // Debug logging
            if (function_exists('Guard_Dog') && Guard_Dog()->debug && Guard_Dog()->debug->is_enabled()) {
                Guard_Dog()->debug->info('Loaded email template from theme', 'email_template', [
                    'template_name' => $template_name,
                    'template_source' => $template_source,
                    'template_path' => $template_path
                ]);
            }
        }
        // No theme override - check for customizer settings (second priority)
        elseif ($template_name === 'two-factor-code' && class_exists('Guard_Dog_Email_Template_Customizer')) {
            $customizer = new Guard_Dog_Email_Template_Customizer();
            $settings = $customizer->get_settings();

            // Check if customizer has been used (has non-default settings)
            if (!empty($settings) && self::has_customizer_settings($settings)) {
                // Merge template args with default values for customizer
                $template_args = array_merge([
                    'code' => '------',
                    'user' => null,
                    'site_name' => get_bloginfo('name'),
                    'expiry_minutes' => 10
                ], $args);

                // Generate output using customizer
                $content = $customizer->generate_output($template_args);
                $template_source = 'customizer';

                // Debug logging
                if (function_exists('Guard_Dog') && Guard_Dog()->debug && Guard_Dog()->debug->is_enabled()) {
                    Guard_Dog()->debug->info('Generated email template from customizer', 'email_template', [
                        'template_name' => $template_name,
                        'template_source' => 'customizer',
                        'settings_count' => count($settings)
                    ]);
                }
            }
        }
        // Plain text version - check for customizer plain text output
        elseif ($template_name === 'two-factor-code-plain' && class_exists('Guard_Dog_Email_Template_Customizer')) {
            $customizer = new Guard_Dog_Email_Template_Customizer();
            $settings = $customizer->get_settings();

            // Check if customizer has been used
            if (!empty($settings) && self::has_customizer_settings($settings)) {
                // Merge template args
                $template_args = array_merge([
                    'code' => '------',
                    'user' => null,
                    'site_name' => get_bloginfo('name'),
                    'expiry_minutes' => 10
                ], $args);

                // Generate plain text output
                $content = $customizer->generate_plain_text_output($template_args);
                $template_source = 'customizer_plain';

                // Debug logging
                if (function_exists('Guard_Dog') && Guard_Dog()->debug && Guard_Dog()->debug->is_enabled()) {
                    Guard_Dog()->debug->info('Generated plain text email from customizer', 'email_template', [
                        'template_name' => $template_name,
                        'template_source' => 'customizer_plain'
                    ]);
                }
            }
        }
        // Suspicious activity admin - customizer
        elseif ($template_name === 'suspicious-activity-admin' && class_exists('Guard_Dog_Email_Template_Customizer')) {
            $customizer = new Guard_Dog_Email_Template_Customizer( array( 'template_type' => 'suspicious-activity-admin' ) );
            $settings = $customizer->get_settings();

            if (!empty($settings) && self::has_customizer_settings($settings)) {
                $template_args = array_merge( array( 'user' => null, 'type' => '', 'details' => '', 'site_name' => get_bloginfo( 'name' ) ), $args );
                $content = $customizer->generate_output( $template_args );
                $template_source = 'customizer';
            }
        }
        // Suspicious activity admin plain - customizer
        elseif ($template_name === 'suspicious-activity-admin-plain' && class_exists('Guard_Dog_Email_Template_Customizer')) {
            $customizer = new Guard_Dog_Email_Template_Customizer( array( 'template_type' => 'suspicious-activity-admin' ) );
            $settings = $customizer->get_settings();

            if (!empty($settings) && self::has_customizer_settings($settings)) {
                $template_args = array_merge( array( 'user' => null, 'type' => '', 'details' => '', 'site_name' => get_bloginfo( 'name' ) ), $args );
                $content = $customizer->generate_plain_text_output( $template_args );
                $template_source = 'customizer_plain';
            }
        }
        // Suspicious activity user - customizer
        elseif ($template_name === 'suspicious-activity-user' && class_exists('Guard_Dog_Email_Template_Customizer')) {
            $customizer = new Guard_Dog_Email_Template_Customizer( array( 'template_type' => 'suspicious-activity-user' ) );
            $settings = $customizer->get_settings();

            if (!empty($settings) && self::has_customizer_settings($settings)) {
                $template_args = array_merge( array( 'user' => null, 'site_name' => get_bloginfo( 'name' ), 'name' => '' ), $args );
                $content = $customizer->generate_output( $template_args );
                $template_source = 'customizer';
            }
        }
        // Suspicious activity user plain - customizer
        elseif ($template_name === 'suspicious-activity-user-plain' && class_exists('Guard_Dog_Email_Template_Customizer')) {
            $customizer = new Guard_Dog_Email_Template_Customizer( array( 'template_type' => 'suspicious-activity-user' ) );
            $settings = $customizer->get_settings();

            if (!empty($settings) && self::has_customizer_settings($settings)) {
                $template_args = array_merge( array( 'user' => null, 'site_name' => get_bloginfo( 'name' ), 'name' => '' ), $args );
                $content = $customizer->generate_plain_text_output( $template_args );
                $template_source = 'customizer_plain';
            }
        }

        // Fallback to default plugin template if no customizer or theme override
        if (empty($content) && file_exists($plugin_template_path)) {
            // Extract variables to make them available in the template
            if (!empty($args)) {
                extract($args);
            }

            // Start output buffering
            ob_start();

            // Allow themes/plugins to modify variables before template is loaded
            do_action('guard_dog_before_email_template', $template_name, $args);

            // Include the template file
            include $plugin_template_path;

            // Get the buffered content
            $content = ob_get_clean();
            $template_source = 'plugin_default';

            // Debug logging
            if (function_exists('Guard_Dog') && Guard_Dog()->debug && Guard_Dog()->debug->is_enabled()) {
                Guard_Dog()->debug->info('Loaded default plugin email template', 'email_template', [
                    'template_name' => $template_name,
                    'template_source' => 'plugin_default',
                    'template_path' => $plugin_template_path
                ]);
            }
        }

        // If still no content, log error
        if (empty($content)) {
            if (function_exists('Guard_Dog') && Guard_Dog()->debug && Guard_Dog()->debug->is_enabled()) {
                Guard_Dog()->debug->error('Email template not found', 'email_template', [
                    'template_name' => $template_name,
                    'searched_paths' => [
                        'theme' => $theme_template_path,
                        'parent_theme' => $parent_theme_template_path,
                        'plugin' => $plugin_template_path
                    ]
                ]);
            }
            return '';
        }

        // Allow themes/plugins to modify the output
        $content = apply_filters('guard_dog_email_template_content', $content, $template_name, $args, $template_source);

        return $content;
    }

    /**
     * Check if customizer has non-default settings.
     *
     * @since 1.8.45
     * @param array $settings Customizer settings
     * @return bool True if customizer has been customized
     */
    private static function has_customizer_settings($settings) {
        // If settings array is empty, not customized
        if (empty($settings)) {
            return false;
        }

        // Check if any non-default values exist
        // The customizer is considered "used" if at least one setting is present
        $has_settings = count($settings) > 0;

        return $has_settings;
    }
} 