 7 * DAY_IN_SECONDS ),
        ] );
        if ( ! empty( $recent_orders ) ) {
            WCIA_Logs::add( 'remarketing', $phone, true, "Cancelado: cliente já comprou após agendamento (pedido #{$recent_orders[0]->get_id()})" );
            return;
        }
    }

    // Sanitizar: nunca exibir texto conversacional do cliente
    if ( $query && ( count( explode( ' ', $query ) ) > 6 || preg_match( '/obrigad|aguardando|ta certo|beleza|valeu|perfeito|combinado/iu', $query ) ) ) {
        $query = ! empty( $course['name'] ) ? mb_substr( $course['name'], 0, 40 ) : 'seu concurso';
    }

    // Desconto e validade por estágio
    $disc_map  = [ 'awareness' => 0, 'consideration' => 5, 'intent_price' => 10, 'checkout_friction' => 10 ];
    $hours_map = [ 'awareness' => 0, 'consideration' => 24, 'intent_price' => 12, 'checkout_friction' => 12 ];
    $discount  = (int) ( $opts[ 'discount_' . $stage ] ?? $disc_map[ $stage ] ?? (int) ( $opts['discount'] ?? 10 ) );
    $hours     = (int) ( $opts[ 'coupon_hours_' . $stage ] ?? $hours_map[ $stage ] ?? (int) ( $opts['coupon_hours'] ?? 24 ) );
    $prefix    = strtoupper( sanitize_key( $opts['prefix'] ?? 'VOLTE' ) );

    // Gerar cupom WooCommerce (se estágio merece desconto)
    $coupon_text = '';
    if ( $discount > 0 && $hours > 0 ) {
        $code   = strtoupper( $prefix . $discount . '-' . wp_generate_password( 5, false, false ) );
        $expiry = date( 'Y-m-d', strtotime( "+{$hours} hours" ) );

        $coupon = new WC_Coupon();
        $coupon->set_code( $code );
        $coupon->set_discount_type( 'percent' );
        $coupon->set_amount( $discount );
        $coupon->set_individual_use( true );
        $coupon->set_usage_limit( 1 );
        $coupon->set_date_expires( $expiry );
        $coupon->set_description( "Remarketing {$stage} | {$phone} | {$query}" );
        $coupon->save();

        if ( $coupon->get_id() ) {
            update_post_meta( $coupon->get_id(), '_wcia_auto', 'yes' );
            update_post_meta( $coupon->get_id(), '_wcia_type', 'remarketing' );
            $coupon_text = "🎫 Cupom: *{$code}*\n💰 *{$discount}% OFF*\n⏰ Válido por *{$hours}h*\n";
        }
    }

    $link = $course['url'] ?? '';
    if ( ! $link && $query ) $link = get_site_url() . '/todos-os-cursos/?s=' . urlencode( $query );
    if ( $link ) $link = WCIA_Analytics::tracked_url( $link, $phone, (int) ( $course['id'] ?? 0 ), 'remarketing_' . $stage );

    // Mensagem por estágio
    switch ( $stage ) {
        case 'checkout_friction':
            $msg = "Oi! Vi que você ficou na parte do pagamento 😊\n\n✅ Aceitamos *PIX*, *cartão* e *boleto*\n";
            if ( $coupon_text ) $msg .= "\n{$coupon_text}";
            if ( ! empty( $course['name'] ) ) $msg .= "\n📚 Curso: *{$course['name']}*\n";
            if ( $link ) $msg .= "\n🔗 {$link}\n";
            $msg .= "\nSe quiser, eu te ajudo a fechar agora.";
            break;
        case 'intent_price':
            $msg = "Oi! Vi que você consultou valores 😊\n\n";
            if ( ! empty( $course['name'] ) ) $msg .= "📚 *{$course['name']}*\n";
            if ( $coupon_text ) $msg .= "\n{$coupon_text}";
            if ( $link ) $msg .= "\n🔗 {$link}\n";
            $msg .= "\nPosso te ajudar a concluir a compra.";
            break;
        case 'consideration':
            $msg = "Separei novamente o curso que você viu 👇\n\n";
            if ( ! empty( $course['name'] ) ) $msg .= "📚 *{$course['name']}*\n";
            if ( $coupon_text ) $msg .= "\n{$coupon_text}";
            if ( $link ) $msg .= "\n🔗 {$link}\n";
            $msg .= "\nSe quiser, eu te explico rapidinho como pagar.";
            break;
        default: // awareness
            $msg = "Oi! Vi que você procurou por *{$query}* 😊\n\nTemos opções diferentes para esse concurso.\n";
            if ( $link ) $msg .= "\n🔗 {$link}\n";
            $msg .= "\nSe quiser, eu posso te indicar a melhor opção.";
            break;
    }

    WCIA_Sender::proactive( $phone, $msg, 'remarketing_' . $stage );
    WCIA_Logs::add( 'remarketing', $phone, true, "Remarketing [{$stage}] enviado" . ( $coupon_text ? " | cupom: {$code}" : '' ) );
}, 10, 2 );

