<?php

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

/**
 * Order Status Checker
 * 
 * Verifica automaticamente o status dos pedidos na API do provedor
 * e atualiza o status no WooCommerce quando completo
 */

class Upgram_Order_Status_Checker
{
    private static $instance = null;
    private $hook_name = 'upgram_check_order_status';
    private $recurring_hook = 'upgram_check_orders_status_recurring';
    private $action_group = 'upgram';

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

    private function __construct()
    {
        // Hook para verificar status de um pedido específico
        add_action($this->hook_name, array($this, 'check_single_order_status'), 10, 1);
        
        // Hook recorrente para verificar todos os pedidos em segundo plano (IMPORTANTE: garante verificações mesmo quando página é fechada)
        add_action($this->recurring_hook, array($this, 'check_all_orders_status'));
        
        // Hook quando pedido é criado/enviado para API
        add_action('upgram_order_sent_to_provider', array($this, 'register_order_for_checking'), 10, 3);
        
        // Hooks para reconfigurar agendamento quando configurações mudam
        add_action('update_option_upgram_enable_status_checker', array($this, 'handle_status_checker_toggle'), 10, 2);
        add_action('update_option_upgram_status_check_interval', array($this, 'handle_interval_change'), 10, 2);
        
        // Agendar verificações automáticas em segundo plano (garante que pedidos são verificados mesmo se página for fechada)
        // Usar 'wp_loaded' para garantir que Action Scheduler está inicializado
        add_action('wp_loaded', array($this, 'maybe_schedule_recurring_check'), 10);
        // Prioridade baixa (30) para emergency check rodar apenas se necessário, depois de tudo estar configurado
        add_action('wp_loaded', array($this, 'maybe_trigger_emergency_check'), 30);
    }

    /**
     * Verifica se o Action Scheduler está disponível e inicializado
     */
    private function is_action_scheduler_available()
    {
        if (!function_exists('as_schedule_recurring_action') || !class_exists('ActionScheduler')) {
            return false;
        }
        
        // Verificar se o data store está inicializado
        if (class_exists('ActionScheduler_Store')) {
            try {
                ActionScheduler_Store::instance();
                return true;
            } catch (Exception $e) {
                return false;
            }
        }
        
        return false;
    }

    /**
     * Agenda verificação recorrente se necessário
     * Método público para permitir chamada externa
     */
    public function maybe_schedule_recurring_check()
    {
        if (!get_option('upgram_enable_status_checker', true)) {
            // Se desativado, cancelar qualquer agendamento existente
            $this->unschedule_recurring_check();
            return;
        }

        $interval_seconds = $this->get_interval_seconds();
        $interval_minutes = max(1, intval($interval_seconds / MINUTE_IN_SECONDS));

        // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário
        $current_time = current_time('timestamp');
        $first_run = $current_time + max(30, min($interval_seconds, 300));

        // Verificar se Action Scheduler está disponível e inicializado
        if ($this->is_action_scheduler_available()) {
            // Tentar buscar agendamento com action_group primeiro
            $next_scheduled = as_next_scheduled_action($this->recurring_hook, array(), $this->action_group);
            
            // Se não encontrou com action_group, tentar sem (para compatibilidade)
            if (!$next_scheduled) {
                $next_scheduled = as_next_scheduled_action($this->recurring_hook);
            }

            // Se não há agendamento ou está no passado, criar novo
            // IMPORTANTE: Comparar com current_time('timestamp') que considera fuso horário
            $current_time = current_time('timestamp');
            if (!$next_scheduled || $next_scheduled <= $current_time) {
                // Limpar TODOS os agendamentos existentes (com e sem action_group)
                as_unschedule_all_actions($this->recurring_hook);
                
                // Criar novo agendamento recorrente
                // IMPORTANTE: as_schedule_recurring_action cria uma ação que se repete automaticamente
                // Mas garantimos que sempre há uma ação agendada verificando após cada execução
                $result = as_schedule_recurring_action($first_run, $interval_seconds, $this->recurring_hook, array(), $this->action_group);
                
                if ($result) {
                    error_log('Order status checker: Recurring check scheduled (Action Scheduler) - every ' . $interval_minutes . ' minutes - First run: ' . date('Y-m-d H:i:s', $first_run));
                    error_log('Order status checker: Action ID: ' . $result);
                    
                    // Verificar se foi realmente agendado
                    $verify = as_next_scheduled_action($this->recurring_hook, array(), $this->action_group);
                    if ($verify) {
                        error_log('Order status checker: ✓ Verified - Next check scheduled for: ' . date('Y-m-d H:i:s', $verify));
                        error_log('Order status checker: This is a RECURRING action that will repeat every ' . $interval_minutes . ' minutes');
                    } else {
                        error_log('Order status checker: ⚠ WARNING - Schedule created but verification failed');
                        // Tentar criar novamente sem action_group como fallback
                        as_unschedule_all_actions($this->recurring_hook);
                        $result2 = as_schedule_recurring_action($first_run, $interval_seconds, $this->recurring_hook);
                        if ($result2) {
                            error_log('Order status checker: ✓ Fallback schedule created successfully (without action_group)');
                        }
                    }
                } else {
                    error_log('Order status checker: ✗ ERROR - Failed to schedule recurring check with Action Scheduler');
                    // Tentar criar sem action_group como fallback
                    $result2 = as_schedule_recurring_action($first_run, $interval_seconds, $this->recurring_hook);
                    if ($result2) {
                        error_log('Order status checker: ✓ Fallback schedule created (without action_group)');
                    } else {
                        error_log('Order status checker: ✗ ERROR - Fallback schedule also failed');
                    }
                }
            } else {
                // Verificar se o intervalo está correto (tolerância de 60 segundos)
                // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário
                $current_time = current_time('timestamp');
                $expected_next = $current_time + $interval_seconds;
                $difference = abs($next_scheduled - $expected_next);
                
                if ($difference > 60) {
                    error_log('Order status checker: Interval mismatch detected (diff: ' . $difference . 's) - Rescheduling');
                    as_unschedule_all_actions($this->recurring_hook);
                    $result = as_schedule_recurring_action($first_run, $interval_seconds, $this->recurring_hook, array(), $this->action_group);
                    
                    if ($result) {
                        error_log('Order status checker: Recurring check rescheduled (Action Scheduler) - every ' . $interval_minutes . ' minutes');
                        error_log('Order status checker: Action ID: ' . $result);
                    } else {
                        error_log('Order status checker: ✗ ERROR - Failed to reschedule with Action Scheduler');
                        // Fallback sem action_group
                        $result2 = as_schedule_recurring_action($first_run, $interval_seconds, $this->recurring_hook);
                        if ($result2) {
                            error_log('Order status checker: ✓ Fallback reschedule successful');
                        }
                    }
                } else {
                    // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário
                    $current_time_for_diff = current_time('timestamp');
                    error_log('Order status checker: ✓ Already scheduled correctly - Next check: ' . date('Y-m-d H:i:s', $next_scheduled) . ' (in ' . human_time_diff($current_time_for_diff, $next_scheduled) . ')');
                    // Verificar se é uma ação recorrente (múltiplas ações futuras agendadas)
                    // Se houver apenas uma ação agendada, pode não ser recorrente
                    if (function_exists('as_get_scheduled_actions')) {
                        $all_actions = as_get_scheduled_actions(array(
                            'hook' => $this->recurring_hook,
                            'per_page' => 5,
                            'status' => 'pending'
                        ));
                        $action_count = is_array($all_actions) ? count($all_actions) : 0;
                        if ($action_count > 0) {
                            error_log('Order status checker: Found ' . $action_count . ' pending recurring action(s)');
                        } else {
                            error_log('Order status checker: ⚠ WARNING - No pending recurring actions found, but next scheduled exists. This might indicate a problem.');
                            // Tentar reagendar para garantir que há uma ação recorrente
                            error_log('Order status checker: Attempting to re-schedule to ensure recurring action...');
                            as_unschedule_all_actions($this->recurring_hook);
                            $result = as_schedule_recurring_action($first_run, $interval_seconds, $this->recurring_hook, array(), $this->action_group);
                            if ($result) {
                                error_log('Order status checker: ✓ Re-scheduled successfully');
                            }
                        }
                    }
                }
            }
        } else {
            $next_scheduled = wp_next_scheduled($this->recurring_hook);

            // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário
            $current_time = current_time('timestamp');
            if (!$next_scheduled || $next_scheduled <= $current_time) {
                // Limpar agendamento existente
                wp_clear_scheduled_hook($this->recurring_hook);
                
                // Criar novo agendamento
                $result = wp_schedule_event($first_run, 'upgram_custom_interval', $this->recurring_hook);
                
                if ($result !== false) {
                    error_log('Order status checker: Recurring check scheduled (WP-Cron) - every ' . $interval_minutes . ' minutes');
                } else {
                    error_log('Order status checker: ✗ ERROR - Failed to schedule recurring check with WP-Cron');
                }
            }

            // Verificar se foi agendado corretamente
            $verify_scheduled = wp_next_scheduled($this->recurring_hook);
            if (!$verify_scheduled) {
                error_log('Order status checker: ✗ ERROR - Failed to schedule recurring check with WP-Cron (verification failed)');
            } else {
                error_log('Order status checker: ✓ Verified - Next check scheduled for: ' . date('Y-m-d H:i:s', $verify_scheduled));
            }
        }
    }

