<?php

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

class AIEO_Google_Reviews_Cron {

    const HOOK  = 'aieo_grv_refresh';
    const GROUP = 'aieo';

    private static $inited = false;

    
    public static function init() {
        if (self::$inited) { return; }
        self::$inited = true;
        add_action(self::HOOK, array(__CLASS__, 'run'));
        
        add_action('admin_init', array(__CLASS__, 'ensure_scheduled'));
    }

    
    public static function ensure_scheduled() {
        if (self::is_configured()) {
            if (!self::is_scheduled()) { self::schedule(); }
        } elseif (self::is_scheduled()) {
            self::unschedule();
        }
    }

    
    public static function reschedule() {
        self::unschedule();
        self::schedule();
    }

    public static function is_scheduled() {
        if (function_exists('as_next_scheduled_action')
            && false !== as_next_scheduled_action(self::HOOK, array(), self::GROUP)) {
            return true;
        }
        return (bool) wp_next_scheduled(self::HOOK);
    }

    public static function schedule() {
        
        
        
        if (!self::is_configured()) {
            return;
        }
        
        
        
        self::unschedule();

        $schedule = (string) AIEO_Google_Reviews_Settings::get('schedule', 'daily');
        $run_time = (string) AIEO_Google_Reviews_Settings::get('run_time', '03:30');
        $first    = self::next_run_timestamp($run_time);
        $interval = self::interval_seconds($schedule);

        if (function_exists('as_schedule_recurring_action')) {
            
            as_schedule_recurring_action($first, $interval, self::HOOK, array(), self::GROUP, true);
        } elseif (!wp_next_scheduled(self::HOOK)) {
            wp_schedule_event($first, self::wp_recurrence($schedule), self::HOOK);
        }
    }

    public static function unschedule() {
        if (function_exists('as_unschedule_all_actions')) {
            as_unschedule_all_actions(self::HOOK, array(), self::GROUP);
        }
        $ts = wp_next_scheduled(self::HOOK);
        while ($ts) {
            wp_unschedule_event($ts, self::HOOK);
            $ts = wp_next_scheduled(self::HOOK);
        }
    }

    
    public static function run() {
        self::maybe_load_services();
        
        
        if (!class_exists('AIEO_Google_Reviews_Fetcher') || !self::is_configured()) {
            return;
        }
        try {
            $totals = AIEO_Google_Reviews_Fetcher::fetch_all_enabled(true); 
        } catch (\Throwable $e) {
            $totals = array('error' => $e->getMessage());
        }
        update_option('aieo_grv_last_cron', array('at' => time(), 'totals' => $totals), false);
    }

    
    public static function is_configured() {
        self::maybe_load_services();
        if (!class_exists('AIEO_Google_Reviews_Locations') || !class_exists('AIEO_Google_Reviews_Settings')) {
            return false;
        }
        foreach (AIEO_Google_Reviews_Locations::list_all(true) as $loc) { 
            $key = AIEO_Google_Reviews_Settings::api_key_for_location($loc);
            $pid = (string) ($loc['place_id'] ?? '');
            if ($key !== '' && 0 === strpos($pid, 'ChIJ')) {
                return true;
            }
        }
        return false;
    }

    
    private static function maybe_load_services() {
        if (class_exists('AIEO_Google_Reviews_Fetcher') || !defined('AIEO_DIR')) {
            return;
        }
        $base = AIEO_DIR . 'includes/dmm/google-reviews/';
        foreach (array(
            'class-aieo-google-reviews-settings.php',
            'class-aieo-google-reviews-locations.php',
            'class-aieo-google-reviews-cache.php',
            'class-aieo-google-reviews-fetcher.php',
        ) as $f) {
            if (file_exists($base . $f)) { require_once $base . $f; }
        }
    }

    

    
    private static function interval_seconds($schedule) {
        switch ($schedule) {
            case 'twice_daily': return 12 * HOUR_IN_SECONDS;
            case 'weekly':      return WEEK_IN_SECONDS;
            case 'monthly':     return 30 * DAY_IN_SECONDS; 
            case 'daily':
            default:            return DAY_IN_SECONDS;
        }
    }

    
    private static function wp_recurrence($schedule) {
        switch ($schedule) {
            case 'twice_daily': return 'twicedaily';
            case 'weekly':      return 'weekly';
            case 'monthly':     return 'weekly'; 
            case 'daily':
            default:            return 'daily';
        }
    }

    
    private static function next_run_timestamp($run_time) {
        $h = 3; $m = 30;
        if (preg_match('/^([01]\d|2[0-3]):([0-5]\d)$/', (string) $run_time, $mm)) {
            $h = (int) $mm[1];
            $m = (int) $mm[2];
        }
        $tz   = function_exists('wp_timezone') ? wp_timezone() : new DateTimeZone('UTC');
        $now  = new DateTimeImmutable('now', $tz);
        $next = $now->setTime($h, $m, 0);
        if ($next <= $now) {
            $next = $next->modify('+1 day');
        }
        return $next->getTimestamp();
    }
}
