<?php
/**
 * SCHEMAFY Schema Builder Class
 * 
 * Main orchestrator for the visual/JSON schema builder
 * 
 * @package CustomSchemaSchemafy
 * @since 2.0.0
 * @author SCHEMAFY Team
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Class SCHEMAFY_Schema_Builder
 * 
 * Manages the schema builder interface and functionality
 */
class SCHEMAFY_Schema_Builder {
    
    /**
     * Field Generator instance
     * 
     * @var SCHEMAFY_Field_Generator
     */
    private $field_generator;
    
    /**
     * Validator instance
     * 
     * @var SCHEMAFY_Validator
     */
    private $validator;
    
    /**
     * Database instance
     * 
     * @var SCHEMAFY_Database
     */
    private $database;
    
    /**
     * Supported schema types with their configurations
     * 
     * @var array
     */
    private $schema_types = array(
        // WebPage subtypes
        'ImageGallery',
        'CollectionPage',
        'ItemPage',
        'ProfilePage',
        // Content types
        'Article',
        'BlogPosting',
        'NewsArticle',
        'FAQPage',
        'HowTo',
        'Recipe',
        'Review',
        'Course',
        'VideoObject',
        // Commerce / listings
        'Product',
        'JobPosting',
        // Entities
        'Organization',
        'Person',
        'Event',
        'WebPage',
        'AboutPage',
        'ContactPage',
        'WebSite',
        'BreadcrumbList',
        'Service',
        // LocalBusiness base
        'LocalBusiness',
        // LocalBusiness verticals
        'EventVenue',
        'Restaurant',
        'CafeOrCoffeeShop',
        'Dentist',
        'Physician',
        'Physiotherapist',
        'Pharmacy',
        'BeautySalon',
        'HealthAndBeautyBusiness',
        'Optician',
        'VeterinaryCare',
        'ChildCare',
        'ExerciseGym',
        'LegalService',
        'AccountingService',
        'FinancialService',
        'InsuranceAgency',
        'ProfessionalService',
        'RealEstateAgent',
        'LodgingBusiness',
        'AutoDealer',
        'AutoRepair',
        'AutoWash',
        'AutoRental',
        'AutomotiveBusiness',
        'TaxiService',
        'TravelAgency',
        'Florist',
        'MovingCompany',
        'Plumber',
        'Electrician',
        'HVACBusiness',
        'GeneralContractor',
        'RoofingContractor',
        'HousePainter',
        'HomeAndConstructionBusiness',
        'Locksmith',
        // Food & Beverage
        'FoodEstablishment',
        'Bakery',
        // Events & Entertainment
        'EntertainmentBusiness',
        // Health & Fitness
        'SportsActivityLocation',
        'MedicalBusiness',
    );
    
    /**
     * Constructor
     * 
     * @param SCHEMAFY_Field_Generator $field_generator Field generator instance
     * @param SCHEMAFY_Validator $validator Validator instance
     * @param SCHEMAFY_Database $database Database instance
     */
    public function __construct($field_generator, $validator, $database) {
        $this->field_generator = $field_generator;
        $this->validator = $validator;
        $this->database = $database;
    }
    
    /**
     * Initialize builder hooks
     * 
     * @return void
     */
    public function init() {
        // AJAX handlers for builder
        add_action('wp_ajax_schemafy_builder_load_schema', array($this, 'ajax_load_schema'));
        add_action('wp_ajax_schemafy_builder_save_schema', array($this, 'ajax_save_schema'));
        add_action('wp_ajax_schemafy_builder_validate_field', array($this, 'ajax_validate_field'));
        add_action('wp_ajax_schemafy_builder_get_template', array($this, 'ajax_get_template'));
        add_action('wp_ajax_schemafy_builder_get_field_config', array($this, 'ajax_get_field_config'));
    }
    
    /**
     * Render builder interface
     * 
     * @param array $args Builder configuration
     * @return void
     */
    public function render_builder($args = array()) {
        $defaults = array(
            'schema_id' => 0,
            'context' => 'admin', // 'admin' or 'metabox'
            'url' => '',
            'mode' => 'visual' // 'visual' or 'json'
        );
        
        $args = wp_parse_args($args, $defaults);
        
        // Load existing schema if ID provided
        $schema_data = null;
        if ($args['schema_id'] > 0) {
            $schema_data = $this->database->get_schema($args['schema_id']);
        }
        
        // Enqueue builder assets
        $this->enqueue_builder_assets($args['context']);
        
        // Render template
        $template_path = SCHEMAFY_PLUGIN_PATH . 'templates/builder/main-builder.php';
        if (file_exists($template_path)) {
            include $template_path;
        }
    }
    