    /**
     * Fallback para detectar quando cron não está rodando e reagendar verificações
     * IMPORTANTE: Este método NÃO deve interferir com agendamentos recorrentes regulares
     */
    public function maybe_trigger_emergency_check()
    {
        if (!get_option('upgram_enable_status_checker', true)) {
            return;
        }

        if (defined('DOING_CRON') && DOING_CRON) {
            return;
        }

        if (wp_doing_ajax()) {
            return;
        }

        // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário do WordPress
        $now = current_time('timestamp');
        $interval_seconds = $this->get_interval_seconds();
        $last_check = intval(get_option('_upgram_last_status_check_time', 0));
        $next_scheduled = $this->get_next_scheduled_time();

        // Verificar se há um agendamento recorrente válido primeiro
        $has_recurring = false;
        if ($this->is_action_scheduler_available()) {
            $recurring_next = as_next_scheduled_action($this->recurring_hook, array(), $this->action_group);
            if (!$recurring_next) {
                $recurring_next = as_next_scheduled_action($this->recurring_hook);
            }
            $has_recurring = ($recurring_next && $recurring_next > $now && $recurring_next <= ($now + ($interval_seconds * 3)));
        } else {
            $recurring_next = wp_next_scheduled($this->recurring_hook);
            $has_recurring = ($recurring_next && $recurring_next > $now && $recurring_next <= ($now + ($interval_seconds * 3)));
        }

        // Se existe agendamento recorrente válido, não fazer nada de emergência
        if ($has_recurring) {
            return;
        }

        // Se existe agendamento válido próximo (dentro de 2 intervalos), não fazer nada
        if ($next_scheduled && $next_scheduled >= $now && $next_scheduled <= ($now + ($interval_seconds * 2))) {
            return;
        }

        // Se ainda há verificação recente (dentro de 2 intervalos), aguardar
        if ($last_check && ($now - $last_check) <= ($interval_seconds * 2)) {
            return;
        }

        $lock_key = 'upgram_status_checker_emergency_lock';
        if (get_transient($lock_key)) {
            return;
        }

        // Se não há agendamento recorrente válido, tentar criar um primeiro antes de fazer verificação de emergência
        if (!$has_recurring) {
            error_log('Order status checker: No recurring schedule found, attempting to create one...');
            $this->maybe_schedule_recurring_check();
            
            // Aguardar um pouco e verificar novamente
            $recheck_next = $this->get_next_scheduled_time();
            if ($recheck_next && $recheck_next > $now) {
                error_log('Order status checker: Recurring schedule created successfully, skipping emergency check');
                return;
            }
        }

        set_transient($lock_key, $now, 60);

        $schedule_time = $now + 30;
        $ran_inline = false;

        // Executar verificação imediatamente apenas se não há agendamento próximo E passou muito tempo
        if (($now - $last_check) >= ($interval_seconds * 2)) {
            error_log('Order status checker: Emergency inline batch check triggered (last check: ' . ($last_check ? date('Y-m-d H:i:s', $last_check) : 'never') . ')');
            $ran_inline = true;
            $this->check_all_orders_status();
        }

        // Tentar criar agendamento recorrente novamente como último recurso
        if (!$has_recurring) {
            if ($this->is_action_scheduler_available()) {
                // Não criar ação única, apenas tentar criar recorrente
                as_unschedule_all_actions($this->recurring_hook);
                $first_run = $now + 30;
                as_schedule_recurring_action($first_run, $interval_seconds, $this->recurring_hook, array(), $this->action_group);
                error_log('Order status checker: Emergency recurring schedule created for ' . date('Y-m-d H:i:s', $first_run));
            } else {
                wp_clear_scheduled_hook($this->recurring_hook);
                $first_run = $now + 30;
                wp_schedule_event($first_run, 'upgram_custom_interval', $this->recurring_hook);
                error_log('Order status checker: Emergency recurring schedule created (WP-Cron) for ' . date('Y-m-d H:i:s', $first_run));
            }
        }

        error_log(
            sprintf(
                'Order status checker: Emergency check processed (inline executed: %s, has_recurring: %s).',
                $ran_inline ? 'yes' : 'no',
                $has_recurring ? 'yes' : 'no'
            )
        );
    }

    /**
     * Registra pedido para verificação de status
     */
    public function register_order_for_checking($order_id, $provider_order_id, $provider_index = null)
    {
        if (!get_option('upgram_enable_status_checker', true)) {
            return;
        }

        $order = wc_get_order($order_id);
        if (!$order) {
            return;
        }

        // Se provider_index foi fornecido, salvar no pedido
        if ($provider_index !== null) {
            $existing_index = $order->get_meta('_upgram_provider_index');
            if (empty($existing_index)) {
                $order->update_meta_data('_upgram_provider_index', $provider_index);
            }
        }

        // Salvar ID do pedido no provedor (apenas se não existir um principal)
        // Como pedidos podem ter múltiplos provider_order_ids, não sobrescrevemos
        $existing_provider_order_id = $order->get_meta('_upgram_provider_order_id');
        if (empty($existing_provider_order_id)) {
            $order->update_meta_data('_upgram_provider_order_id', $provider_order_id);
        }
        
        $existing_last_check = $order->get_meta('_upgram_last_status_check');
        if (empty($existing_last_check)) {
            // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário
            $order->update_meta_data('_upgram_last_status_check', current_time('timestamp'));
            $order->update_meta_data('_upgram_provider_status', 'Pending');
            $order->update_meta_data('_upgram_status_check_count', 0);
        }
        
        $order->save();
        
        // Invalidar cache dos pedidos recentes
        wp_cache_delete('upgram_recent_orders_5', 'upgram_stats');

        error_log(sprintf('Order #%d registered for status checking (Provider Order ID: %s, Provider Index: %s)', 
            $order_id, $provider_order_id, $provider_index));

        // Garantir que haverá uma verificação agendada em breve (primeira verificação após 90 segundos)
        $this->schedule_single_order_check($order_id, 90);
        
        // Garantir que o agendamento recorrente global está ativo
        $this->maybe_schedule_recurring_check();
    }

    /**
     * Verifica status de todos os pedidos pendentes
     */
    public function check_all_orders_status()
    {
        if (!get_option('upgram_enable_status_checker', true)) {
            error_log('Order status checker: Disabled, skipping check');
            return;
        }

        error_log('========== Order status checker: Starting batch check ==========');
        
        // Buscar pedidos que têm provider_order_id
        // IMPORTANTE: Incluir pedidos com status 'processing', 'pending', 'on-hold' E também 'completed' 
        // (para verificar se há pedidos que foram marcados como completos mas ainda têm verificações pendentes)
        // Mas excluir pedidos que já foram completamente processados e não precisam mais de verificação
        
        $orders_by_id = array();
        
        // Estratégia 1: Buscar pedidos com provider_order_id no meta do pedido
        // IMPORTANTE: Usar meta_key ao invés de meta_query para compatibilidade com WooCommerce 9.2.0+
        // Incluir mais status para garantir que não perdemos pedidos
        $args = array(
            'status' => array('processing', 'pending', 'on-hold', 'completed'),
            'limit' => 200, // Aumentar limite significativamente
            'meta_key' => '_upgram_provider_order_id',
            'orderby' => 'date',
            'order' => 'DESC', // Mais recentes primeiro
        );

        try {
            $orders_with_meta = wc_get_orders($args);
            if (!is_array($orders_with_meta)) {
                $orders_with_meta = array();
            }
        } catch (Exception $e) {
            error_log('Order status checker: Error fetching orders with meta_key - ' . $e->getMessage());
            $orders_with_meta = array();
        }
        
        error_log(sprintf('Order status checker: Found %d orders with _upgram_provider_order_id in order meta', count($orders_with_meta)));
        
        foreach ($orders_with_meta as $order) {
            $orders_by_id[$order->get_id()] = $order;
        }
        
        // Estratégia 2: Buscar TODOS os pedidos com status relevantes e verificar nos itens
        // Isso garante que não perdemos pedidos que têm provider_order_id apenas nos itens
        $args_all = array(
            'status' => array('processing', 'pending', 'on-hold', 'completed'),
            'limit' => 200,
            'orderby' => 'date',
            'order' => 'DESC',
        );
        
        try {
            $all_orders = wc_get_orders($args_all);
            if (!is_array($all_orders)) {
                $all_orders = array();
            }
        } catch (Exception $e) {
            error_log('Order status checker: Error fetching all orders - ' . $e->getMessage());
            $all_orders = array();
        }
        
        error_log(sprintf('Order status checker: Checking %d total orders for provider_order_id in items', count($all_orders)));
        
        $found_in_items = 0;
        
        // Verificar pedidos que têm provider_order_id nos itens
        foreach ($all_orders as $order) {
            if (isset($orders_by_id[$order->get_id()])) {
                continue; // Já foi adicionado
            }
            
            // Verificar se tem provider_order_id nos itens
            $items = $order->get_items();
            $has_provider_order = false;
            
            foreach ($items as $item_id => $item) {
                // Verificar se tem links (para pedidos com múltiplos links)
                $links = $item->get_meta('_link', false);
                if (!empty($links) && is_array($links)) {
                    foreach ($links as $link_index => $link_item) {
                        $provider_order_id = wc_get_order_item_meta($item_id, "_provider_order_id_$link_index", true);
                        if (!empty($provider_order_id)) {
                            $has_provider_order = true;
                            break 2; // Sair de ambos os loops
                        }
                    }
                }
                
                // Verificar também provider_order_id sem índice (pedidos antigos)
                if (!$has_provider_order) {
                    $provider_order_id = $item->get_meta('_upgram_provider_order_id');
                    if (empty($provider_order_id)) {
                        $provider_order_id = $item->get_meta('_provider_order_id');
                    }
                    if (!empty($provider_order_id)) {
                        $has_provider_order = true;
                        break;
                    }
                }
            }
            
            if ($has_provider_order) {
                $orders_by_id[$order->get_id()] = $order;
                $found_in_items++;
            }
        }
        
        error_log(sprintf('Order status checker: Found %d additional orders with provider_order_id in items', $found_in_items));
        
        // Filtrar pedidos que já foram completamente processados e não precisam mais verificação
        // (pedidos completos que não têm mais nenhum item pendente)
        $orders_to_check = array();
        foreach ($orders_by_id as $order_id => $order) {
            // Se o pedido está completo, verificar se ainda há itens pendentes
            if ($order->get_status() === 'completed') {
                $provider_orders = $this->get_all_provider_orders_from_order($order);
                if (!empty($provider_orders)) {
                    // Verificar se algum item ainda não está completo
                    $has_pending = false;
                    foreach ($provider_orders as $provider_order) {
                        $item_id = isset($provider_order['item_id']) ? $provider_order['item_id'] : 0;
                        $link_index = isset($provider_order['link_index']) ? $provider_order['link_index'] : 0;
                        $status_key = $link_index > 0 ? "_provider_status_$link_index" : "_provider_status";
                        $item_status = $item_id > 0 ? wc_get_order_item_meta($item_id, $status_key, true) : $order->get_meta($status_key);
                        
                        if (empty($item_status) || !in_array(strtolower(trim($item_status)), array('completed', 'complete', 'finished', 'done'))) {
                            $has_pending = true;
                            break;
                        }
                    }
                    
                    if ($has_pending) {
                        $orders_to_check[] = $order;
                    }
                }
            } else {
                // Pedidos não completos sempre devem ser verificados
                $orders_to_check[] = $order;
            }
        }
        
        $orders = $orders_to_check;

        if (empty($orders)) {
            error_log('Order status checker: No orders to check (all orders are fully processed or have no provider_order_id)');
            // Mesmo sem pedidos, atualizar timestamp e garantir próxima verificação
            // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário
            update_option('_upgram_last_status_check_time', current_time('timestamp'));
            $this->maybe_schedule_recurring_check();
            return;
        }

        error_log(sprintf('Order status checker: Found %d orders to check (after filtering)', count($orders)));

        $checked_count = 0;
        $completed_count = 0;
        
        foreach ($orders as $order) {
            $old_status = $order->get_status();
            $this->check_single_order_status($order->get_id());
            
            // Reload para verificar se status mudou
            $order->read_meta_data(true);
            $new_status = $order->get_status();
            
            $checked_count++;
            if ($old_status !== 'completed' && $new_status === 'completed') {
                $completed_count++;
            }
        }

        error_log(sprintf('Order status checker: Checked %d orders, %d completed', $checked_count, $completed_count));
        
        // Atualizar timestamp da última verificação global (garantir que seja atualizado)
        // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário do WordPress
        $check_time = current_time('timestamp');
        $check_time_formatted = current_time('mysql');
        update_option('_upgram_last_status_check_time', $check_time);
        error_log(sprintf('[%s] Order status checker: Global last check time updated', $check_time_formatted));
        
        // CRÍTICO: Garantir que a próxima verificação recorrente está agendada
        // Isso previne que o sistema pare de verificar após a primeira execução
        // IMPORTANTE: Action Scheduler deve criar automaticamente a próxima ação recorrente,
        // mas vamos verificar e garantir que está funcionando corretamente
        
        $next_scheduled = $this->get_next_scheduled_time();
        $interval_seconds = $this->get_interval_seconds();
        $expected_next = $check_time + $interval_seconds;
        
        // Verificar se há ações recorrentes agendadas
        $has_recurring_actions = false;
        $action_count = 0;
        if ($this->is_action_scheduler_available()) {
            $all_actions = as_get_scheduled_actions(array(
                'hook' => $this->recurring_hook,
                'per_page' => 10,
                'status' => 'pending'
            ));
            $has_recurring_actions = !empty($all_actions) && count($all_actions) > 0;
            $action_count = $has_recurring_actions ? count($all_actions) : 0;
            error_log(sprintf('Order status checker: Found %d pending recurring action(s)', $action_count));
        }
        
        // Se não há agendamento próximo ou está muito longe, reagendar
        if (!$next_scheduled || $next_scheduled > ($expected_next + 60) || $next_scheduled < $check_time || !$has_recurring_actions) {
            error_log('Order status checker: ⚠ WARNING - Next scheduled check is missing, invalid, or no recurring actions found - re-scheduling...');
            error_log(sprintf('Order status checker: Current time: %s | Expected next: %s | Actual next: %s | Has recurring: %s', 
                date('Y-m-d H:i:s', $check_time),
                date('Y-m-d H:i:s', $expected_next),
                $next_scheduled ? date('Y-m-d H:i:s', $next_scheduled) : 'NONE',
                $has_recurring_actions ? 'yes' : 'no'
            ));
            
            // Reagendar verificação recorrente
            $this->maybe_schedule_recurring_check();
            
            // Verificar novamente após reagendar
            $new_next = $this->get_next_scheduled_time();
            $new_action_count = 0;
            if ($this->is_action_scheduler_available()) {
                $new_actions = as_get_scheduled_actions(array(
                    'hook' => $this->recurring_hook,
                    'per_page' => 5,
                    'status' => 'pending'
                ));
                $new_has_recurring = !empty($new_actions) && count($new_actions) > 0;
                $new_action_count = $new_has_recurring ? count($new_actions) : 0;
                error_log(sprintf('Order status checker: After re-schedule - Next: %s | Recurring actions: %d', 
                    $new_next ? date('Y-m-d H:i:s', $new_next) : 'NONE',
                    $new_action_count
                ));
            }
            
            if ($new_next) {
                error_log(sprintf('Order status checker: ✓ Re-scheduled successfully - Next check: %s', 
                    date('Y-m-d H:i:s', $new_next)));
            } else {
                error_log('Order status checker: ✗ ERROR - Failed to re-schedule after batch check');
            }
        } else {
            error_log(sprintf('Order status checker: ✓ Next check already scheduled: %s (in %s) | Recurring actions: %d', 
                date('Y-m-d H:i:s', $next_scheduled),
                human_time_diff($check_time, $next_scheduled),
                $action_count
            ));
        }
        
        error_log('========== Order status checker: Batch check finished ==========');
    }

