<?php
/**
 * api/testar_automacao.php — Permite disparar manualmente, pelo painel, as
 * mesmas rotinas que os crons rodam sozinhos todo dia (útil para testar
 * sem precisar esperar o horário/dia seguinte), além de consultar e
 * gerenciar as filas de envio. As ações que rodam o cron para TODO o
 * sistema (verificar vencimentos/testes, processar filas) são só do ADM;
 * as de consulta/gestão de fila respeitam o escopo de cada nível (cada um
 * só vê/gerencia os itens dos PRÓPRIOS clientes — o ADM vê tudo).
 */

require_once __DIR__ . '/../core/tarefas_cron.php';

header('Content-Type: application/json; charset=utf-8');
$usuarioLogado = exigir_login();
$acao = $_GET['acao'] ?? $_POST['acao'] ?? '';
$corpo = json_decode(file_get_contents('php://input'), true) ?? $_POST;

/** Filtra uma fila (array de itens com id_operador) pelo escopo do usuário. */
function filtrar_fila_por_escopo(array $fila, array $usuarioLogado): array
{
    $escopo = escopo_visibilidade($usuarioLogado);
    if ($escopo === null) {
        return $fila; // ADM vê tudo
    }
    return array_values(array_filter($fila, fn($item) => in_array($item['id_operador'] ?? '', $escopo, true)));
}