// --- 5a3. Avaliação pós-atendimento ---
add_action( 'wcia_send_satisfaction', function( $phone ) {
    $opts = get_option( 'wcia_satisfaction', [] );
    if ( empty( $opts['enabled'] ) ) return;

    $msg = "Olá! 😊 Gostaríamos de saber como foi seu atendimento!\n\n"
         . "De 1 a 5, qual nota você dá? ⭐\n\n"
         . "1️⃣ Péssimo\n"
         . "2️⃣ Ruim\n"
         . "3️⃣ Regular\n"
         . "4️⃣ Bom\n"
         . "5️⃣ Excelente\n\n"
         . "Responda apenas o número! Sua opinião nos ajuda muito 🙏";

    WCIA_Sender::proactive( $phone, $msg, 'satisfaction' );

    WCIA_Logs::add( 'system', $phone, true, 'Pesquisa de satisfação enviada' );
}, 10, 1 );

// --- 5b. Email semanal ---
add_action( 'wcia_weekly_email_send', function() {
    $opts = get_option( 'wcia_weekly_email', [] );
    if ( empty( $opts['enabled'] ) || empty( $opts['email'] ) ) return;

    // Relatório de logs (original)
    $logs_html = WCIA_Logs::weekly_report_html();

    // Receita atribuída ao bot (novo)
    $sales_html = '';
    if ( class_exists( 'WCIA_Analytics' ) && method_exists( 'WCIA_Analytics', 'bot_sales_summary' ) ) {
        $sales = WCIA_Analytics::bot_sales_summary( 7 );
        $sales_html = '<div style="background:#f0f9f0;border:2px solid #2e7d32;border-radius:8px;padding:16px;margin-bottom:20px">'
            . '<h2 style="color:#2e7d32;margin:0 0 12px">🤖 Vendas atribuídas ao Bot (últimos 7 dias)</h2>'
            . '<div style="font-size:28px;font-weight:bold;color:#2e7d32">R$ ' . number_format( (float) $sales['revenue'], 2, ',', '.' ) . '</div>'
            . '<div style="display:flex;gap:24px;margin-top:8px">'
            . '<div><strong>' . (int) $sales['orders'] . '</strong> pedidos</div>'
            . '<div><strong>R$ ' . number_format( (float) $sales['avg_ticket'], 2, ',', '.' ) . '</strong> ticket médio</div>'
            . '</div></div>';
    }

    // Índice do catálogo
    $index_html = '';
    if ( class_exists( 'WCIA_Catalog_Index' ) ) {
        $idx_count = WCIA_Catalog_Index::count();
        $index_html = '<p>📚 Índice do catálogo: <strong>' . $idx_count . '</strong> produtos indexados</p>';
    }

    // Memória de clientes
    $memory_html = '';
    if ( class_exists( 'WCIA_Customer_Memory' ) ) {
        global $wpdb;
        $mem_count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM " . WCIA_Customer_Memory::table_name() );
        $memory_html = '<p>👥 Clientes na memória: <strong>' . $mem_count . '</strong></p>';
    }

    $full_html = $sales_html . $index_html . $memory_html . '<hr style="margin:20px 0">' . $logs_html;

    wp_mail(
        $opts['email'],
        '📊 Relatório Semanal — WhatChimp IA — ' . current_time( 'd/m/Y' ),
        $full_html,
        [ 'Content-Type: text/html; charset=UTF-8' ]
    );

    WCIA_Logs::add( 'system', '', true, 'Email semanal enviado para ' . $opts['email'] );
} );