    /**
     * Verifica o status de um pedido específico
     */
    public function check_single_order_status($order_id)
    {
        $order = wc_get_order($order_id);
        if (!$order) {
            error_log(sprintf('Order #%d not found for status checking', $order_id));
            return;
        }

        // Verificar se pedido já foi concluído ou cancelado
        $current_status = $order->get_status();
        if (in_array($current_status, array('completed', 'cancelled', 'refunded', 'failed'))) {
            error_log(sprintf('Order #%d already finalized (%s), skipping status check', $order_id, $current_status));
            $this->unschedule_single_order_check($order_id);
            return;
        }

        // Verificar se atingiu o limite de verificações
        $limit_reached = $order->get_meta('_upgram_status_check_limit_reached');
        if ($limit_reached) {
            error_log(sprintf('Order #%d - Check limit reached, skipping automatic verification', $order_id));
            $this->unschedule_single_order_check($order_id);
            return;
        }
        
        // Verificar limite antes de verificar
        $max_check_count = get_option('upgram_status_check_max_count', '');
        $max_check_count = !empty($max_check_count) ? intval($max_check_count) : 0;
        
        if ($max_check_count > 0) {
            $current_check_count = intval($order->get_meta('_upgram_status_check_count'));
            if ($current_check_count >= $max_check_count) {
                error_log(sprintf('Order #%d - Maximum check count already reached (%d/%d), skipping check', 
                    $order_id, $current_check_count, $max_check_count));
                $this->unschedule_single_order_check($order_id);
                $order->update_meta_data('_upgram_status_check_limit_reached', true);
                $order->save();
                return;
            }
        }

        // Buscar TODOS os provider_order_ids de todos os itens do pedido
        // Cada item pode ter múltiplos links, cada link pode ter um provider_order_id diferente
        $order_items_with_providers = $this->get_all_provider_orders_from_order($order);
        
        if (empty($order_items_with_providers)) {
            error_log(sprintf('Order #%d has no provider order IDs in items, skipping', $order_id));
            $this->schedule_single_order_check($order_id, $this->get_retry_delay_seconds());
            return;
        }

        error_log(sprintf('Order #%d found %d provider orders to check (Interval: %d minutos)', 
            $order_id, count($order_items_with_providers), get_option('upgram_status_check_interval', 2)));

        $all_completed = true;
        $any_error = false;
        $completed_count = 0;
        $total_checked = 0;
        
        // Verificar status de cada provider_order_id no seu provedor correto
        foreach ($order_items_with_providers as $item_info) {
            $provider_order_id = $item_info['provider_order_id'];
            $provider_index = $item_info['provider_index'];
            $item_id = $item_info['item_id'];
            $link_index = $item_info['link_index'];
            
            error_log(sprintf('Order #%d - Checking provider_order_id: %s with provider_index: %s', 
                $order_id, $provider_order_id, $provider_index ?: 'EMPTY/NULL'));

            // Obter informações do provedor específico
            $provider_info = null;
            
            $status_info = null;
            
            // Se provider_index está vazio, tentar detectar testando todos os provedores
            $provider_api_url = isset($item_info['provider_api_url']) ? $item_info['provider_api_url'] : null;
            $provider_info = null;
            $status_info = null;
            $providers = get_option('upgram_providers', []);
            $has_provider_index = ($provider_index !== null && $provider_index !== '' && $provider_index !== false);

            if ($has_provider_index) {
                $provider_info = $this->get_provider_info_by_index($provider_index, $provider_api_url);

                if ($provider_info) {
                    $resolved_index = isset($provider_info['__index']) ? $provider_info['__index'] : $provider_index;
                    $provider_api_url = $provider_info['api_url'] ?? $provider_api_url;

                    if ((string)$resolved_index !== (string)$provider_index) {
                        if ($item_id > 0) {
                            wc_update_order_item_meta($item_id, "_provider_index_$link_index", $resolved_index);
                        } else {
                            $order->update_meta_data('_upgram_provider_index', $resolved_index);
                            $order->save();
                        }
                        $provider_index = $resolved_index;
                    }

                    if (!empty($provider_api_url)) {
                        if ($item_id > 0) {
                            wc_update_order_item_meta($item_id, "_provider_api_url_$link_index", $provider_api_url);
                        } else {
                            $order->update_meta_data('_upgram_provider_api_url', $provider_api_url);
                            $order->save();
                        }
                    }

                    $status_info = $this->query_provider_status($provider_order_id, $provider_info);
                } else {
                    error_log(sprintf('Order #%d - Provider index %s not found; attempting auto-detection for provider_order_id %s', 
                        $order_id, $provider_index, $provider_order_id));
                    $has_provider_index = false;
                    $provider_index = null;
                }
            }

            if (!$has_provider_index) {
                if (empty($providers)) {
                    error_log(sprintf('Order #%d - ✗ No providers configured to test', $order_id));
                    $any_error = true;
                    continue;
                }

                $provider_candidates = $providers;
                if (!empty($provider_api_url)) {
                    $filtered_candidates = array();
                    foreach ($providers as $candidate_index => $candidate_provider) {
                        if (isset($candidate_provider['api_url']) && $this->normalize_api_url($candidate_provider['api_url']) === $this->normalize_api_url($provider_api_url)) {
                            $filtered_candidates[$candidate_index] = $candidate_provider;
                        }
                    }
                    if (!empty($filtered_candidates)) {
                        $provider_candidates = $filtered_candidates;
                    }
                }

                $found_provider = false;
                foreach ($provider_candidates as $test_index => $test_provider) {
                    error_log(sprintf('Order #%d - Testing provider index %s (name: %s, URL: %s) for order %s', 
                        $order_id, $test_index, $test_provider['name'] ?? 'Unknown', $test_provider['api_url'] ?? 'N/A', $provider_order_id));

                    $test_status_info = $this->query_provider_status($provider_order_id, $test_provider);

                    if ($test_status_info && !is_wp_error($test_status_info)) {
                        $provider_index = $test_index;
                        $provider_info = $test_provider;
                        $provider_api_url = $test_provider['api_url'] ?? $provider_api_url;
                        $found_provider = true;

                        if ($item_id > 0) {
                            wc_update_order_item_meta($item_id, "_provider_index_$link_index", $provider_index);
                            if (!empty($provider_api_url)) {
                                wc_update_order_item_meta($item_id, "_provider_api_url_$link_index", $provider_api_url);
                            }
                            error_log(sprintf('Order #%d - ✓ Detected and saved provider_index %s for provider_order_id %s (provider: %s)', 
                                $order_id, $provider_index, $provider_order_id, $test_provider['name'] ?? 'Unknown'));
                        } else {
                            $order->update_meta_data('_upgram_provider_index', $provider_index);
                            if (!empty($provider_api_url)) {
                                $order->update_meta_data('_upgram_provider_api_url', $provider_api_url);
                            }
                            $order->save();
                            error_log(sprintf('Order #%d - ✓ Detected and saved provider_index %s in order meta for provider_order_id %s (provider: %s)', 
                                $order_id, $provider_index, $provider_order_id, $test_provider['name'] ?? 'Unknown'));
                        }

                        $status_info = $test_status_info;
                        break;
                    } else {
                        $error_msg = is_wp_error($test_status_info) ? $test_status_info->get_error_message() : 'Unknown error';
                        error_log(sprintf('Order #%d - ✗ Provider index %s returned error for order %s: %s', 
                            $order_id, $test_index, $provider_order_id, $error_msg));
                    }
                }

                if (!$found_provider) {
                    error_log(sprintf('Order #%d - ✗ Could not detect provider for provider_order_id %s after testing %d providers', 
                        $order_id, $provider_order_id, count($provider_candidates)));
                    $any_error = true;
                    continue;
                }
            }

            if (!$provider_info) {
                $provider_info = $this->get_provider_info_by_index($provider_index, $provider_api_url);
                if (!$provider_info) {
                    error_log(sprintf('Order #%d - ✗ Unable to resolve provider info for order %s even after detection', 
                        $order_id, $provider_order_id));
                    $any_error = true;
                    continue;
                }
            }

            if (!$status_info) {
                $status_info = $this->query_provider_status($provider_order_id, $provider_info);
            }
            
            // Atualizar última verificação do pedido sempre que verificar (mesmo se der erro)
            // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário do WordPress
            $order->update_meta_data('_upgram_last_status_check', current_time('timestamp'));
            
            if ($status_info && !is_wp_error($status_info)) {
                $total_checked++;
                $this->clear_provider_error_meta($order, $provider_order_id, $item_id, $link_index);

                $provider_status = $status_info['status'];
                error_log(sprintf('Order #%d - Provider order %s status: %s, charge=%s, remains=%s', 
                    $order_id,
                    $provider_order_id,
                    $provider_status, 
                    isset($status_info['charge']) ? $status_info['charge'] : 'N/A',
                    isset($status_info['remains']) ? $status_info['remains'] : 'N/A'
                ));
                
                // Salvar status do provider_order_id específico no item
                wc_update_order_item_meta($item_id, "_provider_status_$link_index", $provider_status);
                if (isset($status_info['start_count']) && !empty($status_info['start_count'])) {
                    wc_update_order_item_meta($item_id, "_provider_start_count_$link_index", $status_info['start_count']);
                }
                // Salvar remains também no item para fácil acesso
                if (isset($status_info['remains']) && $status_info['remains'] !== '') {
                    wc_update_order_item_meta($item_id, "_provider_remains_$link_index", $status_info['remains']);
                }
                
                // Invalidar cache dos pedidos recentes para que os status sejam atualizados na página do produto
                wp_cache_delete('upgram_recent_orders_5', 'upgram_stats');
                
                // Verificar se status indica cancelamento
                $cancelled_statuses = array(
                    'cancelled', 'canceled', 'cancel', 'refunded'
                );
                
                $is_cancelled = in_array(strtolower(trim($provider_status)), $cancelled_statuses);
                
                // Se status é cancelado, marcar pedido como "Provedor Cancelado"
                if ($is_cancelled) {
                    error_log(sprintf('Order #%d - Provider order %s cancelled! (Status: %s) - Marking order as Provider Cancelled', 
                        $order_id, $provider_order_id, $provider_status));
                    
                    // Marcar pedido como "Provedor Cancelado"
                    if (function_exists('upgram_set_order_provider_cancelled_status')) {
                        upgram_set_order_provider_cancelled_status($order);
                    }
                    
                    // Incrementar contador de verificados mas não marcar como completo
                    $total_checked++;
                    // Não incrementar completed_count pois foi cancelado
                    $all_completed = false;
                    
                    // Continuar verificando outros itens do pedido, mas este item está cancelado
                    continue;
                }
                
                // Verificar se status indica conclusão (mais flexível)
                $completed_statuses = array(
                    'completed', 'complete', 'finished', 'done', 'delivered', 
                    'finalized', 'processed', 'success', 'successful'
                );
                
                // Normalizar status para comparação (pode vir como string, número, etc)
                $provider_status_normalized = is_string($provider_status) ? $provider_status : (string) $provider_status;
                $provider_status_lower = strtolower(trim($provider_status_normalized));
                
                $is_completed = in_array($provider_status_lower, $completed_statuses);
                
                // Verificar também se remains é 0 (indica conclusão)
                $remains = isset($status_info['remains']) ? $status_info['remains'] : null;
                // Converter remains para número (pode vir como string "0" ou número 0)
                $remains_int = ($remains !== null && $remains !== '') ? intval($remains) : -1;
                $is_completed_by_remains = ($remains_int === 0);
                
                error_log(sprintf('Order #%d - Provider order %s completion check: Status="%s" (normalized="%s", lower="%s"), is_completed=%s, Remains=%s (int=%d), is_completed_by_remains=%s', 
                    $order_id, 
                    $provider_order_id,
                    var_export($provider_status, true),
                    $provider_status_normalized,
                    $provider_status_lower,
                    $is_completed ? 'true' : 'false',
                    var_export($remains, true),
                    $remains_int,
                    $is_completed_by_remains ? 'true' : 'false'
                ));
                
                // Verificar também se já estava marcado como completo anteriormente
                $previous_status = wc_get_order_item_meta($item_id, "_provider_status_$link_index", true);
                $previous_remains = wc_get_order_item_meta($item_id, "_provider_remains_$link_index", true);
                $was_already_completed = false;
                
                if (!empty($previous_status)) {
                    $was_already_completed = in_array(strtolower(trim($previous_status)), $completed_statuses);
                }
                
                // Verificar também pelo remains anterior (mesmo que status atual dê erro, se remains era 0, estava completo)
                if (!$was_already_completed && $previous_remains !== '' && $previous_remains !== null && intval($previous_remains) === 0) {
                    $was_already_completed = true;
                    error_log(sprintf('Order #%d - Provider order %s was already completed (previous remains was 0)', 
                        $order_id, $provider_order_id));
                }
                
                $item_is_completed = ($is_completed || $is_completed_by_remains || $was_already_completed);
                
                if ($item_is_completed) {
                    $completed_count++;
                    error_log(sprintf('Order #%d - ✓ Provider order %s completed! (Status: %s, Remains: %s, Already completed: %s, is_completed=%s, is_completed_by_remains=%s)', 
                        $order_id, 
                        $provider_order_id, 
                        $provider_status, 
                        $remains, 
                        $was_already_completed ? 'yes' : 'no',
                        $is_completed ? 'true' : 'false',
                        $is_completed_by_remains ? 'true' : 'false'
                    ));
                } else {
                    $all_completed = false;
                    error_log(sprintf('Order #%d - ✗ Provider order %s not completed yet (Status: %s (lower: %s), Remains: %s (int: %d), is_completed=%s, is_completed_by_remains=%s)', 
                        $order_id, 
                        $provider_order_id, 
                        $provider_status,
                        $provider_status_lower,
                        $remains,
                        $remains_int,
                        $is_completed ? 'true' : 'false',
                        $is_completed_by_remains ? 'true' : 'false'
                    ));
                }
            } else {
                $error_message = is_wp_error($status_info) ? $status_info->get_error_message() : 'Erro desconhecido';
                $error_code = is_wp_error($status_info) ? $status_info->get_error_code() : 'unknown';
                error_log(sprintf('Order #%d - Provider order %s check failed: %s', 
                    $order_id, $provider_order_id, $error_message));
                
                // Verificar se já estava completo antes do erro (não impedir conclusão se já estava completo)
                $previous_status = wc_get_order_item_meta($item_id, "_provider_status_$link_index", true);
                $previous_remains = wc_get_order_item_meta($item_id, "_provider_remains_$link_index", true);
                $was_already_completed = false;
                
                if (!empty($previous_status)) {
                    $completed_statuses = array(
                        'completed', 'complete', 'finished', 'done', 'delivered', 
                        'finalized', 'processed', 'success', 'successful'
                    );
                    $was_already_completed = in_array(strtolower(trim($previous_status)), $completed_statuses);
                    if (!$was_already_completed && $previous_remains !== '' && $previous_remains !== null && intval($previous_remains) === 0) {
                        $was_already_completed = true;
                    }
                }
                
                if ($was_already_completed) {
                    $completed_count++;
                    $total_checked++;
                    error_log(sprintf('Order #%d - Provider order %s was already completed before error, counting as completed', 
                        $order_id, $provider_order_id));
                } else {
                    $this->store_provider_error_meta(
                        $order,
                        $provider_order_id,
                        $provider_index,
                        $error_code,
                        $error_message,
                        $item_id,
                        $link_index
                    );
                    $any_error = true;
                }
            }
        }
        
        // Verificar limite de verificações
        $max_check_count = get_option('upgram_status_check_max_count', '');
        $max_check_count = !empty($max_check_count) ? intval($max_check_count) : 0; // 0 = ilimitado
        
        // Atualizar meta data do pedido
        // Buscar contagem atual (garantir que seja um número válido)
        $current_check_count = intval($order->get_meta('_upgram_status_check_count'));
        if ($current_check_count < 0) {
            $current_check_count = 0;
        }
        $check_count = $current_check_count + 1;
        // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário do WordPress
        $last_check_time = current_time('timestamp');
        $last_check_time_formatted = current_time('mysql');
        
        error_log(sprintf('[%s] Order #%d - Updating meta data: check_count=%d (was %d), last_check=%d, max_limit=%s', 
            $last_check_time_formatted, $order_id, $check_count, $current_check_count, $last_check_time, $max_check_count > 0 ? $max_check_count : 'unlimited'));
        
        // Garantir que última verificação está atualizada (pode ter sido atualizada durante loop, mas garantir aqui também)
        if (!$order->get_meta('_upgram_last_status_check')) {
            $order->update_meta_data('_upgram_last_status_check', $last_check_time);
        }
        $order->update_meta_data('_upgram_status_check_count', $check_count);
        
        // Verificar se atingiu o limite de verificações
        if ($max_check_count > 0 && $check_count >= $max_check_count) {
            error_log(sprintf('Order #%d - Maximum check count reached (%d/%d). Stopping automatic verification.', 
                $order_id, $check_count, $max_check_count));
            
            // Cancelar agendamento individual deste pedido
            $this->unschedule_single_order_check($order_id);
            
            // Adicionar nota ao pedido
            $order->add_order_note(sprintf(
                'Verificação automática interrompida: atingido limite de %d verificações. Verifique manualmente se necessário.',
                $max_check_count
            ));
            
            // Marcar que atingiu o limite
            $order->update_meta_data('_upgram_status_check_limit_reached', true);
            $order->update_meta_data('_upgram_status_check_limit_reached_at', $last_check_time);
        }
        
        // Atualizar status geral do pedido (usar status do primeiro item para referência)
        if (!empty($order_items_with_providers)) {
            $first_item = $order_items_with_providers[0];
            $first_item_obj = $order->get_item($first_item['item_id']);
            if ($first_item_obj) {
                $first_status = wc_get_order_item_meta($first_item_obj->get_id(), "_provider_status_" . $first_item['link_index'], true);
                if (!empty($first_status)) {
                    $order->update_meta_data('_upgram_provider_status', $first_status);
                }
            }
        }
        
        $order->save();
        
        // Invalidar cache dos pedidos recentes para atualizar status na página do produto
        wp_cache_delete('upgram_recent_orders_5', 'upgram_stats');
        
        // Verificar conclusão: todos os provider orders verificados com sucesso devem estar completos
        // Se alguns já estavam completos antes de um erro, ainda consideramos como completo
        $total_provider_orders = count($order_items_with_providers);
        
        // Buscar todos os provider orders que já foram marcados como completos anteriormente
        $previously_completed_count = 0;
        $completed_statuses = array(
            'completed', 'complete', 'finished', 'done', 'delivered', 
            'finalized', 'processed', 'success', 'successful'
        );
        
        foreach ($order_items_with_providers as $item_info) {
            $check_item_id = $item_info['item_id'];
            $check_link_index = $item_info['link_index'];
            $check_provider_order_id = $item_info['provider_order_id'];
            
            // Verificar se já estava marcado como completo anteriormente
            $prev_status = wc_get_order_item_meta($check_item_id, "_provider_status_$check_link_index", true);
            $prev_remains = wc_get_order_item_meta($check_item_id, "_provider_remains_$check_link_index", true);
            
            $is_prev_completed = false;
            
            if (!empty($prev_status)) {
                $prev_status_lower = strtolower(trim($prev_status));
                if (in_array($prev_status_lower, $completed_statuses)) {
                    $is_prev_completed = true;
                }
            }
            
            // Verificar também pelo remains (se remains era 0, estava completo)
            if (!$is_prev_completed && $prev_remains !== '' && $prev_remains !== null && intval($prev_remains) === 0) {
                $is_prev_completed = true;
            }
            
            if ($is_prev_completed) {
                $previously_completed_count++;
                error_log(sprintf('Order #%d - Provider order %s was previously completed (Status: %s, Remains: %s)', 
                    $order_id, $check_provider_order_id, $prev_status ?: 'N/A', $prev_remains ?: 'N/A'));
            }
        }
        
        // Contar total de completos: os verificados agora + os que já estavam completos antes
        $total_completed = $completed_count;
        // Adicionar os que já estavam completos mas não foram verificados nesta rodada
        $not_checked_but_completed = $previously_completed_count - $completed_count;
        if ($not_checked_but_completed > 0) {
            $total_completed = max($completed_count, $previously_completed_count);
            error_log(sprintf('Order #%d - Found %d previously completed provider orders that were not checked in this round', 
                $order_id, $not_checked_but_completed));
        }
        
        // Verificar se todos os provider orders verificados com sucesso estão completos
        $all_verified_completed = ($total_checked > 0 && $completed_count === $total_checked);
        
        // Se todos os provider orders foram verificados e todos estão completos
        $all_providers_completed = ($total_checked === $total_provider_orders && $completed_count === $total_provider_orders);
        
        // Se todos estão completos (verificados agora ou já estavam completos antes), marcar como completo
        $all_providers_are_completed = ($total_completed >= $total_provider_orders);
        
        // Log detalhado para debug
        error_log(sprintf('Order #%d - Completion check summary: total_provider_orders=%d, completed_count=%d, total_checked=%d, previously_completed_count=%d, total_completed=%d, all_providers_completed=%s, all_verified_completed=%s, all_providers_are_completed=%s', 
            $order_id,
            $total_provider_orders,
            $completed_count,
            $total_checked,
            $previously_completed_count,
            $total_completed,
            $all_providers_completed ? 'true' : 'false',
            $all_verified_completed ? 'true' : 'false',
            $all_providers_are_completed ? 'true' : 'false'
        ));
        
        // Verificar condições para marcar como completo
        $should_complete = false;
        $completion_reason = '';
        
        if ($all_providers_completed) {
            $should_complete = true;
            $completion_reason = 'all_providers_completed';
        } elseif ($all_verified_completed && $total_checked === $total_provider_orders) {
            $should_complete = true;
            $completion_reason = 'all_verified_completed';
        } elseif ($all_providers_are_completed) {
            $should_complete = true;
            $completion_reason = 'all_providers_are_completed';
        }
        
        if ($should_complete) {
            error_log(sprintf('Order #%d - ✓ All provider orders completed! (Reason: %s, Completed: %d/%d checked, Previously completed: %d, Total completed: %d/%d) Marking order as completed.', 
                $order_id, 
                $completion_reason,
                $completed_count, 
                $total_checked, 
                $previously_completed_count, 
                $total_completed, 
                $total_provider_orders));
            
            // Criar status_info consolidado para complete_order
            $status_info = array(
                'status' => 'Completed',
                'charge' => '',
                'start_count' => '',
                'remains' => 0
            );
            
            $this->complete_order($order, $status_info);
        } else {
            // Calcular se todos estão completos baseado na lógica acima
            $calculated_all_completed = ($total_completed >= $total_provider_orders);
            
            error_log(sprintf('Order #%d - ✗ Not all provider orders completed yet (Completed: %d/%d checked, Previously completed: %d, Total completed: %d/%d, all_providers_are_completed=%s, any_error=%s)', 
                $order_id, 
                $completed_count, 
                $total_checked, 
                $previously_completed_count,
                $total_completed,
                $total_provider_orders, 
                $calculated_all_completed ? 'true' : 'false', 
                $any_error ? 'true' : 'false'
            ));
            $retry_multiplier = $any_error ? 2 : 1;
            $this->schedule_single_order_check($order_id, $this->get_retry_delay_seconds($retry_multiplier));
        }
    }
    
