<?php
/**
 * includes/admin/import-diagnostics.php
 *
 * ============================================================================
 * DIAGNÓSTICO DE INTEGRIDADE DE IMPORTAÇÕES
 * ============================================================================
 *
 * Detecta inconsistências causadas pelo bug histórico (1.5.103 e antes) onde
 * imports diferentes do mesmo ficheiro partilhavam file_hash, e operações
 * (rejeitar, anular) afetavam dados de TODOS os imports daquele hash.
 *
 * Mostra:
 *   - Imports que partilham file_hash com outros (alto risco)
 *   - Linhas em ledger/daily_stats/comm sem import_log_id populado (legacy)
 *   - Imports aprovadas que perderam dados (ex: ledger zerado mas log está
 *     active+approved)
 *
 * Acessível via tab "🩺 Diagnóstico" em Distribuição (admin only).
 */

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


function rmbz_render_import_diagnostics() {
    if ( ! current_user_can('manage_options') ) wp_die('Sem permissão.');
    global $wpdb;

    $t_logs      = $wpdb->prefix . 'rmbz_distro_import_logs';
    $t_ledger    = $wpdb->prefix . 'rmbz_distro_ledger';
    $t_daily     = $wpdb->prefix . 'rmbz_distro_daily_stats';
    $t_unclaimed = $wpdb->prefix . 'rmbz_distro_unclaimed';
    $t_comm      = $wpdb->prefix . 'rmbz_distro_platform_commissions';

    ?>
    <div class="wrap" style="max-width:1100px;">
        <h2>🩺 Diagnóstico de Integridade de Importações</h2>
        <p style="color:var(--rmbz-text-muted, #666);">
            Esta página detecta inconsistências causadas por bugs históricos de gestão de file_hash.
            Útil para confirmar se algum dado foi estragado por operações anteriores à versão 1.5.104.
        </p>

        <?php
        // ─────────────────────────────────────────────────────────────────
        // 1. file_hash duplicados (múltiplos imports do mesmo ficheiro)
        // ─────────────────────────────────────────────────────────────────
        $duplicates = $wpdb->get_results(
            "SELECT file_hash, COUNT(*) AS n,
                    GROUP_CONCAT(id ORDER BY id) AS ids,
                    GROUP_CONCAT(status ORDER BY id) AS statuses,
                    GROUP_CONCAT(approval_status ORDER BY id) AS approvals
             FROM $t_logs
             GROUP BY file_hash
             HAVING n > 1
             ORDER BY n DESC, file_hash"
        );
        ?>

        <div class="card" style="padding:16px; max-width:none;">
            <h3 style="margin-top:0;">1. file_hash duplicados</h3>
            <p style="color:var(--rmbz-text-muted, #666);">
                Imports diferentes que partilham o mesmo file_hash (geralmente após "limpar hash"
                e re-importar). Antes da 1.5.104, operações nestes imports podiam afetar-se mutuamente.
            </p>
            <?php if ( empty($duplicates) ): ?>
                <p style="color:var(--rmbz-success-strong, #059669);"><strong>✓ Sem duplicados — OK.</strong></p>
            <?php else: ?>
                <table class="widefat striped">
                    <thead>
                        <tr>
                            <th>file_hash (curto)</th>
                            <th>Nº imports</th>
                            <th>IDs</th>
                            <th>Status</th>
                            <th>Approval</th>
                        </tr>
                    </thead>
                    <tbody>
                    <?php foreach ( $duplicates as $d ): ?>
                        <tr>
                            <td><code><?php echo esc_html( substr($d->file_hash, 0, 12) ); ?></code></td>
                            <td><strong style="color:var(--rmbz-danger-strong, #dc2626);"><?php echo (int) $d->n; ?></strong></td>
                            <td><?php echo esc_html($d->ids); ?></td>
                            <td><?php echo esc_html($d->statuses); ?></td>
                            <td><?php echo esc_html($d->approvals); ?></td>
                        </tr>
                    <?php endforeach; ?>
                    </tbody>
                </table>
            <?php endif; ?>
        </div>

        <?php
        // ─────────────────────────────────────────────────────────────────
        // 2. Imports aprovados/active sem dados em ledger (provável dano)
        // ─────────────────────────────────────────────────────────────────
        $orphan_logs = $wpdb->get_results(
            "SELECT il.id, il.file_hash, il.reporting_period, il.status, il.approval_status,
                    il.processed_rows, il.total_amount_usd,
                    (SELECT COUNT(*) FROM $t_ledger l WHERE l.import_hash = il.file_hash) AS ledger_count
             FROM $t_logs il
             WHERE il.status = 'active'
               AND il.approval_status = 'approved'
               AND il.processed_rows > 0
               AND (SELECT COUNT(*) FROM $t_ledger l WHERE l.import_hash = il.file_hash AND l.reverted_at IS NULL) = 0
             ORDER BY il.imported_at DESC"
        );
        ?>

        <div class="card" style="padding:16px; max-width:none; margin-top:16px;">
            <h3 style="margin-top:0;">2. Imports aprovadas sem dados activos no ledger</h3>
            <p style="color:var(--rmbz-text-muted, #666);">
                Imports marcadas como activas+aprovadas mas que não têm linhas no ledger.
                Provável sintoma de bug histórico — outro import com o mesmo hash foi rejeitado/anulado
                e levou os dados desta junto.
            </p>
            <?php if ( empty($orphan_logs) ): ?>
                <p style="color:var(--rmbz-success-strong, #059669);"><strong>✓ Sem imports aprovadas com dados em falta.</strong></p>
            <?php else: ?>
                <div class="notice notice-error" style="margin:8px 0; padding:12px;">
                    <strong>⚠ <?php echo count($orphan_logs); ?> import(s) aprovado(s) com dados em falta:</strong>
                </div>
                <table class="widefat striped">
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>Hash</th>
                            <th>Período</th>
                            <th>Status</th>
                            <th>Linhas processadas (no log)</th>
                            <th>Valor total (no log)</th>
                            <th>Linhas no ledger agora</th>
                        </tr>
                    </thead>
                    <tbody>
                    <?php foreach ( $orphan_logs as $o ): ?>
                        <tr>
                            <td><?php echo (int) $o->id; ?></td>
                            <td><code><?php echo esc_html( substr($o->file_hash, 0, 12) ); ?></code></td>
                            <td><?php echo esc_html($o->reporting_period); ?></td>
                            <td><?php echo esc_html($o->status . ' / ' . $o->approval_status); ?></td>
                            <td><?php echo number_format( (int) $o->processed_rows ); ?></td>
                            <td>$<?php echo number_format( (float) $o->total_amount_usd, 2 ); ?></td>
                            <td style="color:<?php echo (int)$o->ledger_count === 0 ? '#c00' : '#444'; ?>;">
                                <strong><?php echo (int) $o->ledger_count; ?></strong>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                    </tbody>
                </table>
                <p style="margin-top:12px; color:var(--rmbz-text-muted, #666); font-size:12px;">
                    💡 <strong>Recuperação possível:</strong> se tens o CSV original, podes usar
                    "Limpar hash" → re-importar. Os dados antigos do log servem como prova histórica.
                </p>
            <?php endif; ?>
        </div>

        <?php
        // ─────────────────────────────────────────────────────────────────
        // 3. Linhas legacy sem import_log_id (informativo)
        // ─────────────────────────────────────────────────────────────────
        $legacy_counts = [];
        foreach ( ['ledger' => $t_ledger, 'daily_stats' => $t_daily, 'unclaimed' => $t_unclaimed, 'commissions' => $t_comm] as $label => $tbl ) {
            if ( $wpdb->get_var("SHOW TABLES LIKE '$tbl'") !== $tbl ) continue;
            $cols = $wpdb->get_col("SHOW COLUMNS FROM $tbl");
            if ( ! in_array('import_log_id', $cols, true) ) continue;
            $legacy_counts[$label] = (int) $wpdb->get_var("SELECT COUNT(*) FROM $tbl WHERE import_log_id IS NULL AND import_hash IS NOT NULL");
        }
        ?>

        <div class="card" style="padding:16px; max-width:none; margin-top:16px;">
            <h3 style="margin-top:0;">3. Linhas legacy (informativo)</h3>
            <p style="color:var(--rmbz-text-muted, #666);">
                Linhas criadas antes da 1.5.104 que ainda não têm <code>import_log_id</code> populado.
                Continuam a funcionar com fallback hash+período. Se houver poucos duplicados de file_hash
                (Secção 1), o impacto é nulo.
            </p>
            <ul>
                <?php foreach ( $legacy_counts as $label => $n ): ?>
                    <li><?php echo esc_html(ucfirst($label)); ?>: <strong><?php echo number_format($n); ?></strong> linha(s) sem import_log_id</li>
                <?php endforeach; ?>
            </ul>
        </div>

        <?php
        // ─────────────────────────────────────────────────────────────────
        // [DS 1.5.109] 4. Arquivo de CSVs e gestão de espaço
        // ─────────────────────────────────────────────────────────────────
        if ( ! function_exists('rmbz_archive_preview_purge') ) {
            // Módulo de archive não carregado (defensivo)
            ?>
            <div class="card" style="padding:16px; max-width:none; margin-top:16px;">
                <h3 style="margin-top:0;">4. Arquivo de CSVs</h3>
                <p style="color:var(--rmbz-text-muted, #888);">Módulo de arquivo não está carregado.</p>
            </div>
            </div>
            <?php
            return;
        }

        // Processar acção de purga manual
        if ( isset($_POST['rmbz_purge_archive']) && check_admin_referer('rmbz_purge_archive_action') ) {
            $result = rmbz_archive_purge_old( 500 );
            ?>
            <div class="notice notice-success is-dismissible" style="margin-top:16px;">
                <p>
                    <strong>✓ Purga concluída:</strong>
                    <?php echo (int) $result['deleted']; ?> ficheiro(s) apagado(s),
                    <?php echo size_format($result['bytes_freed']); ?> libertado(s)
                    <?php if ( $result['errors'] > 0 ): ?>
                        — <span style="color:var(--rmbz-danger-strong, #dc2626);"><?php echo (int) $result['errors']; ?> erro(s) (ver error log)</span>
                    <?php endif; ?>
                </p>
            </div>
            <?php
        }

        // Processar mudança de retention
        if ( isset($_POST['rmbz_save_retention']) && check_admin_referer('rmbz_save_retention_action') ) {
            $new_days = max(30, (int) ($_POST['retention_days'] ?? 730));
            update_option( 'rmbz_csv_archive_retention_days', $new_days, false );
            echo '<div class="notice notice-success is-dismissible" style="margin-top:16px;"><p>✓ Retenção actualizada: <strong>' . $new_days . ' dias</strong></p></div>';
        }

        $preview = rmbz_archive_preview_purge();
        $archive_dir = rmbz_imports_archive_dir();
        $total_files = 0;
        $total_size  = 0;
        if ( ! empty($archive_dir) ) {
            $glob_files = glob( $archive_dir . '/*.csv' );
            $total_files = is_array($glob_files) ? count($glob_files) : 0;
            $total_size  = rmbz_archive_total_size();
        }
        $next_cron = wp_next_scheduled('rmbz_archive_daily_purge');
        ?>

        <div class="card" style="padding:16px; max-width:none; margin-top:16px;">
            <h3 style="margin-top:0;">4. Arquivo de CSVs (gestão de espaço)</h3>
            <p style="color:var(--rmbz-text-muted, #666);">
                Cada importação preserva o CSV original em
                <code>/wp-content/uploads/rmbz_imports_archive/</code> para permitir
                "Desfazer Anulação". Ficheiros antigos são apagados automaticamente
                após o período de retenção. Os dados financeiros (ledger, comissões)
                são mantidos para sempre — só o CSV físico é removido.
            </p>

            <table class="widefat" style="margin-bottom:16px;">
                <tbody>
                    <tr>
                        <td><strong>Espaço actualmente usado</strong></td>
                        <td><?php echo size_format($total_size); ?> em <?php echo number_format($total_files); ?> ficheiro(s)</td>
                    </tr>
                    <tr>
                        <td><strong>Período de retenção</strong></td>
                        <td>
                            <form method="post" style="display:inline-flex; gap:8px; align-items:center;">
                                <?php wp_nonce_field('rmbz_save_retention_action'); ?>
                                <input type="number" name="retention_days" min="30" max="3650"
                                       value="<?php echo esc_attr(rmbz_archive_retention_days()); ?>"
                                       style="width:90px;">
                                <span style="color:var(--rmbz-text-muted, #888);">dias</span>
                                <button type="submit" name="rmbz_save_retention" class="button button-small">Guardar</button>
                                <span style="color:var(--rmbz-text-muted, #888); font-size:11px;">(default 730 = 2 anos · mínimo 30)</span>
                            </form>
                        </td>
                    </tr>
                    <tr>
                        <td><strong>Próxima limpeza automática</strong></td>
                        <td>
                            <?php if ( $next_cron ): ?>
                                <?php echo esc_html(human_time_diff(time(), $next_cron) . ' (' . wp_date('Y-m-d H:i', $next_cron) . ')'); ?>
                            <?php else: ?>
                                <span style="color:var(--rmbz-danger-strong, #dc2626);">Cron não agendado</span>
                            <?php endif; ?>
                        </td>
                    </tr>
                </tbody>
            </table>

            <?php if ( $preview['count'] > 0 ): ?>
                <div style="background:var(--rmbz-bg-surface, #fff)9e6; border:1px solid #f0b90b; border-radius:6px; padding:14px; margin-bottom:14px;">
                    <p style="margin:0 0 8px 0;">
                        <strong>🧹 <?php echo (int) $preview['count']; ?> ficheiro(s) elegíveis para limpeza</strong>
                        — <?php echo size_format($preview['total_bytes']); ?> a libertar
                    </p>
                    <p style="margin:0 0 12px 0; font-size:12px; color:var(--rmbz-text-muted, #666);">
                        Importados antes de <?php echo esc_html($preview['cutoff_date']); ?>
                        (mais de <?php echo (int) $preview['retention_days']; ?> dias).
                        Os dados financeiros são preservados — só o CSV físico é apagado.
                    </p>

                    <?php if ( ! empty($preview['sample']) ): ?>
                        <details style="margin-bottom:12px;">
                            <summary style="cursor:pointer; font-size:12px; color:var(--rmbz-info-strong, #2563eb);">Ver amostra (até 5 entradas)</summary>
                            <table class="widefat" style="margin-top:8px; font-size:12px;">
                                <thead>
                                    <tr><th>ID</th><th>Hash</th><th>Período</th><th>Importado</th><th>Idade</th><th>Tamanho</th></tr>
                                </thead>
                                <tbody>
                                    <?php foreach ( $preview['sample'] as $s ): ?>
                                        <tr>
                                            <td>#<?php echo (int) $s['id']; ?></td>
                                            <td><code><?php echo esc_html($s['hash']); ?></code></td>
                                            <td><?php echo esc_html($s['period']); ?></td>
                                            <td><?php echo esc_html($s['imported']); ?></td>
                                            <td><?php echo (int) $s['age_days']; ?> dias</td>
                                            <td><?php echo size_format($s['size_bytes']); ?></td>
                                        </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>
                        </details>
                    <?php endif; ?>

                    <form method="post" style="display:inline;">
                        <?php wp_nonce_field('rmbz_purge_archive_action'); ?>
                        <button type="submit" name="rmbz_purge_archive" class="button button-primary"
                                onclick="return confirm('🧹 Limpar <?php echo (int) $preview['count']; ?> ficheiro(s) CSV antigo(s)?\n\nLibertará ' + '<?php echo esc_js(size_format($preview['total_bytes'])); ?>'.\n\nOs dados financeiros são preservados — só o CSV físico é apagado.\n\nNão poderás \"Desfazer Anulação\" destas importações depois.\n\nContinuar?');">
                            🧹 Executar limpeza agora
                        </button>
                    </form>
                </div>
            <?php else: ?>
                <p style="color:var(--rmbz-success-strong, #059669); margin:0;">
                    <strong>✓ Sem ficheiros elegíveis para limpeza.</strong>
                    Nada a fazer agora — o cron diário trata disto automaticamente quando algum CSV passar dos
                    <?php echo (int) $preview['retention_days']; ?> dias.
                </p>
            <?php endif; ?>
        </div>

        <?php
        // ─────────────────────────────────────────────────────────────────
        // [DS 1.5.110] 5. Wallets MT afectadas pelo bug USD-tratado-como-MT
        // ─────────────────────────────────────────────────────────────────
        if ( ! function_exists('rmbz_wallet_mt_list_affected') ) {
            ?>
            <div class="card" style="padding:16px; max-width:none; margin-top:16px;">
                <h3 style="margin-top:0;">5. Wallets MT afectadas (bug pre-1.5.110)</h3>
                <p style="color:var(--rmbz-text-muted, #888);">Módulo de limpeza não está carregado.</p>
            </div>
            </div>
            <?php
            return;
        }

        // Processar correção individual se admin clicou
        if ( isset($_POST['rmbz_apply_mt_fix']) && check_admin_referer('rmbz_apply_mt_fix_action') ) {
            $tel    = sanitize_text_field($_POST['telemovel'] ?? '');
            $amount = (float) ($_POST['amount'] ?? 0);
            $note   = sanitize_textarea_field($_POST['note'] ?? '');
            $r = rmbz_wallet_mt_apply_correction($tel, $amount, $note);
            $css = $r['success'] ? 'notice-success' : 'notice-error';
            echo '<div class="notice ' . $css . ' is-dismissible" style="margin-top:16px;"><p>' . esc_html($r['message']) . '</p></div>';
        }

        // [1.5.147] Processar anulação de correção previamente aplicada
        if ( isset($_POST['rmbz_undo_mt_fix']) && check_admin_referer('rmbz_undo_mt_fix_action') ) {
            $tx_id = (int) ($_POST['transaction_id'] ?? 0);
            $r = rmbz_wallet_mt_undo_correction($tx_id);
            $css = $r['success'] ? 'notice-success' : 'notice-error';
            echo '<div class="notice ' . $css . ' is-dismissible" style="margin-top:16px;"><p>' . esc_html($r['message']) . '</p></div>';
        }

        $affected = rmbz_wallet_mt_list_affected();
        // Filtrar só os que ainda têm "lixo" para corrigir (net_wrong > 0.01)
        $to_fix = array_filter($affected, function($r) {
            return $r->net_wrong > 0.01;
        });
        $rate = function_exists('rmbz_get_exchange_rate') ? (float) rmbz_get_exchange_rate() : 63.50;
        ?>

        <div class="card" style="padding:16px; max-width:none; margin-top:16px;">
            <h3 style="margin-top:0;">5. Wallets MT com créditos errados (bug pre-1.5.110)</h3>
            <p style="color:var(--rmbz-text-muted, #666);">
                Antes da 1.5.110, royalties USD eram somados directamente à carteira em MT
                sem conversão de câmbio. Esta secção lista artistas afectados e permite
                corrigir caso a caso. <strong>Nada é automático</strong> — cada caso pode
                ter histórico próprio (artistas podem já ter levantado parte do dinheiro,
                etc.). Câmbio actual nas configurações:
                <code><?php echo number_format($rate, 2); ?> MT/USD</code>.
            </p>

            <?php if ( empty($to_fix) ): ?>
                <p style="color:var(--rmbz-success-strong, #059669); margin:0;">
                    <strong>✓ Nenhuma wallet com lixo a corrigir.</strong>
                    Ou nunca houve aprovações de imports/matches que tocassem a wallet,
                    ou já foram todos corrigidos.
                </p>
            <?php else: ?>
                <div class="notice notice-warning" style="margin-bottom:16px; padding:12px;">
                    <p style="margin:0;">
                        <strong>⚠ <?php echo count($to_fix); ?> artista(s) afectado(s).</strong>
                        Total acumulado de "lixo" na wallet:
                        <?php
                        $total_garbage = array_sum(array_column($to_fix, 'net_wrong'));
                        echo number_format($total_garbage, 2) . ' (USD-tratado-como-MT)';
                        ?>
                    </p>
                </div>

                <table class="widefat striped" style="font-size:12px;">
                    <thead>
                        <tr>
                            <th>Telemóvel</th>
                            <th style="text-align:right;">Crédito errado</th>
                            <th style="text-align:right;">Já debitado (revert)</th>
                            <th style="text-align:right;">Lixo actual</th>
                            <th style="text-align:right;">Equivalente MT correcto<br><small style="color:var(--rmbz-text-muted, #888);">(se devesse ser convertido)</small></th>
                            <th style="text-align:right;">Diferença a corrigir</th>
                            <th>Acção</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ( $to_fix as $a ):
                            $correct_mt_if_converted = $a->net_wrong * $rate;
                            $diff_to_correct = $a->net_wrong; // O lixo é o que está a mais; debitar tudo torna ao certo
                        ?>
                            <tr>
                                <td>
                                    <code><?php echo esc_html($a->user_telemovel); ?></code>
                                    <br>
                                    <small style="color:var(--rmbz-text-muted, #888);"><?php echo (int) $a->tx_count; ?> transação(ões)</small>
                                </td>
                                <td style="text-align:right; color:var(--rmbz-danger-strong, #dc2626);">
                                    +<?php echo number_format($a->total_credited_wrong, 2); ?>
                                </td>
                                <td style="text-align:right; color:var(--rmbz-text-muted, #888);">
                                    <?php echo number_format($a->total_debited_wrong, 2); ?>
                                </td>
                                <td style="text-align:right;">
                                    <strong><?php echo number_format($a->net_wrong, 2); ?> MT</strong>
                                </td>
                                <td style="text-align:right; color:var(--rmbz-text-muted, #888);">
                                    <?php echo number_format($correct_mt_if_converted, 2); ?> MT
                                </td>
                                <td style="text-align:right; color:var(--rmbz-danger-strong, #dc2626);">
                                    <strong>-<?php echo number_format($diff_to_correct, 2); ?> MT</strong>
                                </td>
                                <td>
                                    <a href="<?php echo esc_url(add_query_arg('inspect_tel', $a->user_telemovel, $_SERVER['REQUEST_URI'])); ?>#inspect-<?php echo esc_attr(md5($a->user_telemovel)); ?>"
                                       class="button button-small button-primary" style="margin-right:4px;">
                                        🔍 Inspeccionar e Debitar
                                    </a>
                                    <span style="font-size:11px; color:var(--rmbz-text-muted, #888);">
                                        (preview antes de debitar)
                                    </span>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>

                <p style="margin-top:12px; font-size:12px; color:var(--rmbz-text-muted, #666);">
                    💡 Cada débito é registado em <code>wallet_transactions</code> com
                    <code>type='mt_fix_correction'</code> e marker <code>[mtfix:TIMESTAMP]</code>
                    para auditoria. Saldo pode ficar negativo — o artista terá de cobrir
                    antes de levantamentos futuros.
                </p>

                <?php
                // ─────────────────────────────────────────────────────────
                // [DS 1.5.113 / 1.5.147] Inspector — mostra breakdown se admin
                // clicou num "🔍 Inspeccionar e Debitar". Inclui:
                //   - Composição por categoria
                //   - Markers únicos vs duplicados
                //   - Distribuição mensal
                //   - Histórico de transações afectadas (paginado)
                //   - Histórico de correções já aplicadas (com undo)
                //   - Painel de débito parcial com PREVIEW LIVE via AJAX
                // ─────────────────────────────────────────────────────────
                if ( ! empty($_GET['inspect_tel']) ) {
                    $inspect_tel = sanitize_text_field( $_GET['inspect_tel'] );

                    // Paginação das transações afectadas
                    $insp_page     = max( 1, (int) ( $_GET['insp_page'] ?? 1 ) );
                    $insp_per_page = 100;
                    $insp_total    = rmbz_wallet_mt_count_artist_details( $inspect_tel );
                    $insp_pages    = max( 1, (int) ceil( $insp_total / $insp_per_page ) );

                    $breakdown    = rmbz_wallet_mt_artist_breakdown( $inspect_tel );
                    $details      = rmbz_wallet_mt_get_artist_details( $inspect_tel, $insp_page, $insp_per_page );
                    $corrections  = rmbz_wallet_mt_get_corrections_history( $inspect_tel );

                    // Calcular net_wrong para esta wallet (= valor sugerido para débito)
                    $insp_record = null;
                    foreach ( $affected as $a ) {
                        if ( $a->user_telemovel === $inspect_tel ) { $insp_record = $a; break; }
                    }
                    $insp_net_wrong = $insp_record ? (float) $insp_record->net_wrong : 0;

                    // Saldo actual da wallet — para preview e cálculo de "débito seguro"
                    global $wpdb;
                    $insp_balance = (float) $wpdb->get_var( $wpdb->prepare(
                        "SELECT balance FROM {$wpdb->prefix}rmbz_wallets WHERE user_telemovel = %s",
                        $inspect_tel
                    ) );
                    $insp_safe_max = max( 0, $insp_balance );
                    ?>
                    <div id="inspect-<?php echo esc_attr(md5($inspect_tel)); ?>"
                         style="margin-top:24px; padding:16px; background:var(--rmbz-bg-elevated, #f9f9f9); border:2px solid var(--rmbz-info-strong, #2563eb); border-radius:6px;">
                        <h4 style="margin-top:0;">🔍 Inspecção de <?php echo esc_html($inspect_tel); ?></h4>

                        <h5>Composição por categoria</h5>
                        <?php if ( empty($breakdown['by_type']) ): ?>
                            <p style="color:var(--rmbz-text-muted, #888);">Sem transações.</p>
                        <?php else: ?>
                            <table class="widefat striped" style="font-size:12px; max-width:780px;">
                                <thead>
                                    <tr>
                                        <th>Categoria</th>
                                        <th style="text-align:right;">Nº transações</th>
                                        <th style="text-align:right;">Total MT</th>
                                        <th style="text-align:right;">Média MT</th>
                                        <th>Primeiro</th>
                                        <th>Último</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <?php foreach ( $breakdown['by_type'] as $b ):
                                        $bucket_label = [
                                            'import' => '📥 Import (royalty_payout)',
                                            'match'  => '🔗 Match Review',
                                            'revert' => '↩ Revert antigo',
                                            'fix'    => '🧹 Correção 1.5.111',
                                            'other'  => '❓ Outro',
                                        ];
                                    ?>
                                        <tr>
                                            <td><?php echo esc_html($bucket_label[$b->bucket] ?? $b->bucket); ?></td>
                                            <td style="text-align:right;"><strong><?php echo number_format($b->cnt); ?></strong></td>
                                            <td style="text-align:right;"><?php echo number_format($b->total, 2); ?></td>
                                            <td style="text-align:right; color:var(--rmbz-text-muted, #888);"><?php echo number_format($b->avg_amount, 4); ?></td>
                                            <td style="font-size:11px;"><?php echo esc_html(mysql2date('d/m/Y', $b->min_date)); ?></td>
                                            <td style="font-size:11px;"><?php echo esc_html(mysql2date('d/m/Y', $b->max_date)); ?></td>
                                        </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>
                        <?php endif; ?>

                        <?php
                        // RED FLAG: muitas transacções vs poucos markers únicos = duplicação
                        $total_creditante = 0;
                        foreach ( $breakdown['by_type'] as $b ) {
                            if ( in_array($b->bucket, ['import', 'match'], true) ) $total_creditante += $b->cnt;
                        }
                        $unique = $breakdown['unique_markers'];
                        if ( $unique > 0 && $total_creditante > 0 ):
                            $ratio = $total_creditante / $unique;
                        ?>
                            <div style="margin-top:12px; padding:10px; border-radius:4px;
                                background:<?php echo $ratio > 5 ? '#fff5f5' : '#f0f8ff'; ?>;
                                border:1px solid <?php echo $ratio > 5 ? '#c0392b' : '#0073aa'; ?>;">
                                <strong>Markers únicos vs transacções:</strong>
                                <?php echo number_format($unique); ?> markers únicos para
                                <?php echo number_format($total_creditante); ?> transação(ões) creditadas
                                — rácio <strong><?php echo number_format($ratio, 1); ?>x</strong>
                                <?php if ( $ratio > 5 ): ?>
                                    <br><span style="color:var(--rmbz-danger-strong, #dc2626);">⚠ Rácio anormalmente alto. Cada import/match único devia gerar UMA transação. Pode haver duplicação.</span>
                                <?php elseif ( $ratio > 1.5 ): ?>
                                    <br><span style="color:var(--rmbz-text-muted, #888);">⓵ Rácio elevado mas pode ser normal se há splits com vários colaboradores.</span>
                                <?php else: ?>
                                    <br><span style="color:var(--rmbz-success-strong, #059669);">✓ Rácio normal.</span>
                                <?php endif; ?>
                            </div>
                        <?php endif; ?>

                        <?php if ( ! empty($breakdown['repeating']) ): ?>
                            <h5 style="margin-top:16px;">Markers que se repetem (top 10)</h5>
                            <p style="font-size:12px; color:var(--rmbz-text-muted, #666);">
                                Se um marker aparece muitas vezes, o mesmo import/match foi creditado
                                repetidamente — possível bug de race condition.
                            </p>
                            <table class="widefat striped" style="font-size:12px; max-width:780px;">
                                <thead><tr><th>Marker</th><th style="text-align:right;">Vezes</th><th style="text-align:right;">Total creditado</th></tr></thead>
                                <tbody>
                                    <?php foreach ( $breakdown['repeating'] as $r ): ?>
                                        <tr>
                                            <td><code><?php echo esc_html($r->marker); ?></code></td>
                                            <td style="text-align:right;
                                                <?php echo $r->occurrences > 10 ? 'color:var(--rmbz-danger-strong, #dc2626); font-weight:bold;' : ''; ?>">
                                                <?php echo number_format($r->occurrences); ?>×
                                            </td>
                                            <td style="text-align:right;"><?php echo number_format($r->total_credited, 2); ?> MT</td>
                                        </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>
                        <?php else: ?>
                            <p style="color:var(--rmbz-success-strong, #059669); margin-top:12px;">
                                ✓ Cada marker é único — sem duplicação detectada.
                            </p>
                        <?php endif; ?>

                        <?php if ( ! empty($breakdown['by_month']) ): ?>
                            <h5 style="margin-top:16px;">Distribuição por mês (últimos 12)</h5>
                            <table class="widefat striped" style="font-size:12px; max-width:520px;">
                                <thead><tr><th>Mês</th><th style="text-align:right;">Nº transações</th><th style="text-align:right;">Total MT</th></tr></thead>
                                <tbody>
                                    <?php foreach ( $breakdown['by_month'] as $m ): ?>
                                        <tr>
                                            <td><?php echo esc_html($m->month); ?></td>
                                            <td style="text-align:right;"><?php echo number_format($m->cnt); ?></td>
                                            <td style="text-align:right;"><?php echo number_format($m->total, 2); ?></td>
                                        </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>
                        <?php endif; ?>

                        <h5 style="margin-top:16px;">
                            Histórico de transações afectadas
                            <span style="font-weight:normal; color:var(--rmbz-text-muted, #888); font-size:13px;">
                                (página <?php echo (int) $insp_page; ?> de <?php echo (int) $insp_pages; ?> · total <?php echo number_format($insp_total); ?>)
                            </span>
                        </h5>
                        <div style="max-height:400px; overflow-y:auto; border:1px solid var(--rmbz-border-subtle, #ddd); border-radius:4px;">
                            <table class="widefat striped" style="font-size:11px;">
                                <thead style="position:sticky; top:0; background:var(--rmbz-bg-surface, #fff); z-index:1;">
                                    <tr><th>Data</th><th>Tipo</th><th style="text-align:right;">Valor</th><th>Detalhes</th></tr>
                                </thead>
                                <tbody>
                                    <?php foreach ( $details as $d ): ?>
                                        <tr>
                                            <td><?php echo esc_html(mysql2date('d/m/Y H:i', $d->transaction_date)); ?></td>
                                            <td><code style="font-size:10px;"><?php echo esc_html($d->type); ?></code></td>
                                            <td style="text-align:right; color:<?php echo (float) $d->amount >= 0 ? '#27ae60' : '#c0392b'; ?>;">
                                                <?php echo number_format((float) $d->amount, 2); ?>
                                            </td>
                                            <td style="font-size:10px;"><?php echo esc_html(mb_strimwidth($d->details, 0, 120, '…')); ?></td>
                                        </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>
                        </div>

                        <?php /* [1.5.147] Paginação simples para o histórico — útil
                            quando uma wallet tem 1000+ transações afectadas */ ?>
                        <?php if ( $insp_pages > 1 ): ?>
                            <div style="margin-top:8px; display:flex; gap:6px; align-items:center; font-size:12px;">
                                <span style="color:var(--rmbz-text-muted, #888);">Página:</span>
                                <?php
                                // Truncação inteligente: 1 ... atual-1 atual atual+1 ... última
                                $pages_to_show = [];
                                if ( $insp_pages <= 7 ) {
                                    for ( $i = 1; $i <= $insp_pages; $i++ ) $pages_to_show[] = $i;
                                } else {
                                    $pages_to_show[] = 1;
                                    if ( $insp_page > 3 ) $pages_to_show[] = '...';
                                    for ( $i = max(2, $insp_page - 1); $i <= min($insp_pages - 1, $insp_page + 1); $i++ ) {
                                        $pages_to_show[] = $i;
                                    }
                                    if ( $insp_page < $insp_pages - 2 ) $pages_to_show[] = '...';
                                    $pages_to_show[] = $insp_pages;
                                }
                                foreach ( $pages_to_show as $p ):
                                    if ( $p === '...' ) {
                                        echo '<span style="color:#aaa;">…</span>';
                                        continue;
                                    }
                                    $url = esc_url(add_query_arg('insp_page', $p)) . '#inspect-' . esc_attr(md5($inspect_tel));
                                    if ( (int) $p === (int) $insp_page ) {
                                        echo '<strong style="background:#0073aa; color:#fff; padding:3px 9px; border-radius:3px;">' . (int) $p . '</strong>';
                                    } else {
                                        echo '<a href="' . $url . '" class="button button-small">' . (int) $p . '</a>';
                                    }
                                endforeach;
                                ?>
                            </div>
                        <?php endif; ?>

                        <?php /* ──────────────────────────────────────────────────
                            [1.5.147] HISTÓRICO DE CORREÇÕES JÁ APLICADAS
                            ────────────────────────────────────────────────── */ ?>
                        <?php if ( ! empty($corrections) ): ?>
                            <h5 style="margin-top:24px;">
                                🧹 Correções já aplicadas
                                <span style="font-weight:normal; color:var(--rmbz-text-muted, #888); font-size:13px;">
                                    (<?php echo count($corrections); ?>)
                                </span>
                            </h5>
                            <p style="font-size:12px; color:var(--rmbz-text-muted, #666); margin:4px 0 8px;">
                                Auditoria de correções <code>type='mt_fix_correction'</code> previamente
                                executadas. Podes anular individualmente se foi engano (devolve o valor à wallet).
                            </p>
                            <table class="widefat striped" style="font-size:12px; max-width:980px;">
                                <thead>
                                    <tr>
                                        <th width="140">Data</th>
                                        <th style="text-align:right;" width="100">Debitado</th>
                                        <th>Detalhes</th>
                                        <th width="120">Acção</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <?php foreach ( $corrections as $c ):
                                        // Detectar se já foi anulada (procurar mt_fix_undo com este tx id)
                                        $is_undone = (int) $wpdb->get_var( $wpdb->prepare(
                                            "SELECT COUNT(*) FROM {$wpdb->prefix}rmbz_wallet_transactions
                                             WHERE type = 'mt_fix_undo'
                                               AND details LIKE %s",
                                            '%[undo:' . (int) $c->transaction_id . ']%'
                                        ) );
                                    ?>
                                        <tr style="<?php echo $is_undone ? 'opacity:0.55;' : ''; ?>">
                                            <td><?php echo esc_html(mysql2date('d/m/Y H:i', $c->transaction_date)); ?></td>
                                            <td style="text-align:right; color:var(--rmbz-danger-strong, #dc2626); font-weight:bold;">
                                                <?php echo number_format( (float) $c->amount, 2 ); ?>
                                            </td>
                                            <td style="font-size:11px;">
                                                <?php echo esc_html(mb_strimwidth($c->details, 0, 200, '…')); ?>
                                            </td>
                                            <td>
                                                <?php if ( $is_undone ): ?>
                                                    <span style="color:var(--rmbz-success-strong, #059669); font-size:11px;">✓ Já anulada</span>
                                                <?php else: ?>
                                                    <form method="post" style="display:inline;"
                                                          onsubmit="return confirm('Anular esta correção? Vai DEVOLVER <?php echo number_format(abs((float) $c->amount), 2); ?> MT à wallet de <?php echo esc_js($inspect_tel); ?>.\n\nEsta operação é registada como mt_fix_undo no extrato.\n\nContinuar?');">
                                                        <?php wp_nonce_field('rmbz_undo_mt_fix_action'); ?>
                                                        <input type="hidden" name="transaction_id" value="<?php echo (int) $c->transaction_id; ?>">
                                                        <button type="submit" name="rmbz_undo_mt_fix" class="button button-small">
                                                            ↩ Anular
                                                        </button>
                                                    </form>
                                                <?php endif; ?>
                                            </td>
                                        </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>
                        <?php endif; ?>

                        <?php /* ──────────────────────────────────────────────────
                            [1.5.147] PAINEL DE DÉBITO PARCIAL COM PREVIEW LIVE
                            Substitui o botão "Debitar" simples antigo. Permite
                            ao admin escolher o valor exacto, com 3 quick-presets
                            e preview live via AJAX antes de confirmar.
                            ────────────────────────────────────────────────── */ ?>
                        <?php if ( $insp_net_wrong > 0.01 ): ?>
                            <h5 style="margin-top:24px;">⚠ Aplicar correção</h5>
                            <div style="background:var(--rmbz-bg-surface, #fff); border:1px solid var(--rmbz-danger-strong, #dc2626); border-radius:6px; padding:14px; max-width:780px;">

                                <div style="display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:14px;">
                                    <div style="background:var(--rmbz-bg-elevated, #f9f9f9); padding:10px; border-radius:4px;">
                                        <div style="font-size:11px; color:var(--rmbz-text-muted, #666); text-transform:uppercase; letter-spacing:0.05em;">Saldo actual</div>
                                        <div style="font-size:18px; font-weight:bold;">
                                            <?php echo number_format($insp_balance, 2); ?> MT
                                        </div>
                                    </div>
                                    <div style="background:var(--rmbz-bg-surface, #fff)8f0; padding:10px; border-radius:4px;">
                                        <div style="font-size:11px; color:var(--rmbz-text-muted, #666); text-transform:uppercase; letter-spacing:0.05em;">Lixo a corrigir (net_wrong)</div>
                                        <div style="font-size:18px; font-weight:bold; color:var(--rmbz-danger-strong, #dc2626);">
                                            <?php echo number_format($insp_net_wrong, 2); ?> MT
                                        </div>
                                    </div>
                                </div>

                                <p style="font-size:12px; margin:0 0 10px; color:var(--rmbz-text-muted, #666);">
                                    Escolhe quanto debitar. Usa os botões para presets ou escreve o valor à mão.
                                </p>

                                <div style="display:flex; gap:6px; flex-wrap:wrap; margin-bottom:10px;">
                                    <button type="button" class="button button-small rmbz-mtfix-preset"
                                            data-amount="<?php echo number_format($insp_net_wrong, 2, '.', ''); ?>">
                                        💯 Tudo (<?php echo number_format($insp_net_wrong, 2); ?> MT)
                                    </button>
                                    <button type="button" class="button button-small rmbz-mtfix-preset"
                                            data-amount="<?php echo number_format( min($insp_net_wrong, $insp_safe_max), 2, '.', ''); ?>">
                                        🛡 Seguro (<?php echo number_format( min($insp_net_wrong, $insp_safe_max), 2 ); ?> MT)
                                    </button>
                                    <button type="button" class="button button-small rmbz-mtfix-preset"
                                            data-amount="<?php echo number_format( $insp_net_wrong / 2, 2, '.', ''); ?>">
                                        ½ Metade (<?php echo number_format( $insp_net_wrong / 2, 2 ); ?> MT)
                                    </button>
                                </div>

                                <form method="post" id="rmbz-mtfix-form-<?php echo esc_attr(md5($inspect_tel)); ?>">
                                    <?php wp_nonce_field('rmbz_apply_mt_fix_action'); ?>
                                    <input type="hidden" name="telemovel" value="<?php echo esc_attr($inspect_tel); ?>">

                                    <div style="display:flex; gap:8px; align-items:center; margin-bottom:10px;">
                                        <label style="font-weight:bold; min-width:120px;">Valor a debitar:</label>
                                        <input type="number" step="0.01" min="0.01" max="<?php echo number_format($insp_net_wrong, 2, '.', ''); ?>"
                                               name="amount" id="rmbz-mtfix-amount-<?php echo esc_attr(md5($inspect_tel)); ?>"
                                               value="<?php echo number_format($insp_net_wrong, 2, '.', ''); ?>"
                                               class="rmbz-mtfix-amount-input"
                                               style="width:140px; font-size:14px; font-weight:bold;">
                                        <span style="color:var(--rmbz-text-muted, #666);">MT</span>
                                    </div>

                                    <div style="margin-bottom:10px;">
                                        <label style="font-weight:bold; display:block; margin-bottom:4px;">Nota (opcional):</label>
                                        <input type="text" name="note" placeholder="Ex: Artista contactou e aprovou correção parcial"
                                               style="width:100%; max-width:600px;">
                                    </div>

                                    <?php /* Preview box — actualizada via JS com cores conforme severidade */ ?>
                                    <div id="rmbz-mtfix-preview-<?php echo esc_attr(md5($inspect_tel)); ?>"
                                         class="rmbz-mtfix-preview"
                                         style="margin:12px 0; padding:12px; border-radius:4px; background:var(--rmbz-info-soft, #f0f8ff); border:1px solid var(--rmbz-info-strong, #2563eb);">
                                        <div style="display:flex; justify-content:space-between; align-items:center;">
                                            <div>
                                                <span style="color:var(--rmbz-text-muted, #666); font-size:12px;">Saldo após débito:</span>
                                                <strong class="rmbz-mtfix-new-balance" style="font-size:16px; margin-left:8px;">
                                                    <?php echo number_format($insp_balance - $insp_net_wrong, 2); ?> MT
                                                </strong>
                                            </div>
                                            <div class="rmbz-mtfix-severity-badge" style="font-weight:bold;"></div>
                                        </div>
                                        <div class="rmbz-mtfix-recommendation" style="font-size:12px; margin-top:6px; color:#444;"></div>
                                    </div>

                                    <button type="submit" name="rmbz_apply_mt_fix" class="button button-primary"
                                            onclick="return confirm('Confirmar débito de ' + document.getElementById('rmbz-mtfix-amount-<?php echo esc_attr(md5($inspect_tel)); ?>').value + ' MT a <?php echo esc_js($inspect_tel); ?>?');">
                                        💾 Aplicar Débito
                                    </button>
                                </form>
                            </div>

                            <?php /* JS — preview live via AJAX, debounce 300ms.
                                Sem `&&` para sobreviver ao escape do WP (1.5.119/126). */ ?>
                            <script>
                            (function(){
                                var prefix = <?php echo wp_json_encode( md5($inspect_tel) ); ?>;
                                var tel    = <?php echo wp_json_encode( $inspect_tel ); ?>;
                                var ajaxUrl = <?php echo wp_json_encode( admin_url('admin-ajax.php') ); ?>;
                                var nonce  = <?php echo wp_json_encode( wp_create_nonce('rmbz_wallet_mt_preview_nonce') ); ?>;

                                var input    = document.getElementById('rmbz-mtfix-amount-' + prefix);
                                var preview  = document.getElementById('rmbz-mtfix-preview-' + prefix);
                                if (!input) return;
                                if (!preview) return;

                                var newBalEl = preview.querySelector('.rmbz-mtfix-new-balance');
                                var sevEl    = preview.querySelector('.rmbz-mtfix-severity-badge');
                                var recEl    = preview.querySelector('.rmbz-mtfix-recommendation');

                                // Quick-preset buttons
                                document.querySelectorAll('.rmbz-mtfix-preset').forEach(function(btn) {
                                    btn.addEventListener('click', function() {
                                        input.value = btn.getAttribute('data-amount');
                                        input.dispatchEvent(new Event('input'));
                                    });
                                });

                                var timer = null;
                                function refresh() {
                                    if (timer) clearTimeout(timer);
                                    timer = setTimeout(function() {
                                        var fd = new FormData();
                                        fd.append('action', 'rmbz_wallet_mt_preview');
                                        fd.append('nonce', nonce);
                                        fd.append('telemovel', tel);
                                        fd.append('amount', input.value);

                                        fetch(ajaxUrl, { method:'POST', body:fd, credentials:'same-origin' })
                                            .then(function(r){ return r.json(); })
                                            .then(function(resp){
                                                var ok = false;
                                                if (resp) { if (resp.success) { ok = true; } }
                                                if (!ok) return;
                                                var d = resp.data;
                                                newBalEl.textContent = (Number(d.new_balance).toFixed(2)) + ' MT';

                                                // Cores e badges conforme severidade
                                                var bg = 'var(--rmbz-info-soft, rgba(59,130,246,0.08))',
                                                    border = 'var(--rmbz-info-strong, #2563eb)',
                                                    sevText = '✓ SEGURO',
                                                    sevColor = 'var(--rmbz-success-strong, #059669)';
                                                if (d.severity === 'warning') {
                                                    bg = 'var(--rmbz-warning-soft, rgba(245,158,11,0.12))';
                                                    border = 'var(--rmbz-warning, #f59e0b)';
                                                    sevText = '⚠ ATENÇÃO'; sevColor = 'var(--rmbz-warning, #f59e0b)';
                                                } else if (d.severity === 'critical') {
                                                    bg = 'var(--rmbz-danger-soft, rgba(239,68,68,0.12))';
                                                    border = 'var(--rmbz-danger-strong, #dc2626)';
                                                    sevText = '🚨 SALDO NEGATIVO'; sevColor = 'var(--rmbz-danger-strong, #dc2626)';
                                                }
                                                preview.style.background = bg;
                                                preview.style.borderColor = border;
                                                if (sevEl) {
                                                    sevEl.textContent = sevText;
                                                    sevEl.style.color = sevColor;
                                                }
                                                if (newBalEl) newBalEl.style.color = sevColor;
                                                if (recEl) recEl.textContent = d.recommendation || '';
                                            })
                                            .catch(function(){ /* silencioso */ });
                                    }, 300);
                                }

                                input.addEventListener('input', refresh);
                                // Trigger inicial
                                refresh();
                            })();
                            </script>
                        <?php endif; ?>

                        <p style="margin-top:12px;">
                            <a href="<?php echo esc_url(remove_query_arg(['inspect_tel', 'insp_page'])); ?>" class="button">Fechar inspecção</a>
                        </p>
                    </div>
                    <?php
                }
                ?>
            <?php endif; ?>
        </div>
    </div>
    <?php
}
