<?php
require_once __DIR__ . '/../core/db_helper.php';
require_once __DIR__ . '/../core/auth.php';
require_once __DIR__ . '/../core/notificacoes.php';

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

if ($acao === 'listar') {
    $config = db_read('config');
    $canaisResolvidos = resolver_canais_para_usuario($usuarioLogado['id']);
    $mensagensResolvidas = resolver_mensagens_para_usuario($usuarioLogado['id']);
    echo json_encode([
        'ok' => true,
        'mensagens' => $mensagensResolvidas,
        'canais' => $canaisResolvidos,
        'pix_manual' => $config['pix_manual'] ?? ['chave' => '', 'nome_beneficiario' => '', 'instrucoes' => ''],
        'sms_gateway' => [
            'url_api' => $config['sms_gateway']['url_api'] ?? 'https://api.sms-gate.app/3rdparty/v1/messages',
            'usuario' => $config['sms_gateway']['usuario'] ?? '',
            'tem_senha_salva' => !empty($config['sms_gateway']['senha']),
        ],
        'agendamento' => $config['agendamento_notificacoes'] ?? ['dias_aviso' => [3], 'dias_aviso_pos_vencimento' => [1], 'horario_inicio' => '09:00', 'intervalo_segundos_email' => 30, 'lote_por_execucao_email' => 10, 'intervalo_segundos_sms' => 30, 'lote_por_execucao_sms' => 10, 'minutos_aviso_teste' => 60, 'minutos_antes_aviso_teste' => 15],
        'saudacoes' => $config['saudacoes'] ?? ['Olá'],
        'despedidas' => $config['despedidas'] ?? ['Atenciosamente'],
    ], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($acao === 'salvar_pix') {
    exigir_nivel(['ADM', 'REVENDA']);
    $chave = trim($corpo['chave'] ?? '');
    $beneficiario = trim($corpo['nome_beneficiario'] ?? '');
    $instrucoes = trim($corpo['instrucoes'] ?? '');
    db_update('config', function (&$config) use ($chave, $beneficiario, $instrucoes) {
        $config['pix_manual'] = [
            'chave' => $chave,
            'nome_beneficiario' => $beneficiario,
            'instrucoes' => $instrucoes,
        ];
    });
    auditoria_log($usuarioLogado['usuario'], 'PIX_MANUAL_ATUALIZADO', $chave ? 'Chave configurada' : 'Chave removida');
    echo json_encode(['ok' => true], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($acao === 'salvar_sms') {
    exigir_nivel(['ADM']);
    $url = trim($corpo['url_api'] ?? '');
    $usuarioSms = trim($corpo['usuario'] ?? '');
    $senha = trim($corpo['senha'] ?? '');

    db_update('config', function (&$config) use ($url, $usuarioSms, $senha) {
        // Se a senha vier vazia e já havia uma salva, mantém a anterior
        // (evita apagar sem querer ao reabrir o formulário).
        if ($senha === '' && !empty($config['sms_gateway']['senha'])) {
            $senha = $config['sms_gateway']['senha'];
        }
        $config['sms_gateway'] = [
            'provedor' => 'sms-gate-app',
            'url_api' => $url ?: 'https://api.sms-gate.app/3rdparty/v1/messages',
            'usuario' => $usuarioSms,
            'senha' => $senha,
        ];
    });
    auditoria_log($usuarioLogado['usuario'], 'SMS_GATEWAY_ATUALIZADO', $usuarioSms ? 'Configurado' : 'Removido');
    echo json_encode(['ok' => true], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($acao === 'testar_sms') {
    // Qualquer nível pode testar o PRÓPRIO gateway de SMS resolvido pela
    // hierarquia (o dele, ou o de quem o criou, ou o padrão do sistema).
    $numero = trim($corpo['numero'] ?? '');
    if (!$numero) {
        http_response_code(422);
        echo json_encode(['ok' => false, 'erro' => 'Informe um número de WhatsApp/celular para o teste.']);
        exit;
    }

    // Garante um limite de tempo seguro, mesmo que a hospedagem tenha um
    // padrão baixo — evita que o script seja morto no meio da requisição
    // (o que derruba a conexão e aparece no navegador como "falha de rede").
    if (function_exists('set_time_limit')) {
        @set_time_limit(25);
    }

    try {
        $inicio = microtime(true);
        $ok = enviar_sms($numero, 'Teste de SMS via celular - COBRANEX. Se você recebeu esta mensagem, está tudo funcionando!', $usuarioLogado['id']);
        $duracao = round(microtime(true) - $inicio, 2);

        echo json_encode([
            'ok' => $ok,
            'erro' => $ok ? null : 'Falha ao enviar. Confira a URL/usuário/senha e se o app está com o modo Cloud Server ativo no celular. Veja também os logs de auditoria para o motivo exato.',
            'duracao_segundos' => $duracao,
        ], JSON_UNESCAPED_UNICODE);
    } catch (\Throwable $e) {
        error_log('Erro inesperado ao testar SMS: ' . $e->getMessage());
        http_response_code(500);
        echo json_encode(['ok' => false, 'erro' => 'Erro interno ao testar SMS: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
    }
    exit;
}

if ($acao === 'salvar_agendamento') {
    exigir_nivel(['ADM']);
    $diasAviso = $corpo['dias_aviso'] ?? [3];
    // Sanitiza: só inteiros positivos, sem repetição, ordenados do maior pro menor
    $diasAviso = array_values(array_unique(array_filter(array_map('intval', (array) $diasAviso), fn($d) => $d > 0)));
    rsort($diasAviso);

    // Dias APÓS o vencimento pra avisar "vencido" (antes de inativar). Hoje
    // a inativação automática acontece com 2 dias de atraso, então só o
    // valor 1 tem efeito prático — mas deixamos a validação genérica igual
    // à de dias_aviso, caso o limite de inativação mude no futuro.
    $diasAvisoPosVencimento = $corpo['dias_aviso_pos_vencimento'] ?? [1];
    $diasAvisoPosVencimento = array_values(array_unique(array_filter(array_map('intval', (array) $diasAvisoPosVencimento), fn($d) => $d > 0)));
    rsort($diasAvisoPosVencimento);

    $horario = $corpo['horario_inicio'] ?? '09:00';
    if (!preg_match('/^([01]\d|2[0-3]):[0-5]\d$/', $horario)) {
        $horario = '09:00';
    }

    $intervalo = max(1, (int) ($corpo['intervalo_segundos_email'] ?? 30));
    $lote = max(1, min(100, (int) ($corpo['lote_por_execucao_email'] ?? 10)));
    $intervaloSms = max(1, (int) ($corpo['intervalo_segundos_sms'] ?? 30));
    $loteSms = max(1, min(100, (int) ($corpo['lote_por_execucao_sms'] ?? 10)));
    $minutosAvisoTeste = max(1, (int) ($corpo['minutos_aviso_teste'] ?? 60));
    $minutosAntesAvisoTeste = max(1, (int) ($corpo['minutos_antes_aviso_teste'] ?? 15));

    db_update('config', function (&$config) use ($diasAviso, $diasAvisoPosVencimento, $horario, $intervalo, $lote, $intervaloSms, $loteSms, $minutosAvisoTeste, $minutosAntesAvisoTeste) {
        $config['agendamento_notificacoes'] = [
            'dias_aviso' => $diasAviso ?: [3],
            'dias_aviso_pos_vencimento' => $diasAvisoPosVencimento,
            'horario_inicio' => $horario,
            'intervalo_segundos_email' => $intervalo,
            'lote_por_execucao_email' => $lote,
            'intervalo_segundos_sms' => $intervaloSms,
            'lote_por_execucao_sms' => $loteSms,
            'minutos_aviso_teste' => $minutosAvisoTeste,
            'minutos_antes_aviso_teste' => $minutosAntesAvisoTeste,
        ];
    });
    auditoria_log($usuarioLogado['usuario'], 'AGENDAMENTO_ATUALIZADO', json_encode($corpo, JSON_UNESCAPED_UNICODE));
    echo json_encode(['ok' => true], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($acao === 'salvar_variacoes') {
    // Saudações e despedidas são globais (não por usuário) — são só um
    // "tempero" de linguagem, não faz sentido cada Revenda ter sua lista.
    exigir_nivel(['ADM']);
    $saudacoes = array_values(array_filter(array_map('trim', (array) ($corpo['saudacoes'] ?? [])), fn($v) => $v !== ''));
    $despedidas = array_values(array_filter(array_map('trim', (array) ($corpo['despedidas'] ?? [])), fn($v) => $v !== ''));

    db_update('config', function (&$config) use ($saudacoes, $despedidas) {
        $config['saudacoes'] = !empty($saudacoes) ? $saudacoes : ['Olá'];
        $config['despedidas'] = !empty($despedidas) ? $despedidas : ['Atenciosamente'];
    });
    auditoria_log($usuarioLogado['usuario'], 'VARIACOES_ATUALIZADAS', '');
    echo json_encode(['ok' => true], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($acao === 'salvar') {
    // Cada usuário (ADM, Revenda ou Sub-Revenda) tem os PRÓPRIOS templates
    // — se não configurar algum, continua herdando de quem o criou, ou do
    // padrão de fábrica do sistema (mesmo padrão hierárquico do Canais/
    // SMS/PIX). Antes isso escrevia direto no arquivo global, o que fazia
    // a edição de uma Revenda "vazar" pra todo mundo que ainda não tinha
    // template próprio.
    // Templates rotativos aceitam uma LISTA de variações (o sistema roda
    // em rodízio, uma por envio, pra não repetir sempre o mesmo texto).
    // Os dois de "teste grátis" continuam sendo texto único.
    $chavesRotativas = ['boas_vindas', 'aviso_3_dias', 'aviso_vencimento_dia', 'confirmacao_renovacao', 'aviso_pos_vencimento', 'aviso_expirado'];
    $chavesTexto = ['teste_expirando', 'teste_aviso_previo'];

    $mensagensProprias = [];
    foreach ($chavesRotativas as $chave) {
        if (isset($corpo[$chave])) {
            $valor = $corpo[$chave];
            if (is_array($valor)) {
                $mensagensProprias[$chave] = array_values(array_filter(array_map('strval', $valor), fn($v) => trim($v) !== ''));
            } else {
                $mensagensProprias[$chave] = (string) $valor;
            }
        }
    }
    foreach ($chavesTexto as $chave) {
        if (isset($corpo[$chave])) {
            $mensagensProprias[$chave] = (string) $corpo[$chave];
        }
    }
    $atualizado = db_update('usuarios', function (&$usuarios) use ($usuarioLogado, $mensagensProprias) {
        foreach ($usuarios as &$u) {
            if ($u['id'] === $usuarioLogado['id']) {
                $u['mensagens'] = $mensagensProprias;
                $r = $u;
                unset($r['senha_hash']);
                return $r;
            }
        }
        return null;
    });
    if (!$atualizado) {
        http_response_code(404);
        echo json_encode(['ok' => false, 'erro' => 'Usuário não encontrado.']);
        exit;
    }
    auditoria_log($usuarioLogado['usuario'], 'TEMPLATES_ATUALIZADOS', '');
    echo json_encode(['ok' => true], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($acao === 'salvar_canais') {
    // Cada usuário (ADM, Revenda ou Sub-Revenda) tem os PRÓPRIOS canais de
    // envio — se não configurar, herda de quem o criou, ou do padrão do
    // sistema (mesmo padrão hierárquico já usado pro SMS/PIX/Mensagens).
    $canais = $corpo['canais'] ?? [];
    $canaisSalvar = [];
    foreach (['cobranca', 'renovacao', 'teste'] as $grupo) {
        if (isset($canais[$grupo])) {
            $canaisSalvar[$grupo] = [
                'whatsapp' => !empty($canais[$grupo]['whatsapp']),
                'email' => !empty($canais[$grupo]['email']),
                'sms' => !empty($canais[$grupo]['sms']),
            ];
        }
    }
    $atualizado = db_update('usuarios', function (&$usuarios) use ($usuarioLogado, $canaisSalvar) {
        foreach ($usuarios as &$u) {
            if ($u['id'] === $usuarioLogado['id']) {
                $u['canais_notificacao'] = $canaisSalvar;
                $r = $u;
                unset($r['senha_hash']);
                return $r;
            }
        }
        return null;
    });
    if (!$atualizado) {
        http_response_code(404);
        echo json_encode(['ok' => false, 'erro' => 'Usuário não encontrado.']);
        exit;
    }
    auditoria_log($usuarioLogado['usuario'], 'CANAIS_NOTIFICACAO_ATUALIZADOS', json_encode($canaisSalvar, JSON_UNESCAPED_UNICODE));
    echo json_encode(['ok' => true], JSON_UNESCAPED_UNICODE);
    exit;
}

// ---- Templates extras (mensagens avulsas criadas pelo usuário) ----

if ($acao === 'criar_extra') {
    exigir_nivel(['ADM', 'REVENDA']);
    $nome = trim($corpo['nome'] ?? '');
    $texto = trim($corpo['texto'] ?? '');
    if (!$nome || !$texto) {
        http_response_code(422);
        echo json_encode(['ok' => false, 'erro' => 'Informe nome e texto da mensagem.']);
        exit;
    }
    $novo = ['id' => gerar_id('MSGTPL-'), 'nome' => $nome, 'texto' => $texto];
    db_update('mensagens', function (&$m) use ($novo) {
        if (!isset($m['extras']) || !is_array($m['extras'])) $m['extras'] = [];
        $m['extras'][] = $novo;
    });
    auditoria_log($usuarioLogado['usuario'], 'TEMPLATE_EXTRA_CRIADO', $nome);
    echo json_encode(['ok' => true, 'template' => $novo], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($acao === 'editar_extra') {
    exigir_nivel(['ADM', 'REVENDA']);
    $id = $corpo['id'] ?? '';
    $atualizado = db_update('mensagens', function (&$m) use ($id, $corpo) {
        if (!isset($m['extras'])) return null;
        foreach ($m['extras'] as &$t) {
            if ($t['id'] === $id) {
                if (isset($corpo['nome'])) $t['nome'] = trim($corpo['nome']);
                if (isset($corpo['texto'])) $t['texto'] = trim($corpo['texto']);
                return $t;
            }
        }
        return null;
    });
    if (!$atualizado) {
        http_response_code(404);
        echo json_encode(['ok' => false, 'erro' => 'Template não encontrado.']);
        exit;
    }
    auditoria_log($usuarioLogado['usuario'], 'TEMPLATE_EXTRA_EDITADO', $id);
    echo json_encode(['ok' => true, 'template' => $atualizado], JSON_UNESCAPED_UNICODE);
    exit;
}

if ($acao === 'deletar_extra') {
    exigir_nivel(['ADM', 'REVENDA']);
    $id = $corpo['id'] ?? '';
    db_update('mensagens', function (&$m) use ($id) {
        if (isset($m['extras'])) {
            $m['extras'] = array_values(array_filter($m['extras'], fn($t) => $t['id'] !== $id));
        }
    });
    auditoria_log($usuarioLogado['usuario'], 'TEMPLATE_EXTRA_REMOVIDO', $id);
    echo json_encode(['ok' => true], JSON_UNESCAPED_UNICODE);
    exit;
}

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