    /**
     * Obtém todos os provider_order_ids de um pedido com seus provedores
     */
    private function get_all_provider_orders_from_order($order)
    {
        $provider_orders = array();
        $items = $order->get_items();
        
        foreach ($items as $item_id => $item) {
            // Cada item pode ter múltiplos links, buscar provider_order_id de cada um
            $links = $item->get_meta('_link', false);
            
            if (!empty($links)) {
                foreach ($links as $link_index => $link_item) {
                    $provider_order_id = wc_get_order_item_meta($item_id, "_provider_order_id_$link_index", true);
                    $provider_index = wc_get_order_item_meta($item_id, "_provider_index_$link_index", true);
                    $provider_api_url = wc_get_order_item_meta($item_id, "_provider_api_url_$link_index", true);

                    if (empty($provider_order_id)) {
                        $provider_order_id = wc_get_order_item_meta($item_id, '_provider_order_id', true);
                    }
                    if (empty($provider_index)) {
                        $provider_index = wc_get_order_item_meta($item_id, '_provider_index', true);
                    }
                    
                    // Se não encontrou provider_index, tentar detectar do produto
                    if (!empty($provider_order_id) && empty($provider_index)) {
                        $variation_id = $item->get_variation_id();
                        $product_id = $item->get_product_id();
                        
                        // Tentar buscar do produto/variação (buscar ambos os campos para compatibilidade)
                        $provider_index = get_post_meta($variation_id, '_upgram_provider', true);
                        if (empty($provider_index)) {
                            $provider_index = get_post_meta($variation_id, '_upgram_provider_index', true);
                        }
                        if (empty($provider_index)) {
                            $provider_index = get_post_meta($product_id, '_upgram_provider', true);
                        }
                        if (empty($provider_index)) {
                            $provider_index = get_post_meta($product_id, '_upgram_provider_index', true);
                        }
                        
                        // Se ainda não encontrou, tentar detectar pela URL da API salva
                        if (empty($provider_index)) {
                            $saved_api_url = get_post_meta($variation_id, '_upgram_api_url', true);
                            if (empty($saved_api_url)) {
                                $saved_api_url = get_post_meta($product_id, '_upgram_api_url', true);
                            }
                            
                            if (!empty($saved_api_url)) {
                                // Buscar qual provedor tem essa URL
                                $providers = get_option('upgram_providers', []);
                                foreach ($providers as $idx => $provider) {
                                    if (isset($provider['api_url']) && $this->normalize_api_url($provider['api_url']) === $this->normalize_api_url($saved_api_url)) {
                                        $provider_index = $idx;
                                        $provider_api_url = $provider['api_url'];
                                        error_log(sprintf('Order #%d - Detected provider_index %s by API URL match', 
                                            $order->get_id(), $provider_index));
                                        break;
                                    }
                                }
                            }
                        }
                        
                        // Se encontrou, salvar para próxima vez
                        if (!empty($provider_index)) {
                            wc_update_order_item_meta($item_id, "_provider_index_$link_index", $provider_index);
                            if (!empty($provider_api_url)) {
                                wc_update_order_item_meta($item_id, "_provider_api_url_$link_index", $provider_api_url);
                            }
                            error_log(sprintf('Order #%d - Detected and saved provider_index %s for item %d, link %d', 
                                $order->get_id(), $provider_index, $item_id, $link_index));
                        } else {
                            error_log(sprintf('Order #%d - WARNING: Could not detect provider_index for provider_order_id %s', 
                                $order->get_id(), $provider_order_id));
                        }
                    }
                    
                    if (!empty($provider_order_id)) {
                        if (empty($provider_api_url)) {
                            $provider_api_url = $item->get_meta('_provider_api_url');
                        }
                        $provider_orders[] = array(
                            'provider_order_id' => $provider_order_id,
                            'provider_index' => $provider_index,
                            'item_id' => $item_id,
                            'link_index' => $link_index,
                            'provider_api_url' => $provider_api_url
                        );
                        
                        error_log(sprintf('Order #%d - Found provider_order_id: %s, provider_index: %s, item_id: %s, link_index: %s', 
                            $order->get_id(), $provider_order_id, $provider_index ?: 'EMPTY', $item_id, $link_index));
                    }
                }
            } else {
                // Fallback: tentar buscar provider_order_id sem índice de link (pedidos antigos)
                $provider_order_id = $item->get_meta('_upgram_provider_order_id');
                $provider_index = $item->get_meta('_upgram_provider_index');
                $provider_api_url = $item->get_meta('_upgram_provider_api_url');

                if (empty($provider_order_id)) {
                    $provider_order_id = $item->get_meta('_provider_order_id');
                }
                if (empty($provider_index)) {
                    $provider_index = $item->get_meta('_provider_index');
                }
                if (empty($provider_api_url)) {
                    $provider_api_url = $item->get_meta('_provider_api_url');
                }

                if (empty($provider_order_id)) {
                    $provider_order_id = $item->get_meta('_provider_order_id');
                }
                if (empty($provider_index)) {
                    $provider_index = $item->get_meta('_provider_index');
                }
                
                // Tentar detectar do produto se não encontrou
                if (!empty($provider_order_id) && empty($provider_index)) {
                    $variation_id = $item->get_variation_id();
                    $product_id = $item->get_product_id();
                    
                    // Buscar ambos os campos para compatibilidade
                    $provider_index = get_post_meta($variation_id, '_upgram_provider', true);
                    if (empty($provider_index)) {
                        $provider_index = get_post_meta($variation_id, '_upgram_provider_index', true);
                    }
                    if (empty($provider_index)) {
                        $provider_index = get_post_meta($product_id, '_upgram_provider', true);
                    }
                    if (empty($provider_index)) {
                        $provider_index = get_post_meta($product_id, '_upgram_provider_index', true);
                    }

                    if (empty($provider_api_url)) {
                        $saved_api_url = get_post_meta($variation_id, '_upgram_api_url', true);
                        if (empty($saved_api_url)) {
                            $saved_api_url = get_post_meta($product_id, '_upgram_api_url', true);
                        }

                        if (!empty($saved_api_url)) {
                            $providers = get_option('upgram_providers', []);
                            foreach ($providers as $idx => $provider) {
                                if (isset($provider['api_url']) && $this->normalize_api_url($provider['api_url']) === $this->normalize_api_url($saved_api_url)) {
                                    $provider_index = $provider_index ?: $idx;
                                    $provider_api_url = $provider['api_url'];
                                    break;
                                }
                            }
                        }
                    }

                    if (!empty($provider_index)) {
                        wc_update_order_item_meta($item_id, '_upgram_provider_index', $provider_index);
                    }
                    if (!empty($provider_api_url)) {
                        wc_update_order_item_meta($item_id, '_upgram_provider_api_url', $provider_api_url);
                    }
                }
                
                if (!empty($provider_order_id)) {
                    $provider_orders[] = array(
                        'provider_order_id' => $provider_order_id,
                        'provider_index' => $provider_index,
                        'item_id' => $item_id,
                        'link_index' => 0,
                        'provider_api_url' => $provider_api_url
                    );
                }
            }
        }
        
        // Se não encontrou nos itens, tentar no pedido (para compatibilidade)
        if (empty($provider_orders)) {
            $provider_order_id = $order->get_meta('_upgram_provider_order_id');
            $provider_index = $order->get_meta('_upgram_provider_index');
            $provider_api_url = $order->get_meta('_upgram_provider_api_url');
            
            if (!empty($provider_order_id)) {
                $provider_orders[] = array(
                    'provider_order_id' => $provider_order_id,
                    'provider_index' => $provider_index,
                    'item_id' => 0,
                    'link_index' => 0,
                    'provider_api_url' => $provider_api_url
                );
            }
        }
        
        return $provider_orders;
    }
    