// --- 5c. Health Check ---
add_filter( 'cron_schedules', function( $schedules ) {
    $schedules['wcia_6hours']  = [ 'interval' => 21600, 'display' => 'A cada 6 horas' ];
    $schedules['wcia_12hours'] = [ 'interval' => 43200, 'display' => 'A cada 12 horas' ];
    return $schedules;
} );

$hc_opts = get_option( 'wcia_health_check', [] );
if ( ! empty( $hc_opts['enabled'] ) ) {
    if ( ! wp_next_scheduled( 'wcia_health_check' ) ) {
        wp_schedule_event( time() + 300, $hc_opts['interval'] ?? 'wcia_6hours', 'wcia_health_check' );
    }
} else {
    $ts = wp_next_scheduled( 'wcia_health_check' );
    if ( $ts ) wp_unschedule_event( $ts, 'wcia_health_check' );
}

add_action( 'wcia_health_check', 'wcia_run_health_check' );

/**
 * Verifica saúde das APIs (WhatChimp, IA, Evolution).
 *
 * Salva resultado em 'wcia_health_results' para o dashboard.
 * Notifica por email se algum serviço falhou.
 */
function wcia_run_health_check(): void {
    $results = [];

    // --- Evolution API (se ativada) ---
    if ( WCIA_Evolution::server_url() && WCIA_Evolution::global_key() && WCIA_Evolution::instance_name() ) {
        $results['evolution'] = WCIA_Evolution::health_check();
    }

    // --- WhatChimp (se configurado) ---
    $token    = WCIA_Config::whatchimp_token();
    $phone_id = WCIA_Config::whatchimp_phone_id();
    if ( $token && $phone_id ) {
        $resp = wp_remote_post( 'https://app.whatchimp.com/api/v1/whatsapp/subscriber/create', [
            'timeout' => 15,
            'body'    => [
                'apiToken' => $token, 'phone_number_id' => $phone_id,
                'phone_number' => '5500000000000', 'first_name' => 'HealthCheck',
            ],
        ] );
        $ok = ! is_wp_error( $resp ) && wp_remote_retrieve_response_code( $resp ) < 500;
        $results['whatchimp'] = [
            'ok' => $ok, 'time' => current_time( 'mysql' ),
            'msg' => $ok ? 'OK' : ( is_wp_error( $resp ) ? $resp->get_error_message() : 'HTTP ' . wp_remote_retrieve_response_code( $resp ) ),
        ];
    }

    // --- DeepSeek ---
    $ds_key = WCIA_Config::deepseek_key();
    if ( $ds_key ) {
        $resp = wp_remote_post( 'https://api.deepseek.com/chat/completions', [
            'timeout' => 15,
            'headers' => [ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $ds_key ],
            'body'    => wp_json_encode( [ 'model' => WCIA_Config::deepseek_model(), 'max_tokens' => 5, 'messages' => [ [ 'role' => 'user', 'content' => 'OK' ] ] ] ),
        ] );
        $ok = ! is_wp_error( $resp ) && wp_remote_retrieve_response_code( $resp ) < 300;
        $results['deepseek'] = [
            'ok' => $ok, 'time' => current_time( 'mysql' ),
            'msg' => $ok ? 'OK' : ( is_wp_error( $resp ) ? $resp->get_error_message() : 'HTTP ' . wp_remote_retrieve_response_code( $resp ) ),
        ];
    }

    // Salvar e notificar
    update_option( 'wcia_health_results', $results, false );

    $failed = array_filter( $results, fn( $r ) => ! $r['ok'] );
    $hc_opts = get_option( 'wcia_health_check', [] );

    if ( ! empty( $failed ) && ! empty( $hc_opts['notify_email'] ) ) {
        $svcs = implode( ', ', array_map( 'strtoupper', array_keys( $failed ) ) );
        wp_mail( $hc_opts['notify_email'], '⚠️ WhatChimp IA — Falha Health Check', "Falha: {$svcs}\n\n" . wp_json_encode( $failed, JSON_PRETTY_PRINT ), [ 'Content-Type: text/plain; charset=UTF-8' ] );
    }

    WCIA_Logs::add( 'health_check', '', empty( $failed ),
        'Serviços: ' . implode( ', ', array_map( fn( $k, $r ) => strtoupper( $k ) . ':' . ( $r['ok'] ? '✅' : '❌' ), array_keys( $results ), $results ) )
    );
}


