<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: /home/ploi/automarketer-ai.com/public/wp-content/plugins/automarketer-ai/includes/class-model-watcher.php
// Description: Daily cron that diffs live provider model lists and flags new models for badge display - NUCLEAR+++
// Last Edited: 2026-04-10
// ==================================================

namespace AutoMarketerAI;

if (!defined('ABSPATH')) {
    exit('No direct script access allowed.');
}

final class ModelWatcher
{
    private const CRON_HOOK     = 'amai_model_watcher_daily';
    private const KNOWN_OPTION  = 'amai_known_models_';
    private const NEW_OPTION    = 'amai_new_models_';

    // ---------------------------------------------------------------------------
    // Boot
    // ---------------------------------------------------------------------------

    public static function init(): void
    {
        add_action(self::CRON_HOOK, [self::class, 'run']);

        if (!wp_next_scheduled(self::CRON_HOOK)) {
            wp_schedule_event(time(), 'daily', self::CRON_HOOK);
        }
    }

    public static function scheduleDaily(): void
    {
        if (!wp_next_scheduled(self::CRON_HOOK)) {
            wp_schedule_event(time(), 'daily', self::CRON_HOOK);
        }
    }

    public static function clearSchedule(): void
    {
        $timestamp = wp_next_scheduled(self::CRON_HOOK);
        if ($timestamp !== false) {
            wp_unschedule_event($timestamp, self::CRON_HOOK);
        }
    }

    // ---------------------------------------------------------------------------
    // Main runner — called by daily cron
    // ---------------------------------------------------------------------------

    public static function run(): void
    {
        $modules = self::load_all_modules();

        foreach ($modules as $id => $module) {
            if (!method_exists($module, 'fetch_live_models')) {
                continue;
            }

            $api_key = KeyVault::decrypt((string) get_option('amai_api_key_' . $id, ''));
            if ($api_key === '') {
                continue;
            }

            $live_models = $module->fetch_live_models($api_key);
            $live_ids    = array_keys($live_models);

            $known_ids = (array) get_option(self::KNOWN_OPTION . $id, []);

            if (empty($known_ids)) {
                // First run — store baseline, no badge.
                update_option(self::KNOWN_OPTION . $id, $live_ids, false);
                continue;
            }

            $new_ids = array_values(array_diff($live_ids, $known_ids));

            if (!empty($new_ids)) {
                // New models detected — store names for badge tooltip, update known list.
                $new_labels = [];
                foreach ($new_ids as $new_id) {
                    $new_labels[$new_id] = $live_models[$new_id] ?? $new_id;
                }
                update_option(self::NEW_OPTION . $id, $new_labels, false);
                update_option(self::KNOWN_OPTION . $id, $live_ids, false);
            }
        }
    }

    // ---------------------------------------------------------------------------
    // Get new-model flag for a provider. Returns array of new model labels or [].
    // ---------------------------------------------------------------------------

    public static function getNewModels(string $provider_id): array
    {
        return (array) get_option(self::NEW_OPTION . $provider_id, []);
    }

    // ---------------------------------------------------------------------------
    // Clear new-model flag — called when user opens Change Model modal.
    // ---------------------------------------------------------------------------

    public static function clearNewModels(string $provider_id): void
    {
        delete_option(self::NEW_OPTION . $provider_id);
    }

    // ---------------------------------------------------------------------------
    // Initialize known model baseline for a provider (called on first activation).
    // ---------------------------------------------------------------------------

    public static function initBaseline(string $provider_id, array $model_ids): void
    {
        if (empty(get_option(self::KNOWN_OPTION . $provider_id))) {
            update_option(self::KNOWN_OPTION . $provider_id, $model_ids, false);
        }
    }

    // ---------------------------------------------------------------------------
    // Load all provider and image provider modules from disk.
    // ---------------------------------------------------------------------------

    private static function load_all_modules(): array
    {
        $modules_dir = AMAI_PLUGIN_DIR . 'modules/';
        $modules     = [];

        if (!is_dir($modules_dir)) {
            return $modules;
        }

        foreach (glob($modules_dir . '*.php') as $file) {
            if (!is_file($file)) {
                continue;
            }
            require_once $file;
            $basename = basename($file, '.php');

            // Resolve class name from file basename.
            if (str_starts_with($basename, 'ai-')) {
                $clean     = ucfirst(str_replace('-', '', substr($basename, 3)));
                $classname = 'AutoMarketerAI\\Modules\\' . $clean;
            } elseif (str_starts_with($basename, 'img-')) {
                $clean     = 'Img' . ucfirst(str_replace('-', '', substr($basename, 4)));
                $classname = 'AutoMarketerAI\\Modules\\' . $clean;
            } else {
                continue;
            }

            if (!class_exists($classname)) {
                continue;
            }

            $instance           = new $classname();
            $modules[$instance->get_id()] = $instance;
        }

        return $modules;
    }
}