    /**
     * Obtém informações do provedor por índice
     */
    private function get_provider_info_by_index($provider_index, $provider_api_url = null)
    {
        $providers = get_option('upgram_providers', []);
        if (empty($providers)) {
            error_log('No providers configured');
            return false;
        }

        $provider_info = null;
        $resolved_index = $provider_index;
        $has_index = ($provider_index !== null && $provider_index !== '' && $provider_index !== false);

        if ($has_index) {
            if (isset($providers[$provider_index])) {
                $provider_info = $providers[$provider_index];
            } elseif (isset($providers[(string) $provider_index])) {
                $provider_info = $providers[(string) $provider_index];
                $resolved_index = (string) $provider_index;
            } elseif (isset($providers[(int) $provider_index])) {
                $provider_info = $providers[(int) $provider_index];
                $resolved_index = (int) $provider_index;
            }
        }

        if (!$provider_info && $provider_api_url) {
            foreach ($providers as $idx => $provider) {
                if (isset($provider['api_url']) && $this->normalize_api_url($provider['api_url']) === $this->normalize_api_url($provider_api_url)) {
                    $provider_info = $provider;
                    $resolved_index = $idx;
                    break;
                }
            }
        }

        if (!$provider_info) {
            if ($has_index) {
                error_log(sprintf('Provider index "%s" (type: %s) not found in providers list. Available providers: %s', 
                    $provider_index, gettype($provider_index), implode(', ', array_map(function($k) { return sprintf('"%s"', $k); }, array_keys($providers)))));
            } else {
                error_log('No provider index provided and API URL did not match any provider.');
            }
            return false;
        }

        error_log(sprintf('✓ Found provider: %s (index: %s, type: %s), API URL: %s', 
            $provider_info['name'] ?? 'Unknown', $resolved_index, gettype($resolved_index), $provider_info['api_url'] ?? 'N/A'));

        $provider_info['__index'] = $resolved_index;

        return $provider_info;
    }


