<?php
/**
 * Schema Templates Manager
 *
 * Manages schema templates (CRUD operations)
 *
 * @package TamRank
 * @subpackage Schema
 */

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

class TAMRANK_Schema_Templates {

    /**
     * Option name for storing templates
     *
     * @var string
     */
    private $option_name = 'tamrank_schema_templates';

    /**
     * Initialize the templates manager
     */
    public function __construct() {
        // Templates are stored as array in options table
    }

    /**
     * Get all templates
     *
     * @return array Templates
     */
    public function get_templates() {
        $templates = get_option($this->option_name, array());

        return is_array($templates) ? $templates : array();
    }

    /**
     * Get a single template by ID
     *
     * @param string $template_id Template ID
     * @return array|null Template data or null
     */
    public function get_template($template_id) {
        $templates = $this->get_templates();

        return isset($templates[$template_id]) ? $templates[$template_id] : null;
    }

    /**
     * Create a new template
     *
     * @param array $template_data Template data
     * @return string|WP_Error Template ID or error
     */
    public function create_template($template_data) {
        $templates = $this->get_templates();

        // Generate unique ID
        $template_id = 'template_' . uniqid();

        // Validate required fields
        if (empty($template_data['name'])) {
            return new WP_Error('missing_name', tamrank__('schema_template_name_required', 'Template name is required'));
        }

        if (empty($template_data['schema_type'])) {
            return new WP_Error('missing_schema_type', tamrank__('schema_template_type_required', 'Schema type is required'));
        }

        // Set defaults
        $template = array(
            'id' => $template_id,
            'name' => sanitize_text_field($template_data['name']),
            'schema_type' => sanitize_text_field($template_data['schema_type']),
            'post_types' => isset($template_data['post_types']) ? array_map('sanitize_text_field', (array)$template_data['post_types']) : array('post'),
            'field_mappings' => isset($template_data['field_mappings']) ? self::sanitize_field_mappings($template_data['field_mappings']) : tamrank_get_default_template_config($template_data['schema_type']),
            'custom_jsonld_enabled' => isset($template_data['custom_jsonld_enabled']) ? (bool) $template_data['custom_jsonld_enabled'] : false,
            'custom_jsonld_code' => isset($template_data['custom_jsonld_code']) ? $template_data['custom_jsonld_code'] : '',
            'created_at' => current_time('mysql'),
            'updated_at' => current_time('mysql')
        );

        $templates[$template_id] = $template;

        if (update_option($this->option_name, $templates)) {
            return $template_id;
        }

        return new WP_Error('save_failed', tamrank__('schema_template_save_failed', 'Template could not be saved'));
    }

    /**
     * Update an existing template
     *
     * @param string $template_id Template ID
     * @param array $template_data New template data
     * @return bool|WP_Error Success or error
     */
    public function update_template($template_id, $template_data) {
        $templates = $this->get_templates();

        if (!isset($templates[$template_id])) {
            return new WP_Error('not_found', tamrank__('schema_template_not_found', 'Template not found'));
        }

        // Validate required fields
        if (empty($template_data['name'])) {
            return new WP_Error('missing_name', tamrank__('schema_template_name_required', 'Template name is required'));
        }

        // Update template
        $templates[$template_id]['name'] = sanitize_text_field($template_data['name']);
        $templates[$template_id]['schema_type'] = sanitize_text_field($template_data['schema_type']);
        $templates[$template_id]['post_types'] = isset($template_data['post_types']) ? array_map('sanitize_text_field', (array)$template_data['post_types']) : array('post');
        $templates[$template_id]['field_mappings'] = isset($template_data['field_mappings']) ? self::sanitize_field_mappings($template_data['field_mappings']) : array();
        $templates[$template_id]['custom_jsonld_enabled'] = isset($template_data['custom_jsonld_enabled']) ? (bool) $template_data['custom_jsonld_enabled'] : false;
        $templates[$template_id]['custom_jsonld_code'] = isset($template_data['custom_jsonld_code']) ? $template_data['custom_jsonld_code'] : '';
        $templates[$template_id]['updated_at'] = current_time('mysql');

        return update_option($this->option_name, $templates);
    }

    /**
     * Recursively sanitise a field-mappings array.
     *
     * field_mappings is structured config (property => mapping, where a mapping
     * is e.g. ['source' => 'post_title', ...]). Every scalar leaf is run through
     * sanitize_text_field while the array structure is preserved. This keeps the
     * config intact (source keys are slugs) while guaranteeing no raw markup is
     * persisted. custom_jsonld_code is intentionally left raw — it is JSON-LD and
     * is json_decode'd + JSON_HEX_TAG-escaped at output time.
     *
     * @param mixed $mappings Raw field mappings.
     * @return array Sanitised field mappings.
     */
    private static function sanitize_field_mappings($mappings) {
        if (!is_array($mappings)) {
            return array();
        }

        $clean = array();
        foreach ($mappings as $key => $value) {
            $key = is_int($key) ? $key : sanitize_text_field((string) $key);
            if (is_array($value)) {
                $clean[$key] = self::sanitize_field_mappings($value);
            } elseif (is_string($value)) {
                $clean[$key] = sanitize_text_field($value);
            } elseif (is_bool($value) || is_int($value) || is_float($value)) {
                // Preserve type for flags/counters so config semantics stay intact.
                $clean[$key] = $value;
            }
            // null / objects are dropped
        }
        return $clean;
    }

    /**
     * Delete a template
     *
     * @param string $template_id Template ID
     * @return bool Success
     */
    public function delete_template($template_id) {
        $templates = $this->get_templates();

        if (!isset($templates[$template_id])) {
            return false;
        }

        unset($templates[$template_id]);

        return update_option($this->option_name, $templates);
    }

    /**
     * Get templates for a specific post type
     *
     * @param string $post_type Post type
     * @return array Templates
     */
    public function get_templates_for_post_type($post_type) {
        $all_templates = $this->get_templates();
        $filtered = array();

        foreach ($all_templates as $template_id => $template) {
            if (in_array($post_type, $template['post_types'])) {
                $filtered[$template_id] = $template;
            }
        }

        return $filtered;
    }


}