switch ($acao) {

    case 'verificar_vencimentos':
        exigir_nivel(['ADM']);
        // Equivale a rodar cron/cron_notificar.php agora mesmo.
        $r = rodar_verificacao_vencimentos();
        auditoria_log($usuarioLogado['usuario'], 'TESTE_MANUAL_CRON', 'Verificação de vencimentos disparada manualmente.');
        echo json_encode(['ok' => true, 'resultado' => $r], JSON_UNESCAPED_UNICODE);
        break;

    case 'verificar_testes':
        exigir_nivel(['ADM']);
        // Verifica clientes de "Teste Grátis" perto de expirar (por minutos).
        $r = rodar_verificacao_testes();
        auditoria_log($usuarioLogado['usuario'], 'TESTE_MANUAL_TESTES', json_encode($r, JSON_UNESCAPED_UNICODE));
        echo json_encode(['ok' => true, 'resultado' => $r], JSON_UNESCAPED_UNICODE);
        break;

    case 'enviar_fila_emails':
        exigir_nivel(['ADM']);
        // Equivale a rodar cron/processar_fila_emails.php agora mesmo.
        // ignorarHorario=true -> força o envio mesmo fora do horário
        // configurado (só faz sentido para teste manual pelo painel).
        $ignorarHorario = !empty($corpo['ignorar_horario']);
        $r = rodar_fila_emails($ignorarHorario);
        auditoria_log($usuarioLogado['usuario'], 'TESTE_MANUAL_FILA_EMAILS', json_encode($r, JSON_UNESCAPED_UNICODE));
        echo json_encode(['ok' => true, 'resultado' => $r], JSON_UNESCAPED_UNICODE);
        break;

    case 'enviar_fila_sms':
        exigir_nivel(['ADM']);
        // Equivale a rodar cron/processar_fila_sms.php agora mesmo.
        $ignorarHorario = !empty($corpo['ignorar_horario']);
        $r = rodar_fila_sms($ignorarHorario);
        auditoria_log($usuarioLogado['usuario'], 'TESTE_MANUAL_FILA_SMS', json_encode($r, JSON_UNESCAPED_UNICODE));
        echo json_encode(['ok' => true, 'resultado' => $r], JSON_UNESCAPED_UNICODE);
        break;

    case 'status_filas':
        // Retorna quantos itens estão pendentes/enviados/com erro em cada
        // fila DENTRO DO ESCOPO do usuário (o ADM vê o total geral).
        $filaEmails = filtrar_fila_por_escopo(db_read('fila_emails'), $usuarioLogado);
        $filaWhatsapp = filtrar_fila_por_escopo(db_read('fila_mensagens'), $usuarioLogado);
        $filaSms = filtrar_fila_por_escopo(db_read('fila_sms'), $usuarioLogado);

        $contar = function (array $fila) {
            $c = ['pendente' => 0, 'processando' => 0, 'enviado' => 0, 'erro' => 0];
            foreach ($fila as $item) {
                $status = $item['status'] ?? 'pendente';
                if (isset($c[$status])) {
                    $c[$status]++;
                }
            }
            return $c;
        };

        echo json_encode([
            'ok' => true,
            'fila_emails' => $contar($filaEmails),
            'fila_whatsapp' => $contar($filaWhatsapp),
            'fila_sms' => $contar($filaSms),
        ], JSON_UNESCAPED_UNICODE);
        break;

    case 'listar_fila_emails':
        $fila = filtrar_fila_por_escopo(db_read('fila_emails'), $usuarioLogado);
        usort($fila, fn($a, $b) => strcmp($b['criado_em'] ?? '', $a['criado_em'] ?? ''));
        echo json_encode(['ok' => true, 'fila' => array_slice($fila, 0, 300)], JSON_UNESCAPED_UNICODE);
        break;

    case 'listar_fila_whatsapp':
        $fila = filtrar_fila_por_escopo(db_read('fila_mensagens'), $usuarioLogado);
        usort($fila, fn($a, $b) => strcmp($b['criado_em'] ?? '', $a['criado_em'] ?? ''));
        echo json_encode(['ok' => true, 'fila' => array_slice($fila, 0, 300)], JSON_UNESCAPED_UNICODE);
        break;

    case 'listar_fila_sms':
        $fila = filtrar_fila_por_escopo(db_read('fila_sms'), $usuarioLogado);
        usort($fila, fn($a, $b) => strcmp($b['criado_em'] ?? '', $a['criado_em'] ?? ''));
        echo json_encode(['ok' => true, 'fila' => array_slice($fila, 0, 300)], JSON_UNESCAPED_UNICODE);
        break;

    case 'excluir_item_fila':
        $tipo = $corpo['tipo'] ?? '';
        $id = $corpo['id'] ?? '';
        $arquivo = $tipo === 'email' ? 'fila_emails' : ($tipo === 'whatsapp' ? 'fila_mensagens' : ($tipo === 'sms' ? 'fila_sms' : null));
        if (!$arquivo) {
            http_response_code(422);
            echo json_encode(['ok' => false, 'erro' => 'Tipo inválido.']);
            break;
        }
        $escopo = escopo_visibilidade($usuarioLogado);
        $itemAlvo = null;
        foreach (db_read($arquivo) as $item) {
            if ($item['id'] === $id) { $itemAlvo = $item; break; }
        }
        if (!$itemAlvo) {
            http_response_code(404);
            echo json_encode(['ok' => false, 'erro' => 'Item não encontrado.']);
            break;
        }
        if ($escopo !== null && !in_array($itemAlvo['id_operador'] ?? '', $escopo, true)) {
            http_response_code(403);
            echo json_encode(['ok' => false, 'erro' => 'Você não tem permissão para gerenciar este item.']);
            break;
        }
        db_update($arquivo, function (&$fila) use ($id) {
            $fila = array_values(array_filter($fila, fn($item) => $item['id'] !== $id));
        });
        auditoria_log($usuarioLogado['usuario'], 'FILA_ITEM_REMOVIDO', "{$tipo}: {$id}");
        echo json_encode(['ok' => true], JSON_UNESCAPED_UNICODE);
        break;

    case 'reenviar_item_fila':
        // Volta um item com erro para "pendente" (o worker do cron pega de novo).
        $tipo = $corpo['tipo'] ?? '';
        $id = $corpo['id'] ?? '';
        $arquivo = $tipo === 'email' ? 'fila_emails' : ($tipo === 'whatsapp' ? 'fila_mensagens' : ($tipo === 'sms' ? 'fila_sms' : null));
        if (!$arquivo) {
            http_response_code(422);
            echo json_encode(['ok' => false, 'erro' => 'Tipo inválido.']);
            break;
        }
        $escopo = escopo_visibilidade($usuarioLogado);
        $itemAlvo = null;
        foreach (db_read($arquivo) as $item) {
            if ($item['id'] === $id) { $itemAlvo = $item; break; }
        }
        if (!$itemAlvo) {
            http_response_code(404);
            echo json_encode(['ok' => false, 'erro' => 'Item não encontrado.']);
            break;
        }
        if ($escopo !== null && !in_array($itemAlvo['id_operador'] ?? '', $escopo, true)) {
            http_response_code(403);
            echo json_encode(['ok' => false, 'erro' => 'Você não tem permissão para gerenciar este item.']);
            break;
        }
        db_update($arquivo, function (&$fila) use ($id) {
            foreach ($fila as &$item) {
                if ($item['id'] === $id) {
                    $item['status'] = 'pendente';
                    $item['tentativas'] = 0;
                    break;
                }
            }
        });
        auditoria_log($usuarioLogado['usuario'], 'FILA_ITEM_REENVIADO', "{$tipo}: {$id}");
        echo json_encode(['ok' => true], JSON_UNESCAPED_UNICODE);
        break;

    default:
        http_response_code(400);
        echo json_encode(['ok' => false, 'erro' => 'Ação inválida.']);
}