    /**
     * Enqueue builder-specific assets
     * 
     * @param string $context Builder context (admin or metabox)
     * @return void
     */
    private function enqueue_builder_assets($context = 'admin') {
        // CSS
        wp_enqueue_style(
            'schemafy-builder',
            SCHEMAFY_PLUGIN_URL . 'assets/css/builder.css',
            array(),
            SCHEMAFY_VERSION
        );
        
        // JavaScript dependencies
        wp_enqueue_script('jquery');
        
        // Builder core
        wp_enqueue_script(
            'schemafy-builder-app',
            SCHEMAFY_PLUGIN_URL . 'assets/js/builder-app.js',
            array('jquery'),
            SCHEMAFY_VERSION,
            true
        );
        
        // Visual mode
        wp_enqueue_script(
            'schemafy-builder-visual',
            SCHEMAFY_PLUGIN_URL . 'assets/js/builder-visual.js',
            array('jquery', 'schemafy-builder-app'),
            SCHEMAFY_VERSION,
            true
        );
        
        // JSON mode (simple textarea-based editor)
        wp_enqueue_script(
            'schemafy-builder-json',
            SCHEMAFY_PLUGIN_URL . 'assets/js/builder-json.js',
            array('jquery', 'schemafy-builder-app'),
            SCHEMAFY_VERSION,
            true
        );
        
        // Preview
        wp_enqueue_script(
            'schemafy-builder-preview',
            SCHEMAFY_PLUGIN_URL . 'assets/js/builder-preview.js',
            array('jquery', 'schemafy-builder-app'),
            SCHEMAFY_VERSION,
            true
        );
        
        // Scoring
        wp_enqueue_script(
            'schemafy-builder-scoring',
            SCHEMAFY_PLUGIN_URL . 'assets/js/builder-scoring.js',
            array('jquery', 'schemafy-builder-app'),
            SCHEMAFY_VERSION,
            true
        );
        
        // Localize script
        wp_localize_script('schemafy-builder-app', 'schemafyBuilder', array(
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('schemafy_builder_nonce'),
            'context' => $context,
            'schema_types' => $this->schema_types,
            'site_url' => get_site_url(),
            'schema_type_registry' => class_exists('SCHEMAFY_Schema_Type_Registry') ? SCHEMAFY_Schema_Type_Registry::get_client_registry() : array(),
            'i18n' => $this->get_builder_i18n()
        ));
    }
    
    /**
     * Get builder internationalization strings
     * 
     * @return array Translatable strings
     */
    private function get_builder_i18n() {
        return array(
            'builder_title' => __('Schema Builder', 'schemafy'),
            'visual_mode' => __('Visual Editor', 'schemafy'),
            'json_mode' => __('JSON Editor', 'schemafy'),
            'preview_mode' => __('Preview', 'schemafy'),
            'meta_tags_mode' => __('Meta Tags', 'schemafy'),
            'save_schema' => __('Save Schema', 'schemafy'),
            'saving' => __('Saving...', 'schemafy'),
            'saved' => __('Saved!', 'schemafy'),
            'error' => __('Error', 'schemafy'),
            'required_field' => __('This field is required', 'schemafy'),
            'invalid_field' => __('Invalid value', 'schemafy'),
            'seo_score' => __('SEO Score', 'schemafy'),
            'excellent' => __('Excellent', 'schemafy'),
            'good' => __('Good', 'schemafy'),
            'needs_work' => __('Needs Work', 'schemafy'),
            'poor' => __('Poor', 'schemafy'),
            'select_type' => __('Select Schema Type', 'schemafy'),
            'load_template' => __('Load Template', 'schemafy'),
            'switch_to_visual' => __('Switch to Visual', 'schemafy'),
            'switch_to_json' => __('Switch to JSON', 'schemafy')
        );
    }
    
    /**
     * AJAX: Load schema configuration
     * 
     * @return void
     */
    public function ajax_load_schema() {
        check_ajax_referer('schemafy_builder_nonce', 'nonce');
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied', 'schemafy'));
        }
        
        $schema_id = intval($_POST['schema_id'] ?? 0);
        