/* ═══════════════════════════════════════════════════════════════════════
 * 5d. CRON JOBS — MÓDULOS AVANÇADOS v3.11
 *
 *   wcia_followup_check    → Follow-up pós-compra (diário)
 *   wcia_upsell_check      → Upsell inteligente (diário)
 *   wcia_wishlist_check    → Alerta lista de desejos (12h)
 *   wcia_reminder_check    → Lembrete curso não acessado (diário)
 *   wcia_scheduled_messages → Mensagens agendadas (5min)
 *   wcia_analytics_cleanup → Limpeza analytics antigos (semanal)
 * ═══════════════════════════════════════════════════════════════════════ */

// Adicionar intervalo de 5 minutos ao cron
add_filter( 'cron_schedules', function( $schedules ) {
    if ( ! isset( $schedules['wcia_5min'] ) ) {
        $schedules['wcia_5min'] = [ 'interval' => 300, 'display' => 'A cada 5 minutos' ];
    }
    if ( ! isset( $schedules['wcia_8hours'] ) ) {
        $schedules['wcia_8hours'] = [ 'interval' => 28800, 'display' => 'A cada 8 horas (3x/dia)' ];
    }
    return $schedules;
}, 20 );

// --- Follow-up pós-compra (diário) ---
if ( ! wp_next_scheduled( 'wcia_followup_check' ) ) {
    wp_schedule_event( time() + 7200, 'daily', 'wcia_followup_check' );
}

// --- Upsell inteligente (diário) ---
if ( ! wp_next_scheduled( 'wcia_upsell_check' ) ) {
    wp_schedule_event( time() + 10800, 'daily', 'wcia_upsell_check' );
}

// --- Wishlist / alerta de preço (12h) ---
if ( ! wp_next_scheduled( 'wcia_wishlist_check' ) ) {
    wp_schedule_event( time() + 14400, 'wcia_12hours', 'wcia_wishlist_check' );
}

// --- Lembrete curso não acessado (diário) ---
if ( ! wp_next_scheduled( 'wcia_reminder_check' ) ) {
    wp_schedule_event( time() + 18000, 'daily', 'wcia_reminder_check' );
}

// --- Mensagens agendadas (5min) ---
if ( ! wp_next_scheduled( 'wcia_scheduled_messages' ) ) {
    wp_schedule_event( time() + 60, 'wcia_5min', 'wcia_scheduled_messages' );
}

// --- Cleanup analytics (semanal) ---
add_action( 'wcia_daily_cleanup', function() {
    // Limpar analytics com mais de 90 dias (roda junto com cleanup diário)
    if ( (int) current_time( 'N' ) === 1 ) { // Só na segunda-feira
        WCIA_Analytics::cleanup();
        WCIA_Conversation::cleanup();
    }
} );

// --- Cleanup de arquivos temporários ---
add_action( 'wcia_cleanup_file', function( $path ) {
    // FIX: Validar que o path está dentro de uploads/ — ChatGPT Bug Crítico #2
    $upload_dir = wp_get_upload_dir();
    $base_real  = realpath( $upload_dir['basedir'] );
    $path_real  = realpath( $path );

    if ( ! $base_real || ! $path_real ) return;
    if ( strpos( $path_real, $base_real . DIRECTORY_SEPARATOR ) !== 0 ) return;
    if ( is_file( $path_real ) ) @unlink( $path_real );
} );


/* ═══════════════════════════════════════════════════════════════════════
 * 6. ATUALIZAÇÃO AUTOMÁTICA DE VERSÃO
 *
 * FIX: Tabelas são criadas em admin_init com try-catch.
 * @since 3.13.0
 * ═══════════════════════════════════════════════════════════════════════ */