    /**
     * Consulta o status na API do provedor
     * SISTEMA REFEITO: Mais robusto, adaptativo e com consideração de fuso horário
     */
    private function query_provider_status($provider_order_id, $provider_info)
    {
        $api_url = $provider_info['api_url'];
        $api_key = $provider_info['api_key'];

        if (empty($api_url) || empty($api_key)) {
            error_log(sprintf('Order %s: Missing API credentials (URL or Key)', $provider_order_id));
            return new WP_Error('missing_credentials', 'API URL ou Key não configurados');
        }

        // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário do WordPress
        $current_time = current_time('timestamp');
        $cache_key = 'upgram_api_request_' . md5($api_url . $provider_order_id);
        $last_request_time = get_transient($cache_key);

        // Rate limiting: aguardar pelo menos 3 segundos entre requisições para o mesmo pedido
        if ($last_request_time && ($current_time - $last_request_time) < 3) {
            $wait_time = 3 - ($current_time - $last_request_time);
            error_log(sprintf('Order %s: Rate limiting - waiting %d seconds before next request', 
                $provider_order_id, $wait_time));
            return new WP_Error('rate_limited', sprintf('Rate limit: aguarde %d segundos', $wait_time));
        }

        // Preparar corpo da requisição
        $request_body = array(
            'key' => $api_key,
            'action' => 'status',
            'order' => $provider_order_id
        );

        // Múltiplos formatos de tentativa (JSON primeiro, depois form-urlencoded)
        $attempts = array(
            array(
                'format' => 'json',
                'headers' => array(
                    'Content-Type' => 'application/json',
                    'User-Agent' => 'UpgramPlugin/2.0',
                    'Accept' => 'application/json',
                    'X-Request-Time' => (string)$current_time,
                    'X-Timezone' => wp_timezone_string()
                ),
                'body' => wp_json_encode($request_body)
            ),
            array(
                'format' => 'form',
                'headers' => array(
                    'Content-Type' => 'application/x-www-form-urlencoded',
                    'User-Agent' => 'UpgramPlugin/2.0',
                    'Accept' => 'application/json, application/*+json, text/plain;q=0.2',
                    'X-Request-Time' => (string)$current_time,
                    'X-Timezone' => wp_timezone_string()
                ),
                'body' => http_build_query($request_body, '', '&')
            )
        );

        $last_error = null;
        $successful_attempt = null;

        foreach ($attempts as $attempt_index => $attempt) {
            // Timeout adaptativo: 60 segundos base, com fallback para 90 segundos
            $timeout = 60;
            if ($attempt_index > 0) {
                $timeout = 90; // Timeout maior para segunda tentativa
            }

            // Log da tentativa com timestamp local
            $attempt_time = current_time('mysql');
            error_log(sprintf(
                '[%s] Order %s: Attempt %d/%d (%s format) - URL: %s',
                $attempt_time,
                $provider_order_id,
                $attempt_index + 1,
                count($attempts),
                strtoupper($attempt['format']),
                $api_url
            ));

            // Fazer requisição com timeout e retry
            $response = wp_remote_post($api_url, array(
                'headers' => $attempt['headers'],
                'body' => $attempt['body'],
                'timeout' => $timeout,
                'sslverify' => true,
                'redirection' => 5,
                'httpversion' => '1.1',
                'blocking' => true
            ));

            // Verificar se houve erro na requisição
            if (is_wp_error($response)) {
                $error_code = $response->get_error_code();
                $error_message = $response->get_error_message();
                
                error_log(sprintf(
                    '[%s] Order %s: Request error (%s format) - Code: %s, Message: %s',
                    current_time('mysql'),
                    $provider_order_id,
                    strtoupper($attempt['format']),
                    $error_code,
                    $error_message
                ));

                // Se for erro de conexão/timeout, tentar com SSL verify desabilitado como fallback
                if (in_array($error_code, array('http_request_failed', 'timeout'))) {
                    error_log(sprintf('Order %s: Retrying without SSL verification...', $provider_order_id));
                    
                    $response = wp_remote_post($api_url, array(
                        'headers' => $attempt['headers'],
                        'body' => $attempt['body'],
                        'timeout' => $timeout,
                        'sslverify' => false, // Fallback: sem verificação SSL
                        'redirection' => 5,
                        'httpversion' => '1.1',
                        'blocking' => true
                    ));

                    if (is_wp_error($response)) {
                        $last_error = $response;
                        continue;
                    }
                } else {
                    $last_error = $response;
                    continue;
                }
            }

            // Normalizar e validar resposta
            $normalized = $this->normalize_provider_response($response, $provider_order_id);

            if (!is_wp_error($normalized)) {
                // Sucesso! Salvar timestamp da última requisição bem-sucedida
                $success_time = current_time('timestamp');
                set_transient($cache_key, $success_time, 300); // Cache por 5 minutos
                
                if ($attempt['format'] === 'form') {
                    error_log(sprintf('[%s] Order %s: ✓ Succeeded using FORM fallback',
                        current_time('mysql'), $provider_order_id));
                } else {
                    error_log(sprintf('[%s] Order %s: ✓ Succeeded using JSON format',
                        current_time('mysql'), $provider_order_id));
                }
                
                // Registrar sucesso para estatísticas adaptativas
                $this->record_provider_request_result($provider_info, true);
                
                return $normalized;
            }

            $error_code = $normalized->get_error_code();
            $error_message = $normalized->get_error_message();

            error_log(sprintf(
                '[%s] Order %s: Response error (%s format) - Code: %s, Message: %s',
                current_time('mysql'),
                $provider_order_id,
                strtoupper($attempt['format']),
                $error_code,
                $error_message
            ));

            $last_error = $normalized;

            // Somente tentar o próximo formato se for erro relacionado ao formato/parse
            if (!in_array($error_code, array('json_error', 'invalid_format', 'missing_status_field'), true)) {
                // Se não é erro de formato, não adianta tentar outro formato
                break;
            }
        }

        // Todas as tentativas falharam
        $failure_time = current_time('timestamp');
        set_transient($cache_key, $failure_time, 60); // Cache de erro por 1 minuto (menor)
        
        // Registrar falha para estatísticas adaptativas
        $this->record_provider_request_result($provider_info, false);

        return $last_error ? $last_error : new WP_Error(
            'provider_request_failed',
            'Não foi possível obter o status do provedor após todas as tentativas'
        );
    }
    