        if ($schema_id > 0) {
            $schema = $this->database->get_schema($schema_id);
            if ($schema) {
                wp_send_json_success($schema);
            } else {
                wp_send_json_error(__('Schema not found', 'schemafy'));
            }
        } else {
            wp_send_json_error(__('Invalid schema ID', 'schemafy'));
        }
    }
    
    /**
     * AJAX: Save schema from builder
     * 
     * @return void
     */
    /**
     * Reject a builder request for a schema type this build cannot serve.
     *
     * Availability is decided by what the build actually ships: a type exists
     * only if its field config is present. The free WordPress.org package has
     * no config for the paid types (Freemius strips *-schema__premium_only.json),
     * so they resolve to "not available" there with no payment check involved.
     *
     * The paid build ships every config, so it additionally enforces the plan
     * server-side — the UI lock cannot be bypassed by crafting a request.
     *
     * @param string $schema_type
     * @return void Dies via wp_send_json_error when the type is unavailable.
     */
    private function guard_premium_type($schema_type) {
        if ($schema_type === '') {
            return;
        }

        if ($this->field_generator->get_field_config($schema_type) === null) {
            wp_send_json_error(__('This schema type is not available in this installation.', 'schemafy'), 404);
        }

        // schemafy_premium_is_paid_type() ships only in the paid build, so this
        // whole branch is absent from the free package.
        if (function_exists('schemafy_premium_is_paid_type')
            && schemafy_premium_is_paid_type($schema_type)
            && ! schemafy_can_access('midtier')) {
            wp_send_json_error(__('This schema type requires a plan upgrade.', 'schemafy'), 403);
        }
    }

    public function ajax_save_schema() {
        check_ajax_referer('schemafy_builder_nonce', 'nonce');

        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied', 'schemafy'));
        }

        $schema_id = intval($_POST['schema_id'] ?? 0);
        $schema_data = json_decode(schemafy_post_string('schema_data') ?: '{}', true);

        // Validate
        $validation = $this->validator->validate_json_decode(schemafy_post_string('schema_data'));
        if (is_wp_error($validation)) {
            wp_send_json_error($validation->get_error_message());
        }

        // Sanitize schema data after validation
        $schema_data = schemafy_sanitize_json_recursive($schema_data);

        // Gate premium schema types by the @type in the payload.
        $posted_type = '';
        if (is_array($schema_data) && isset($schema_data['@type'])) {
            $posted_type = is_array($schema_data['@type']) ? reset($schema_data['@type']) : $schema_data['@type'];
        }
        $this->guard_premium_type(sanitize_text_field((string) $posted_type));

        if ($schema_id > 0) {
            // Update existing
            $result = $this->database->update_schema($schema_id, $schema_data);
        } else {
            // Create new
            $result = $this->database->create_schema($schema_data);
        }
        
        if ($result !== false) {
            wp_send_json_success(array('id' => $result));
        } else {
            wp_send_json_error(__('Failed to save schema', 'schemafy'));
        }
    }
    
    /**
     * AJAX: Validate single field
     * 
     * @return void
     */
    public function ajax_validate_field() {
        check_ajax_referer('schemafy_builder_nonce', 'nonce');
        
        $field_name = sanitize_text_field(wp_unslash($_POST['field_name'] ?? ''));
        $field_value = sanitize_text_field(wp_unslash($_POST['field_value'] ?? ''));
        $field_config = json_decode(schemafy_post_string('field_config') ?: '{}', true);
        // Sanitize field config after JSON decode
        $field_config = schemafy_sanitize_json_recursive($field_config);

        $validation_result = $this->field_generator->validate_field($field_value, $field_config);
        
        wp_send_json_success($validation_result);
    }
    /**
     * AJAX: Get template data
     * 
     * @return void
     */
    public function ajax_get_template() {
        check_ajax_referer('schemafy_builder_nonce', 'nonce');
        
        $schema_type = sanitize_text_field(schemafy_post_string('schema_type'));
        $template_name = sanitize_text_field(wp_unslash($_POST['template_name'] ?? ''));

        $this->guard_premium_type($schema_type);

        $template_data = $this->field_generator->get_template($schema_type, $template_name);
        
        if ($template_data) {
            wp_send_json_success($template_data);
        } else {
            wp_send_json_error(__('Template not found', 'schemafy'));
        }
    }
    
    /**
     * AJAX: Get field configuration for schema type
     * 
     * @return void
     */
    public function ajax_get_field_config() {
        check_ajax_referer('schemafy_builder_nonce', 'nonce');
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Permission denied', 'schemafy'));
        }
        
        $schema_type = sanitize_text_field(schemafy_post_string('schema_type'));

        if (empty($schema_type)) {
            wp_send_json_error(__('Schema type is required', 'schemafy'));
        }

        $this->guard_premium_type($schema_type);

        $field_config = $this->field_generator->get_field_config($schema_type);

        if ($field_config) {
            wp_send_json_success($field_config);
        } else {
            wp_send_json_error(__('This schema type is not available in this installation.', 'schemafy'), 404);
        }
    }
    
    /**
     * Calculate SEO score based on field values
     * 
     * @param array $field_values Field values
     * @param array $config Field configuration
     * @return int Score (0-100)
     */
    private function calculate_seo_score($field_values, $config) {
        $score = 0;
        $max_score = 0;
        
        foreach ($config['fields'] as $field) {
            if (isset($field['seoWeight']) && $field['seoWeight'] > 0) {
                $max_score += $field['seoWeight'];
                
                $field_value = $field_values[$field['name']] ?? '';
                
                if (!empty($field_value)) {
                    $field_score = $field['seoWeight'];
                    
                    // Bonus for meeting minimum length
                    if (isset($field['validation']['minLength']) && 
                        strlen($field_value) >= $field['validation']['minLength']) {
                        $field_score += 5;
                    }
                    
                    // Penalty for exceeding recommended length
                    if (isset($field['maxLength']) && 
                        strlen($field_value) > $field['maxLength'] * 0.9) {
                        $field_score -= 3;
                    }
                    
                    $score += max(0, $field_score);
                }
            }
        }
        
        if ($max_score === 0) {
            return 0;
        }
        
        return min(100, round(($score / $max_score) * 100));
    }
    
    /**
     * Get supported schema types
     * 
     * @return array Schema types
     */
    public function get_schema_types() {
        return $this->schema_types;
    }
}