add_action( 'admin_init', function() {
    try {
    $stored = get_option( 'wcia_installed_version', '' );
    if ( $stored !== WCIA_VERSION ) {
        try {
            @set_time_limit( 60 );
            WCIA_Cache::flush();

            // v3.13.0: criar tabelas MySQL
            if ( version_compare( $stored, '3.13.0', '<' ) ) {
                WCIA_Customer_Memory::install();
                WCIA_Catalog_Index::install();
            }

            // Migração v3.7.0: variáveis → #variavel#
            if ( version_compare( $stored, '3.7.2', '<' ) ) {
                wcia_migrate_variables_370();
            }

            // v3.13.0: limpar "ConcurseiroBot"/"assistente virtual"
            if ( ! get_option( 'wcia_identity_cleanup_313', false ) ) {
                $opts_to_clean = [ 'wcia_deepseek_prompt', 'wcia_global_prompt' ];
                foreach ( $opts_to_clean as $opt_key ) {
                    $val = get_option( $opt_key, '' );
                    if ( is_string( $val ) && $val ) {
                        $val = str_ireplace( [ 'ConcurseiroBot', 'assistente virtual' ], [ 'atendente do Cursos Rateio', 'atendente' ], $val );
                        update_option( $opt_key, $val );
                    }
                }
                update_option( 'wcia_identity_cleanup_313', true );
            }

            // v3.13.0: Limpar serviços legados do health check
            $conn = get_option( 'wcia_connection_status', [] );
            if ( isset( $conn['uazapi'] ) || isset( $conn['evolution_groups'] ) ) {
                unset( $conn['uazapi'], $conn['evolution_groups'] );
                update_option( 'wcia_connection_status', $conn, false );
            }
            $hresults = get_option( 'wcia_health_results', [] );
            if ( isset( $hresults['uazapi'] ) || isset( $hresults['evolution_groups'] ) ) {
                unset( $hresults['uazapi'], $hresults['evolution_groups'] );
                update_option( 'wcia_health_results', $hresults, false );
            }

            // v3.13.0: Limpar opt-in de TODOS os pedidos
            if ( ! get_option( 'wcia_optin_cleanup_done', false ) ) {
                global $wpdb;
                $deleted = (int) $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE meta_key = '_wcia_whatsapp_optin'" );
                $hpos_table = $wpdb->prefix . 'wc_orders_meta';
                if ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $hpos_table ) ) ) {
                    $deleted += (int) $wpdb->query( "DELETE FROM {$hpos_table} WHERE meta_key = '_wcia_whatsapp_optin'" );
                }
                $optin_opts = get_option( 'wcia_checkout_optin', [] );
                if ( ! empty( $optin_opts['enabled'] ) ) {
                    $optin_opts['enabled'] = false;
                    update_option( 'wcia_checkout_optin', $optin_opts );
                }
                update_option( 'wcia_optin_cleanup_done', true );
                if ( $deleted ) {
                    WCIA_Logs::add( 'system', '', true, "🧹 Opt-in limpo: {$deleted} registros removidos" );
                }
            }

            if ( $stored ) {
                WCIA_Logs::add( 'system', '', true, 'Plugin atualizado para v' . WCIA_VERSION . ' — cache limpo.' );
            }
        } catch ( \Throwable $e ) {
            error_log( 'WCIA: Migração falhou: ' . $e->getMessage() );
        }

        // Sempre marcar a versão (pra não travar em loop de migração)
        update_option( 'wcia_installed_version', WCIA_VERSION );
    }

    // Migrações independentes (rodam 1x, depois param)
    if ( ! get_option( 'wcia_migrated_sales_vars', false ) ) {
        wcia_migrate_sales_variables();
        update_option( 'wcia_migrated_sales_vars', true );
    }

    if ( ! get_option( 'wcia_templates_reset_312e', false ) ) {
        delete_option( 'wcia_notification_templates' );
        update_option( 'wcia_templates_reset_312e', true );
    }

    if ( ! get_option( 'wcia_cleanup_search_history', false ) ) {
        delete_option( 'wcia_search_history' );
        delete_option( 'wcia_templates_reset_312' );
        delete_option( 'wcia_templates_reset_312b' );
        delete_option( 'wcia_templates_reset_312c' );
        delete_option( 'wcia_templates_reset_312d' );
        update_option( 'wcia_cleanup_search_history', true );
    }

    } catch ( \Throwable $e ) {
        error_log( 'WCIA FATAL admin_init: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine() );
    }
} );