    /**
     * Registra resultado da requisição para estatísticas adaptativas
     */
    private function record_provider_request_result($provider_info, $success)
    {
        if (!isset($provider_info['__index'])) {
            return;
        }
        
        $provider_index = $provider_info['__index'];
        $stats_key = '_upgram_provider_stats_' . $provider_index;
        
        $stats = get_option($stats_key, array(
            'total_requests' => 0,
            'successful_requests' => 0,
            'failed_requests' => 0,
            'last_success' => 0,
            'last_failure' => 0,
            'success_rate' => 100.0
        ));
        
        $stats['total_requests']++;
        
        if ($success) {
            $stats['successful_requests']++;
            $stats['last_success'] = current_time('timestamp');
        } else {
            $stats['failed_requests']++;
            $stats['last_failure'] = current_time('timestamp');
        }
        
        // Calcular taxa de sucesso
        if ($stats['total_requests'] > 0) {
            $stats['success_rate'] = ($stats['successful_requests'] / $stats['total_requests']) * 100;
        }
        
        // Manter apenas últimas 100 requisições para evitar crescimento infinito
        if ($stats['total_requests'] > 100) {
            // Resetar contadores mas manter taxa de sucesso
            $reset_factor = 0.8;
            $stats['total_requests'] = intval($stats['total_requests'] * $reset_factor);
            $stats['successful_requests'] = intval($stats['successful_requests'] * $reset_factor);
            $stats['failed_requests'] = intval($stats['failed_requests'] * $reset_factor);
        }
        
        update_option($stats_key, $stats);
    }

    private function normalize_provider_response($response, $provider_order_id)
    {
        $response_code = wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);

        // IMPORTANTE: Log com timestamp local usando current_time('mysql')
        $response_time = current_time('mysql');

        error_log(sprintf(
            '[%s] API Status Check - Order: %s, Response Code: %d, Body length: %d chars',
            $response_time,
            $provider_order_id,
            $response_code,
            strlen($body)
        ));
        
