<?php
/**
 * Data Registry Class
 *
 * Tracks all data storage locations used by modules for accurate cleanup
 * and data management.
 *
 * @package Switchboard
 * @since 1.0.0
 */

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

class Switchboard_Data_Registry {

    /**
     * Singleton instance
     */
    private static $instance = null;

    /**
     * Registered module data locations
     */
    private $registered_data = [];

    /**
     * Store module instances for lifecycle management
     */
    private $module_instances = [];

    /**
     * Get singleton instance
     */
    public static function get_instance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Private constructor for singleton
     */
    private function __construct() {
        // Initialize
    }

    /**
     * Register a module's data locations
     *
     * @param string $module_slug Module identifier
     * @param object $module_instance Module instance
     */
    public function register_module($module_slug, $module_instance) {
        // Store the module instance for lifecycle management (activate/deactivate)
        $this->module_instances[$module_slug] = $module_instance;

        // Check if module has registration method
        if (!method_exists($module_instance, 'register_data_locations')) {
            return;
        }

        $data_locations = $module_instance->register_data_locations();

        if (!is_array($data_locations)) {
            return;
        }

        // Validate and store
        $this->registered_data[$module_slug] = $this->validate_data_structure($data_locations);
    }

    /**
     * Get a module instance by slug
     *
     * @param string $module_slug Module identifier
     * @return object|null Module instance or null if not found
     */
    public function get_module_instance($module_slug) {
        return isset($this->module_instances[$module_slug]) ? $this->module_instances[$module_slug] : null;
    }

    /**
     * Auto-register a module by inferring slug from filename
     *
     * @param object $module_instance Module instance
     * @param string $file Module file path (use __FILE__)
     */
    public function auto_register($module_instance, $file) {
        // Extract module slug from filename
        // e.g., /path/to/lean-analytics.php -> lean-analytics
        $module_slug = basename($file, '.php');

        $this->register_module($module_slug, $module_instance);
    }

    /**
     * Validate data structure
     */
    private function validate_data_structure($data) {
        $defaults = [
            'options' => [],
            'option_patterns' => [],
            'tables' => [],
            'post_meta' => [],
            'user_meta' => [],
            'transients' => [],
        ];

        return wp_parse_args($data, $defaults);
    }

    /**
     * Get all registered data from all modules
     *
     * @return array Complete data map
     */
    public function get_all_registered_data() {
        return $this->registered_data;
    }

    /**
     * Get data locations for specific module
     *
     * @param string $module_slug Module identifier
     * @return array|null Module data or null if not found
     */
    public function get_module_data($module_slug) {
        return $this->registered_data[$module_slug] ?? null;
    }

    /**
     * Get consolidated list of all options
     *
     * @return array All option names and patterns
     */
    public function get_all_options() {
        $options = [];
        $patterns = [];

        foreach ($this->registered_data as $module_slug => $data) {
            $options = array_merge($options, $data['options']);
            $patterns = array_merge($patterns, $data['option_patterns']);
        }

        return [
            'names' => array_unique($options),
            'patterns' => array_unique($patterns),
        ];
    }

    /**
     * Get consolidated list of all tables
     *
     * @return array All table names
     */
    public function get_all_tables() {
        $tables = [];

        foreach ($this->registered_data as $module_slug => $data) {
            $tables = array_merge($tables, $data['tables']);
        }

        return array_unique($tables);
    }

    /**
     * Get consolidated list of all post meta keys
     *
     * @return array All post meta keys
     */
    public function get_all_post_meta() {
        $meta_keys = [];

        foreach ($this->registered_data as $module_slug => $data) {
            $meta_keys = array_merge($meta_keys, $data['post_meta']);
        }

        return array_unique($meta_keys);
    }

    /**
     * Get consolidated list of all user meta keys
     *
     * @return array All user meta keys
     */
    public function get_all_user_meta() {
        $meta_keys = [];

        foreach ($this->registered_data as $module_slug => $data) {
            $meta_keys = array_merge($meta_keys, $data['user_meta']);
        }

        return array_unique($meta_keys);
    }

    /**
     * Get data summary for admin display
     *
     * @return array Summary stats
     */
    public function get_summary() {
        $summary = [
            'total_modules' => count($this->registered_data),
            'total_options' => 0,
            'total_patterns' => 0,
            'total_tables' => 0,
            'total_post_meta' => 0,
            'total_user_meta' => 0,
        ];

        foreach ($this->registered_data as $data) {
            $summary['total_options'] += count($data['options']);
            $summary['total_patterns'] += count($data['option_patterns']);
            $summary['total_tables'] += count($data['tables']);
            $summary['total_post_meta'] += count($data['post_meta']);
            $summary['total_user_meta'] += count($data['user_meta']);
        }

        return $summary;
    }

    /**
     * Export registry as JSON (for debugging)
     *
     * @return string JSON representation
     */
    public function export_json() {
        return json_encode($this->registered_data, JSON_PRETTY_PRINT);
    }

    /**
     * Load ALL modules (active AND inactive) to register their data
     *
     * This is used during data cleanup to ensure we can find data from
     * modules that were previously enabled but are now disabled.
     *
     * IMPORTANT: This temporarily loads module files ONLY to call
     * register_data_locations(). It does NOT initialize the modules
     * or run their functionality.
     *
     * @return void
     */
    public function load_all_modules_for_cleanup() {
        if (!defined('SWITCHBOARD_PATH')) {
            return;
        }

        $modules_dir = SWITCHBOARD_PATH . 'modules/';
        $categories = ['admin', 'content', 'media', 'security', 'optimization', 'user-management', 'utilities'];

        foreach ($categories as $category) {
            $category_path = $modules_dir . $category;

            if (!is_dir($category_path)) {
                continue;
            }

            $files = glob($category_path . '/*.php');

            foreach ($files as $file) {
                $module_slug = basename($file, '.php');

                // Skip if already registered (active module)
                if (isset($this->registered_data[$module_slug])) {
                    continue;
                }

                // Temporarily load the file to get registration
                // The module code at the bottom will auto-register
                require_once $file;
            }
        }
    }
}