/**
 * Migra variáveis salvas no banco de dados para o formato #variavel#.
 *
 * Converte:
 *   {NOME} → #curso_nome#, {EDITORA} → #curso_editora#, etc.
 *   [CLIENTE] → #cliente_nome#, [PEDIDO] → #pedido_numero#, etc.
 *
 * @since 3.7.0
 */
function wcia_migrate_variables_370(): void {
    // Mapa de substituições (mais longos primeiro)
    $map = [
        // Opt-in checkout (formato {VARIAVEL} sem underscore)
        '{CURSO_LINKS}' => '#curso_links#',
        '{CURSO}' => '#curso_nome#',
        '{CLIENTE}' => '#cliente_nome#',
        '{PEDIDO}' => '#pedido_numero#',
        '{LISTA}' => '#lista_cursos#',
        // Grupos
        '[GRUPO_LINK]' => '#grupo_link#',
        // Templates cursos (formato {VARIAVEL} com underscore)
        '{PRECO_FMT}' => '#curso_preco_desconto#', '{LINK_CONCURSO}' => '#curso_link_concurso#',
        '{LINK_CARREIRA}' => '#curso_link_carreira#', '{MODALIDADE}' => '#curso_modalidade#',
        '{DETALHES}' => '#curso_detalhes#', '{DESCONTO}' => '#curso_desconto#',
        '{ORIGINAL}' => '#curso_original#', '{EDITORA}' => '#curso_editora#',
        '{CONCURSO}' => '#curso_concurso#', '{RODAPE}' => '#rodape#',
        '{CURSOS}' => '#lista_cursos#', '{OUTROS}' => '#outros_cursos#',
        '{EDITAL}' => '#curso_edital#', '{HORAS}' => '#curso_horas#',
        '{TOTAL}' => '#total_cursos#', '{PRECO}' => '#curso_preco#',
        '{NOME}' => '#curso_nome#', '{LINK}' => '#curso_link#',
        '{ANO}' => '#curso_ano#', '{NUM}' => '#num#', '{Q}' => '#busca#',
        // Notificações (formato [VARIAVEL])
        '[PRODUTOS_LINKS]' => '#pedido_links_produtos#', '[CHECKOUT_URL]' => '#checkout_url#',
        '[CUPOM_TEXTO]' => '#cupom_texto#', '[MINHA_CONTA]' => '#minha_conta#',
        '[PAGAMENTO]' => '#pedido_pagamento#', '[TELEFONE]' => '#cliente_telefone#',
        '[ENDERECO]' => '#cliente_endereco#', '[PRODUTOS]' => '#pedido_produtos#',
        '[CLIENTE]' => '#cliente_nome#', '[STATUS]' => '#pedido_status#',
        '[PEDIDO]' => '#pedido_numero#', '[TOTAL]' => '#pedido_total#',
        '[EMAIL]' => '#cliente_email#', '[DRIVE]' => '#pedido_drive#',
        '[LINK]' => '#pedido_link#', '[LINKS]' => '#pedido_links_produtos#',
        '[DATA]' => '#pedido_data#', '[SITE]' => '#site_url#',
    ];

    // Adicionar variáveis numeradas por curso: {NOME_1} → #curso_nome_1#, etc.
    $numbered_map = [
        'PRECO_FMT' => 'curso_preco_desconto', 'LINK_CONCURSO' => 'curso_link_concurso',
        'LINK_CARREIRA' => 'curso_link_carreira', 'MODALIDADE' => 'curso_modalidade',
        'DETALHES' => 'curso_detalhes', 'DESCONTO' => 'curso_desconto',
        'ORIGINAL' => 'curso_original', 'EDITORA' => 'curso_editora',
        'PRECO' => 'curso_preco', 'NOME' => 'curso_nome',
        'LINK' => 'curso_link', 'HORAS' => 'curso_horas',
        'EDITAL' => 'curso_edital', 'ANO' => 'curso_ano',
        'NUM' => 'num',
    ];
    for ( $n = 1; $n <= 8; $n++ ) {
        foreach ( $numbered_map as $old_key => $new_key ) {
            $map[ '{' . $old_key . '_' . $n . '}' ] = '#' . $new_key . '_' . $n . '#';
        }
    }
    // Também: {LINK_TODOS}
    $map['{LINK_TODOS}'] = '#link_todos#';

    $keys = array_keys( $map );
    $vals = array_values( $map );

    // Options que podem conter variáveis
    $option_keys = [
        'wcia_notification_templates',  // Templates de notificação por status
        'wcia_custom_notifications',    // Notificações customizadas
        'wcia_abandoned',               // Mensagem carrinho abandonado
        'wcia_courses',                 // Templates de novos cursos
        'wcia_checkout_optin',          // Opt-in checkout (mensagem padrão)
        'wcia_groups',                  // Convite pós-compra (mensagem)
    ];

    $migrated = 0;
    foreach ( $option_keys as $opt_key ) {
        $val = get_option( $opt_key );
        if ( ! $val ) continue;

        $json_before = wp_json_encode( $val );
        $json_after  = str_replace( $keys, $vals, $json_before );
        // Fix double ## (ex: #[PEDIDO] → ##pedido_numero#)
        $json_after  = preg_replace( '/##([\w]+)#/', '#$1#', $json_after );

        if ( $json_before !== $json_after ) {
            $new_val = json_decode( $json_after, true );
            if ( $new_val !== null ) {
                update_option( $opt_key, $new_val );
                $migrated++;
            }
        }
    }

    // Migrar template de cursos (wcia_search_templates)
    $tpls = get_option( 'wcia_search_templates' );
    if ( $tpls && is_array( $tpls ) ) {
        $json_before = wp_json_encode( $tpls );
        $json_after  = str_replace( $keys, $vals, $json_before );
        $json_after  = preg_replace( '/##([\w]+)#/', '#$1#', $json_after );
        if ( $json_before !== $json_after ) {
            $new_val = json_decode( $json_after, true );
            if ( $new_val !== null ) {
                update_option( 'wcia_search_templates', $new_val );
                $migrated++;
            }
        }
    }

    if ( $migrated > 0 ) {
        WCIA_Logs::add( 'system', '', true, '🔄 Migração v3.7.0: ' . $migrated . ' opções atualizadas para formato #variavel#' );
    }
}