        // Log completo do body apenas se debug está ativo (evitar logs excessivos)
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log(sprintf('[%s] API Response Body: %s', $response_time, substr($body, 0, 500)));
        }

        if ($response_code !== 200) {
            return new WP_Error('http_error', 'API retornou status HTTP: ' . $response_code);
        }

        if ($body === '' || $body === null) {
            return new WP_Error('empty_response', 'Resposta vazia da API');
        }

        $data = json_decode($body, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            return new WP_Error('json_error', 'Erro ao decodificar resposta da API: ' . json_last_error_msg());
        }

        // Normalizar estrutura comum de APIs SMM
        if (isset($data['error'])) {
            return new WP_Error('api_error', is_array($data['error']) ? wp_json_encode($data['error']) : $data['error']);
        }

        if (isset($data[0]) && is_array($data[0]) && !isset($data['status'])) {
            // Algumas APIs retornam array numérico com um único item
            $data = $data[0];
        }

        if (isset($data['data']) && is_array($data['data']) && !isset($data['status'])) {
            // Outras APIs aninham o resultado em "data"
            $data = $data['data'];
        }

        $status = $this->array_get_case_insensitive($data, 'status');

        if ($status === null) {
            return new WP_Error('missing_status_field', 'Resposta da API não contém campo de status');
        }

        // Normalizar o status para string (pode vir como número ou outro tipo)
        $status_normalized = is_string($status) ? $status : (string) $status;
        
        $normalized = array(
            'status' => $status_normalized,
            'charge' => $this->array_get_case_insensitive($data, 'charge'),
            'start_count' => $this->array_get_case_insensitive($data, 'start_count'),
            'remains' => $this->array_get_case_insensitive($data, 'remains'),
            'currency' => $this->array_get_case_insensitive($data, 'currency'),
            'raw_response' => $data
        );

        // Log do status recebido para debugging com timestamp local
        $status_time = current_time('mysql');
        error_log(sprintf('[%s] API Status Response for order %s: Status=%s (normalized from %s), Remains=%s, Charge=%s', 
            $status_time,
            $provider_order_id, 
            $status_normalized,
            var_export($status, true),
            isset($normalized['remains']) ? $normalized['remains'] : 'N/A',
            isset($normalized['charge']) ? $normalized['charge'] : 'N/A'
        ));

        return $normalized;
    }

    private function array_get_case_insensitive($array, $key)
    {
        if (!is_array($array)) {
            return null;
        }

        if (array_key_exists($key, $array)) {
            return $array[$key];
        }

        $key_lower = strtolower($key);

        foreach ($array as $index => $value) {
            if (is_string($index) && strtolower($index) === $key_lower) {
                return $value;
            }
        }

        return null;
    }

    private function normalize_api_url($url)
    {
        if (empty($url) || !is_string($url)) {
            return '';
        }

        $url = trim($url);
        if ($url === '') {
            return '';
        }

        $parsed = wp_parse_url($url);
        if ($parsed === false || empty($parsed['host'])) {
            return rtrim($url, '/');
        }

        $scheme = isset($parsed['scheme']) ? strtolower($parsed['scheme']) : 'https';
        $host = strtolower($parsed['host']);
        $port = isset($parsed['port']) ? ':' . $parsed['port'] : '';
        $path = isset($parsed['path']) ? rtrim($parsed['path'], '/') : '';

        return $scheme . '://' . $host . $port . $path;
    }

    public function schedule_single_order_check($order_id, $delay_seconds = null)
    {
        if (!get_option('upgram_enable_status_checker', true)) {
            return;
        }

        if ($delay_seconds === null) {
            $delay_seconds = $this->get_retry_delay_seconds();
        }

        $delay_seconds = max(30, intval($delay_seconds));
        // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário
        $current_time = current_time('timestamp');
        $timestamp = $current_time + $delay_seconds;

        if ($this->is_action_scheduler_available()) {
            $existing = as_next_scheduled_action($this->hook_name, array($order_id), $this->action_group);
            if ($existing && $existing >= ($timestamp - 10)) {
                return;
            }

            if ($existing) {
                as_unschedule_all_actions($this->hook_name, array($order_id), $this->action_group);
            }

            as_schedule_single_action($timestamp, $this->hook_name, array($order_id), $this->action_group);
            error_log(sprintf('Order #%d - Single status check scheduled (Action Scheduler) for %s', 
                $order_id, date('Y-m-d H:i:s', $timestamp)));
        } else {
            $existing = wp_next_scheduled($this->hook_name, array($order_id));
            if ($existing && $existing >= ($timestamp - 10)) {
                return;
            }

            if ($existing) {
                wp_clear_scheduled_hook($this->hook_name, array($order_id));
            }

            wp_schedule_single_event($timestamp, $this->hook_name, array($order_id));
            error_log(sprintf('Order #%d - Single status check scheduled (WP-Cron) for %s', 
                $order_id, date('Y-m-d H:i:s', $timestamp)));
        }
    }

    private function unschedule_single_order_check($order_id)
    {
        if ($this->is_action_scheduler_available()) {
            as_unschedule_all_actions($this->hook_name, array($order_id), $this->action_group);
        } else {
            wp_clear_scheduled_hook($this->hook_name, array($order_id));
        }
    }

    private function get_retry_delay_seconds($multiplier = 1)
    {
        $interval_minutes = absint(get_option('upgram_status_check_interval', 2));
        if ($interval_minutes < 1) {
            $interval_minutes = 2;
        }

        $seconds = $interval_minutes * MINUTE_IN_SECONDS;
        $seconds = max(60, $seconds);

        $multiplier = max(1, intval($multiplier));

        return $seconds * $multiplier;
    }

    private function store_provider_error_meta($order, $provider_order_id, $provider_index, $error_code, $error_message, $item_id, $link_index)
    {
        $errors = $order->get_meta('_upgram_provider_status_errors', true);
        if (!is_array($errors)) {
            $errors = array();
        }

        $errors[$provider_order_id] = array(
            'code' => $error_code,
            'message' => $error_message,
            'provider_index' => $provider_index,
            'updated_at' => current_time('mysql')
        );

        $order->update_meta_data('_upgram_provider_status_errors', $errors);

        if ($item_id > 0) {
            wc_update_order_item_meta($item_id, "_provider_status_error_$link_index", $error_message);
        } else {
            $order->update_meta_data('_upgram_provider_status_error', $error_message);
        }
    }

    private function clear_provider_error_meta($order, $provider_order_id, $item_id, $link_index)
    {
        $errors = $order->get_meta('_upgram_provider_status_errors', true);

        if (is_array($errors) && isset($errors[$provider_order_id])) {
            unset($errors[$provider_order_id]);

            if (empty($errors)) {
                $order->delete_meta_data('_upgram_provider_status_errors');
            } else {
                $order->update_meta_data('_upgram_provider_status_errors', $errors);
            }
        }

        if ($item_id > 0) {
            wc_delete_order_item_meta($item_id, "_provider_status_error_$link_index");
        } else {
            $order->delete_meta_data('_upgram_provider_status_error');
        }
    }

    /**
     * Completa o pedido quando status do provedor é "Completed"
     */
    private function complete_order($order, $status_info)
    {
        $order_id = $order->get_id();

        // Verificar se já foi concluído
        if ($order->get_status() === 'completed') {
            error_log(sprintf('Order #%d already completed', $order_id));
            return;
        }

        // Atualizar status para concluído
        $order->update_status('completed', 'Status atualizado automaticamente via API do provedor: Completo.');

        // Adicionar nota detalhada
        $note = "Pedido concluído automaticamente após verificação na API do provedor.\n";
        $note .= "Status do provedor: " . $status_info['status'] . "\n";
        if (!empty($status_info['charge'])) {
            $note .= "Quantidade processada: " . $status_info['charge'];
        }

        $order->add_order_note($note);

        // Remover da fila de verificação (opcional, manter histórico)
        $order->update_meta_data('_upgram_auto_completed', true);
        // IMPORTANTE: Usar current_time('mysql') que considera fuso horário
        $order->update_meta_data('_upgram_auto_completed_date', current_time('mysql'));
        $order->update_meta_data('_upgram_auto_completed_timestamp', current_time('timestamp'));
        $order->save();

        error_log(sprintf('Order #%d auto-completed via status checker', $order_id));

        // Executar ação customizada (para extensões futuras)
        do_action('upgram_order_auto_completed', $order_id, $status_info);
    }

    /**
     * Manipula ativação/desativação do status checker
     */
    public function handle_status_checker_toggle($old_value, $new_value)
    {
        if ($new_value && !$old_value) {
            // Ativado - agendar verificações
            $this->schedule_recurring_check();
            error_log('Order status checker: Enabled');
        } elseif (!$new_value && $old_value) {
            // Desativado - cancelar agendamentos
            $this->unschedule_recurring_check();
            error_log('Order status checker: Disabled');
        }
    }

    /**
     * Manipula mudança no intervalo de verificação
     */
    public function handle_interval_change($old_value, $new_value)
    {
        if (get_option('upgram_enable_status_checker', true)) {
            // Reagendar com novo intervalo
            $this->unschedule_recurring_check();
            $this->schedule_recurring_check();
            error_log(sprintf('Order status checker: Interval changed from %d to %d minutes', $old_value, $new_value));
        }
    }

    /**
     * Agenda verificação recorrente
     */
    private function schedule_recurring_check()
    {
        $interval_seconds = $this->get_interval_seconds();
        $interval_minutes = max(1, intval($interval_seconds / MINUTE_IN_SECONDS));

        // IMPORTANTE: Usar current_time('timestamp') que considera fuso horário
        $current_time = current_time('timestamp');
        $first_run = $current_time + max(30, min($interval_seconds, 300));

        if ($this->is_action_scheduler_available()) {
            // Limpar TODOS os agendamentos existentes (com e sem action_group)
            as_unschedule_all_actions($this->recurring_hook);
            
            $result = as_schedule_recurring_action($first_run, $interval_seconds, $this->recurring_hook, array(), $this->action_group);
            if ($result) {
                error_log('Order status checker: Recurring check scheduled (Action Scheduler) - every ' . $interval_minutes . ' minutes - First run: ' . date('Y-m-d H:i:s', $first_run));
                
                // Verificar se foi realmente agendado
                $verify = as_next_scheduled_action($this->recurring_hook, array(), $this->action_group);
                if ($verify) {
                    error_log('Order status checker: ✓ Verified - Next check scheduled for: ' . date('Y-m-d H:i:s', $verify));
                } else {
                    error_log('Order status checker: ⚠ WARNING - Schedule created but verification failed');
                }
            } else {
                error_log('Order status checker: ✗ ERROR - Failed to schedule with Action Scheduler');
            }
        } else {
            wp_clear_scheduled_hook($this->recurring_hook);
            $result = wp_schedule_event($first_run, 'upgram_custom_interval', $this->recurring_hook);
            if ($result !== false) {
                error_log('Order status checker: Recurring check scheduled (WP-Cron) - every ' . $interval_minutes . ' minutes');
                $next_run = wp_next_scheduled($this->recurring_hook);
                if ($next_run) {
                    error_log('Order status checker: ✓ Verified - Next check scheduled for: ' . date('Y-m-d H:i:s', $next_run));
                } else {
                    error_log('Order status checker: ⚠ WARNING - Schedule created but verification failed');
                }
            } else {
                error_log('Order status checker: ✗ ERROR - Failed to schedule with WP-Cron');
            }
        }
    }

    /**
     * Cancela verificação recorrente
     */
    private function unschedule_recurring_check()
    {
        if ($this->is_action_scheduler_available()) {
            // Limpar TODOS os agendamentos (com e sem action_group)
            as_unschedule_all_actions($this->recurring_hook);
            error_log('Order status checker: All recurring checks unscheduled (Action Scheduler)');
        } else {
            wp_clear_scheduled_hook($this->recurring_hook);
            error_log('Order status checker: Recurring check unscheduled (WP-Cron)');
        }
    }

    /**
     * Obtém estatísticas do status checker
     */
    public function get_statistics()
    {
        // Pedidos sendo monitorados
        $monitored_orders = wc_get_orders(array(
            'status' => array('processing', 'pending', 'on-hold'),
            'meta_key' => '_upgram_provider_order_id',
            'limit' => -1,
            'return' => 'ids'
        ));

        // Pedidos concluídos automaticamente
        $auto_completed_orders = wc_get_orders(array(
            'status' => 'completed',
            'meta_key' => '_upgram_auto_completed',
            'meta_value' => true,
            'limit' => -1,
            'return' => 'ids'
        ));

        return array(
            'monitored_count' => count($monitored_orders),
            'auto_completed_count' => count($auto_completed_orders),
            'last_check' => get_option('_upgram_last_status_check_time', 0),
            'next_check' => $this->get_next_scheduled_time()
        );
    }

    /**
     * Obtém próximo horário agendado
     */
    private function get_next_scheduled_time()
    {
        if ($this->is_action_scheduler_available()) {
            // Tentar buscar com action_group primeiro
            $timestamp = as_next_scheduled_action($this->recurring_hook, array(), $this->action_group);
            
            // Se não encontrou, tentar sem action_group (para compatibilidade)
            if (!$timestamp) {
                $timestamp = as_next_scheduled_action($this->recurring_hook);
            }
            
            return $timestamp ? $timestamp : 0;
        } else {
            $timestamp = wp_next_scheduled($this->recurring_hook);
            return $timestamp ? $timestamp : 0;
        }
    }

    private function get_interval_seconds()
    {
        $interval_minutes = absint(get_option('upgram_status_check_interval', 2));
        if ($interval_minutes < 1) {
            $interval_minutes = 2;
        }

        return $interval_minutes * MINUTE_IN_SECONDS;
    }

    /**
     * Testa a API manualmente (para debugging)
     */
    public function test_provider_api($provider_index, $test_order_id = null)
    {
        $providers = get_option('upgram_providers', []);
        if (!isset($providers[$provider_index])) {
            return new WP_Error('provider_not_found', 'Provedor não encontrado');
        }

        $provider = $providers[$provider_index];
        $api_url = $provider['api_url'];
        $api_key = $provider['api_key'];

        if (empty($api_url) || empty($api_key)) {
            return new WP_Error('missing_credentials', 'API URL ou Key não configurados');
        }

        // Usar order ID de teste se fornecido
        $test_id = $test_order_id ?: '123456';

        // Preparar dados da requisição
        $request_body = array(
            'key' => $api_key,
            'action' => 'status',
            'order' => $test_id
        );

        error_log(sprintf('Testing API - URL: %s, Order ID: %s', $api_url, $test_id));

        // Fazer requisição de teste
        $response = wp_remote_post($api_url, array(
            'headers' => array(
                'Content-Type' => 'application/json',
                'User-Agent' => 'UpgramPlugin/1.0-Test',
                'Accept' => 'application/json'
            ),
            'body' => json_encode($request_body),
            'timeout' => 60,
            'sslverify' => true
        ));

        if (is_wp_error($response)) {
            return $response;
        }

        $response_code = wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);

        $result = array(
            'response_code' => $response_code,
            'body' => $body,
            'request_data' => $request_body,
            'api_url' => $api_url
        );

        error_log(sprintf('API Test Result: %s', print_r($result, true)));

        return $result;
    }

    /**
     * Desabilitar verificações agendadas (sistema agora usa verificação livre/on-demand)
     */
    public function disable_scheduled_checks()
    {
        // Cancelar todos os agendamentos de verificação recorrente
        if (function_exists('as_unschedule_all_actions') && class_exists('ActionScheduler')) {
            as_unschedule_all_actions($this->recurring_hook);
        } else {
            wp_clear_scheduled_hook($this->recurring_hook);
        }
        
        // Desabilitar flag de verificação agendada
        if (get_option('upgram_enable_status_checker', false)) {
            update_option('upgram_enable_status_checker', false, true);
            error_log('Order status checker: Sistema de verificação agendada desativado - usando verificação livre (on-demand)');
        }
    }
}

// Adicionar intervalo customizado ao WP-Cron (sempre atualizado)
add_filter('cron_schedules', function($schedules) {
    $interval_minutes = absint(get_option('upgram_status_check_interval', 2));
    if ($interval_minutes < 1) {
        $interval_minutes = 2;
    }
    
    $interval_seconds = $interval_minutes * MINUTE_IN_SECONDS;
    
    $schedules['upgram_custom_interval'] = array(
        'interval' => $interval_seconds,
        'display' => sprintf('A cada %d minutos (Upgram)', $interval_minutes)
    );
    
    return $schedules;
}, 999); // Prioridade alta para garantir que seja aplicado

// Inicializar o status checker
function upgram_init_order_status_checker()
{
    return Upgram_Order_Status_Checker::get_instance();
}
add_action('plugins_loaded', 'upgram_init_order_status_checker');