/**
 * Migra variáveis de vendas do formato antigo {nome} para o padrão #variavel#.
 * @since 3.11.0
 */
function wcia_migrate_sales_variables(): void {
    $sales = get_option( 'wcia_sales', [] );
    if ( empty( $sales ) ) return;

    $map = [
        '{nome}'     => '#cliente_nome#',
        '{curso}'    => '#pedido_produtos#',
        '{pedido}'   => '#pedido_numero#',
        '{desconto}' => '#cupom_desconto#',
        '{cupom}'    => '#cupom_codigo#',
    ];

    $changed = false;
    $text_fields = [ 'followup_message', 'followup_options', 'upsell_message', 'promo_message' ];

    foreach ( $text_fields as $field ) {
        if ( ! empty( $sales[ $field ] ) ) {
            $original = $sales[ $field ];
            $sales[ $field ] = str_replace( array_keys( $map ), array_values( $map ), $sales[ $field ] );
            if ( $sales[ $field ] !== $original ) $changed = true;
        }
    }

    if ( $changed ) {
        update_option( 'wcia_sales', $sales );
        WCIA_Logs::add( 'system', '', true, '🔄 Migração v3.11.0: variáveis de vendas atualizadas para formato #variavel#' );
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://cursosrateio.com/wp-sitemap-index.xsl" ?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>https://cursosrateio.com/wp-sitemap-posts-post-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-posts-page-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-posts-product-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-posts-product-2.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-posts-product-3.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-posts-product-4.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-posts-product-5.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-posts-porto_builder-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-taxonomies-category-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-taxonomies-product_cat-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-taxonomies-product_tag-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-taxonomies-product_tag-2.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-taxonomies-product_tag-3.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-taxonomies-regiao-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-taxonomies-uf-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-taxonomies-concurso-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-taxonomies-concursos-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-taxonomies-modalidades-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-taxonomies-ano-1.xml</loc></sitemap><sitemap><loc>https://cursosrateio.com/wp-sitemap-taxonomies-edital-1.xml</loc></sitemap></sitemapindex>
