<?php
require_once __DIR__ . '/../core/db_helper.php';
require_once __DIR__ . '/../core/auth.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;

function responder_usr($d, $c = 200)
{
    http_response_code($c);
    echo json_encode($d, JSON_UNESCAPED_UNICODE);
    exit;
}

/**
 * Só o ADM (vê todo mundo) ou quem CRIOU DIRETAMENTE o usuário alvo pode
 * ver/editar as configurações (SMTP/SMS/PIX/Mensagens) de outra pessoa.
 * Isso evita, por exemplo, uma Sub-Revenda mexer na config de outra
 * Sub-Revenda que não é dela.
 */
function pode_gerenciar_config_de(array $usuarioLogado, array $usuarioAlvo): bool
{
    if ($usuarioLogado['nivel'] === 'ADM') {
        return true;
    }
    return ($usuarioAlvo['criado_por'] ?? null) === $usuarioLogado['id'];
}

// Regras de quem pode criar quem
$niveisPermitidosParaCriar = [
    'ADM' => 'REVENDA',
    'REVENDA' => 'SUBREVENDA',
];

switch ($acao) {

    case 'listar':
        $usuarios = db_read('usuarios');
        $escopo = escopo_visibilidade($usuarioLogado);
        if ($escopo !== null) {
            $usuarios = array_values(array_filter($usuarios, fn($u) => in_array($u['id'], $escopo, true)));
        }
        foreach ($usuarios as &$u) {
            unset($u['senha_hash']);
        }
        responder_usr(['ok' => true, 'usuarios' => $usuarios]);
        break;

    case 'criar':
        exigir_nivel(['ADM', 'REVENDA']);
        $nivelCriado = $niveisPermitidosParaCriar[$usuarioLogado['nivel']] ?? null;
        if (!$nivelCriado) {
            responder_usr(['ok' => false, 'erro' => 'Seu nível não pode criar novos usuários.'], 403);
        }

        $usuarios = db_read('usuarios');
        foreach ($usuarios as $u) {
            if (strcasecmp($u['usuario'], $corpo['usuario'] ?? '') === 0) {
                responder_usr(['ok' => false, 'erro' => 'Nome de usuário já existe.'], 409);
            }
        }

        $novo = [
            'id' => gerar_id('USR-'),
            'usuario' => trim($corpo['usuario'] ?? ''),
            'senha_hash' => password_hash($corpo['senha'] ?? bin2hex(random_bytes(4)), PASSWORD_DEFAULT),
            'nivel' => $nivelCriado,
            'nome_completo' => trim($corpo['nome_completo'] ?? ''),
            'email' => trim($corpo['email'] ?? ''),
            'criado_por' => $usuarioLogado['id'],
            'ativo' => true,
            'valor_mensalidade' => (float) ($corpo['valor_mensalidade'] ?? 0),
            'vencimento_painel' => $corpo['vencimento_painel'] ?? date('Y-m-d', strtotime('+30 days')),
            'criado_em' => date('Y-m-d H:i:s'),
        ];

        db_update('usuarios', function (&$u) use ($novo) {
            $u[] = $novo;
        });

        auditoria_log($usuarioLogado['usuario'], 'USUARIO_CRIADO', $novo['usuario'] . ' (' . $novo['nivel'] . ')');
        unset($novo['senha_hash']);
        responder_usr(['ok' => true, 'usuario_criado' => $novo]);
        break;

    case 'renovar_mensalidade':
        // ADM renova a mensalidade de uma Revenda, ou Revenda renova a de
        // uma Sub-Revenda que ela mesma criou. Sem sistema de créditos —
        // é assinatura mensal de acesso ao painel.
        $idDestino = $corpo['id_destino'] ?? '';
        $meses = max(1, (int) ($corpo['meses'] ?? 1));

        $usuarios = db_read('usuarios');
        $destino = null;
        foreach ($usuarios as $u) {
            if ($u['id'] === $idDestino) { $destino = $u; break; }
        }
        if (!$destino || ($destino['criado_por'] ?? '') !== $usuarioLogado['id']) {
            responder_usr(['ok' => false, 'erro' => 'Você só pode renovar usuários criados por você.'], 403);
        }

        $atualizado = renovar_mensalidade_painel($idDestino, $meses);
        if (!$atualizado) {
            responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        }

        // Lança a entrada financeira da mensalidade recebida
        $valor = (float) ($destino['valor_mensalidade'] ?? 0);
        if ($valor > 0) {
            db_update('financeiro', function (&$financeiro) use ($destino, $valor, $usuarioLogado) {
                $financeiro[] = [
                    'id' => gerar_id('FIN-'),
                    'tipo' => 'entrada',
                    'origem' => 'mensalidade_painel',
                    'cliente_id' => null,
                    'criado_por' => $usuarioLogado['id'],
                    'valor' => $valor,
                    'descricao' => 'Mensalidade do painel - ' . ($destino['usuario'] ?? ''),
                    'data' => date('Y-m-d H:i:s'),
                ];
            });
        }

        auditoria_log($usuarioLogado['usuario'], 'MENSALIDADE_RENOVADA', "Usuário {$destino['usuario']} (+{$meses} mês(es))");
        responder_usr(['ok' => true, 'usuario' => $atualizado]);
        break;

    case 'salvar_smtp':
        // Cada usuário (ADM, Revenda ou Sub-Revenda) só pode configurar o
        // PRÓPRIO SMTP — não o de outro usuário. É sempre "meu e-mail de cobrança".
        $smtp = [
            'host' => trim($corpo['host'] ?? ''),
            'port' => (int) ($corpo['port'] ?? 587),
            'usuario' => trim($corpo['usuario_smtp'] ?? ''),
            'senha' => (string) ($corpo['senha'] ?? ''),
            'seguranca' => in_array($corpo['seguranca'] ?? 'tls', ['tls', 'ssl'], true) ? $corpo['seguranca'] : 'tls',
            'remetente_nome' => trim($corpo['remetente_nome'] ?? ''),
        ];

        $atualizado = db_update('usuarios', function (&$usuarios) use ($usuarioLogado, $smtp) {
            foreach ($usuarios as &$u) {
                if ($u['id'] === $usuarioLogado['id']) {
                    // Se o campo de senha vier vazio e já havia uma senha salva,
                    // mantém a senha anterior (evita apagar sem querer ao reabrir o formulário).
                    if ($smtp['senha'] === '' && !empty($u['smtp']['senha'])) {
                        $smtp['senha'] = $u['smtp']['senha'];
                    }
                    $u['smtp'] = $smtp;
                    $r = $u;
                    unset($r['senha_hash']);
                    return $r;
                }
            }
            return null;
        });

        if (!$atualizado) {
            responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        }
        auditoria_log($usuarioLogado['usuario'], 'SMTP_ATUALIZADO', $smtp['host'] ? "Host: {$smtp['host']}" : 'Removido');
        responder_usr(['ok' => true, 'usuario' => $atualizado]);
        break;

    case 'remover_smtp':
        // Remove a configuração própria, voltando a usar o SMTP de quem
        // criou este usuário (ou o padrão do sistema).
        db_update('usuarios', function (&$usuarios) use ($usuarioLogado) {
            foreach ($usuarios as &$u) {
                if ($u['id'] === $usuarioLogado['id']) {
                    unset($u['smtp']);
                    break;
                }
            }
        });
        auditoria_log($usuarioLogado['usuario'], 'SMTP_REMOVIDO', '');
        responder_usr(['ok' => true]);
        break;

    case 'meu_smtp':
        // Retorna o SMTP salvo do próprio usuário logado (para preencher o
        // formulário em "Minha Conta"). Nunca retorna o SMTP de outra pessoa.
        $usuarios = db_read('usuarios');
        foreach ($usuarios as $u) {
            if ($u['id'] === $usuarioLogado['id']) {
                $smtpAtual = $u['smtp'] ?? ['host' => '', 'port' => 587, 'usuario' => '', 'senha' => '', 'seguranca' => 'tls', 'remetente_nome' => ''];
                // Não devolve a senha em texto puro pro front-end por segurança —
                // só indica se já existe uma senha salva.
                $temSenha = !empty($smtpAtual['senha']);
                unset($smtpAtual['senha']);
                $smtpAtual['tem_senha_salva'] = $temSenha;
                responder_usr(['ok' => true, 'smtp' => $smtpAtual]);
            }
        }
        responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        break;

    case 'salvar_sms_proprio':
        // Cada usuário pode configurar seu PRÓPRIO gateway de SMS (celular
        // Android próprio) — mesmo padrão de "meu SMTP", mas pro SMS.
        $gw = [
            'url_api' => trim($corpo['url_api'] ?? ''),
            'usuario' => trim($corpo['usuario'] ?? ''),
            'senha' => (string) ($corpo['senha'] ?? ''),
        ];

        $atualizado = db_update('usuarios', function (&$usuarios) use ($usuarioLogado, $gw) {
            foreach ($usuarios as &$u) {
                if ($u['id'] === $usuarioLogado['id']) {
                    if ($gw['senha'] === '' && !empty($u['sms_gateway']['senha'])) {
                        $gw['senha'] = $u['sms_gateway']['senha'];
                    }
                    $u['sms_gateway'] = $gw;
                    $r = $u;
                    unset($r['senha_hash']);
                    return $r;
                }
            }
            return null;
        });

        if (!$atualizado) {
            responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        }
        auditoria_log($usuarioLogado['usuario'], 'SMS_PROPRIO_ATUALIZADO', $gw['url_api'] ? 'Configurado' : 'Removido');
        responder_usr(['ok' => true]);
        break;

    case 'remover_sms_proprio':
        db_update('usuarios', function (&$usuarios) use ($usuarioLogado) {
            foreach ($usuarios as &$u) {
                if ($u['id'] === $usuarioLogado['id']) {
                    unset($u['sms_gateway']);
                    break;
                }
            }
        });
        auditoria_log($usuarioLogado['usuario'], 'SMS_PROPRIO_REMOVIDO', '');
        responder_usr(['ok' => true]);
        break;

    case 'meu_sms':
        $usuarios = db_read('usuarios');
        foreach ($usuarios as $u) {
            if ($u['id'] === $usuarioLogado['id']) {
                $gwAtual = $u['sms_gateway'] ?? ['url_api' => 'https://api.sms-gate.app/3rdparty/v1/messages', 'usuario' => '', 'senha' => ''];
                $temSenha = !empty($gwAtual['senha']);
                unset($gwAtual['senha']);
                $gwAtual['tem_senha_salva'] = $temSenha;
                responder_usr(['ok' => true, 'sms_gateway' => $gwAtual]);
            }
        }
        responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        break;

    case 'salvar_pix_proprio':
        // Cada usuário pode ter sua PRÓPRIA chave PIX de recebimento.
        $pix = [
            'chave' => trim($corpo['chave'] ?? ''),
            'nome_beneficiario' => trim($corpo['nome_beneficiario'] ?? ''),
            'instrucoes' => trim($corpo['instrucoes'] ?? ''),
        ];

        $atualizado = db_update('usuarios', function (&$usuarios) use ($usuarioLogado, $pix) {
            foreach ($usuarios as &$u) {
                if ($u['id'] === $usuarioLogado['id']) {
                    $u['pix_manual'] = $pix;
                    $r = $u;
                    unset($r['senha_hash']);
                    return $r;
                }
            }
            return null;
        });

        if (!$atualizado) {
            responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        }
        auditoria_log($usuarioLogado['usuario'], 'PIX_PROPRIO_ATUALIZADO', $pix['chave'] ? 'Configurado' : 'Removido');
        responder_usr(['ok' => true]);
        break;

    case 'remover_pix_proprio':
        db_update('usuarios', function (&$usuarios) use ($usuarioLogado) {
            foreach ($usuarios as &$u) {
                if ($u['id'] === $usuarioLogado['id']) {
                    unset($u['pix_manual']);
                    break;
                }
            }
        });
        auditoria_log($usuarioLogado['usuario'], 'PIX_PROPRIO_REMOVIDO', '');
        responder_usr(['ok' => true]);
        break;

    case 'meu_pix':
        $usuarios = db_read('usuarios');
        foreach ($usuarios as $u) {
            if ($u['id'] === $usuarioLogado['id']) {
                $pixAtual = $u['pix_manual'] ?? ['chave' => '', 'nome_beneficiario' => '', 'instrucoes' => ''];
                responder_usr(['ok' => true, 'pix_manual' => $pixAtual]);
            }
        }
        responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        break;

    case 'salvar_mensagens_proprias':
        // Cada usuário pode sobrescrever qualquer template individual (o
        // que não sobrescrever continua vindo de quem o criou, ou do
        // padrão global do sistema).
        $chavesValidasMsg = ['boas_vindas', 'aviso_3_dias', 'aviso_vencimento_dia', 'confirmacao_renovacao', 'aviso_pos_vencimento', 'aviso_expirado', 'teste_expirando', 'teste_aviso_previo'];
        $mensagensProprias = [];
        foreach ($chavesValidasMsg 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) {
            responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        }
        auditoria_log($usuarioLogado['usuario'], 'MENSAGENS_PROPRIAS_ATUALIZADAS', '');
        responder_usr(['ok' => true]);
        break;

    case 'remover_mensagens_proprias':
        db_update('usuarios', function (&$usuarios) use ($usuarioLogado) {
            foreach ($usuarios as &$u) {
                if ($u['id'] === $usuarioLogado['id']) {
                    unset($u['mensagens']);
                    break;
                }
            }
        });
        auditoria_log($usuarioLogado['usuario'], 'MENSAGENS_PROPRIAS_REMOVIDAS', '');
        responder_usr(['ok' => true]);
        break;

    case 'minhas_mensagens':
        $usuarios = db_read('usuarios');
        foreach ($usuarios as $u) {
            if ($u['id'] === $usuarioLogado['id']) {
                responder_usr(['ok' => true, 'mensagens' => $u['mensagens'] ?? [], 'mensagens_padrao' => db_read('mensagens')]);
            }
        }
        responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        break;

    case 'config_de_usuario':
        // ADM (ou quem criou diretamente o usuário) consulta a config de
        // outra pessoa sem precisar logar como ela — SMTP/SMS/PIX/Mensagens.
        $idAlvo = $_GET['id'] ?? $corpo['id'] ?? '';
        $usuarios = db_read('usuarios');
        $alvo = null;
        foreach ($usuarios as $u) {
            if ($u['id'] === $idAlvo) { $alvo = $u; break; }
        }
        if (!$alvo) {
            responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        }
        if (!pode_gerenciar_config_de($usuarioLogado, $alvo)) {
            responder_usr(['ok' => false, 'erro' => 'Você não tem permissão para ver a configuração deste usuário.'], 403);
        }

        $smtpAlvo = $alvo['smtp'] ?? ['host' => '', 'port' => 587, 'usuario' => '', 'senha' => '', 'seguranca' => 'tls', 'remetente_nome' => ''];
        $smtpAlvo['tem_senha_salva'] = !empty($smtpAlvo['senha']);
        unset($smtpAlvo['senha']);

        $smsAlvo = $alvo['sms_gateway'] ?? ['url_api' => '', 'usuario' => '', 'senha' => ''];
        $smsAlvo['tem_senha_salva'] = !empty($smsAlvo['senha']);
        unset($smsAlvo['senha']);

        responder_usr([
            'ok' => true,
            'usuario' => $alvo['usuario'],
            'smtp' => $smtpAlvo,
            'sms_gateway' => $smsAlvo,
            'pix_manual' => $alvo['pix_manual'] ?? ['chave' => '', 'nome_beneficiario' => '', 'instrucoes' => ''],
            'mensagens' => $alvo['mensagens'] ?? [],
            'mensagens_padrao' => db_read('mensagens'),
        ]);
        break;

    case 'salvar_config_usuario':
        // tipo: 'smtp' | 'sms' | 'pix' | 'mensagens'
        $idAlvo = $corpo['id'] ?? '';
        $tipo = $corpo['tipo'] ?? '';
        $usuarios = db_read('usuarios');
        $alvo = null;
        foreach ($usuarios as $u) {
            if ($u['id'] === $idAlvo) { $alvo = $u; break; }
        }
        if (!$alvo) {
            responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        }
        if (!pode_gerenciar_config_de($usuarioLogado, $alvo)) {
            responder_usr(['ok' => false, 'erro' => 'Você não tem permissão para editar a configuração deste usuário.'], 403);
        }

        $atualizado = db_update('usuarios', function (&$us) use ($idAlvo, $tipo, $corpo) {
            foreach ($us as &$u) {
                if ($u['id'] !== $idAlvo) {
                    continue;
                }
                if ($tipo === 'smtp') {
                    $smtp = [
                        'host' => trim($corpo['host'] ?? ''),
                        'port' => (int) ($corpo['port'] ?? 587),
                        'usuario' => trim($corpo['usuario_smtp'] ?? ''),
                        'senha' => (string) ($corpo['senha'] ?? ''),
                        'seguranca' => in_array($corpo['seguranca'] ?? 'tls', ['tls', 'ssl'], true) ? $corpo['seguranca'] : 'tls',
                        'remetente_nome' => trim($corpo['remetente_nome'] ?? ''),
                    ];
                    if ($smtp['senha'] === '' && !empty($u['smtp']['senha'])) {
                        $smtp['senha'] = $u['smtp']['senha'];
                    }
                    $u['smtp'] = $smtp;
                } elseif ($tipo === 'sms') {
                    $gw = [
                        'url_api' => trim($corpo['url_api'] ?? ''),
                        'usuario' => trim($corpo['usuario'] ?? ''),
                        'senha' => (string) ($corpo['senha'] ?? ''),
                    ];
                    if ($gw['senha'] === '' && !empty($u['sms_gateway']['senha'])) {
                        $gw['senha'] = $u['sms_gateway']['senha'];
                    }
                    $u['sms_gateway'] = $gw;
                } elseif ($tipo === 'pix') {
                    $u['pix_manual'] = [
                        'chave' => trim($corpo['chave'] ?? ''),
                        'nome_beneficiario' => trim($corpo['nome_beneficiario'] ?? ''),
                        'instrucoes' => trim($corpo['instrucoes'] ?? ''),
                    ];
                } elseif ($tipo === 'mensagens') {
                    $chavesValidasMsg = ['boas_vindas', 'aviso_3_dias', 'aviso_vencimento_dia', 'confirmacao_renovacao', 'aviso_pos_vencimento', 'aviso_expirado', 'teste_expirando', 'teste_aviso_previo'];
                    $mensagensProprias = [];
                    foreach ($chavesValidasMsg as $chave) {
                        if (isset($corpo[$chave])) {
                            $mensagensProprias[$chave] = (string) $corpo[$chave];
                        }
                    }
                    $u['mensagens'] = $mensagensProprias;
                }
                $r = $u;
                unset($r['senha_hash']);
                return $r;
            }
            return null;
        });

        if (!$atualizado) {
            responder_usr(['ok' => false, 'erro' => 'Tipo de configuração inválido ou usuário não encontrado.'], 400);
        }
        auditoria_log($usuarioLogado['usuario'], 'CONFIG_USUARIO_ATUALIZADA', "Alvo: {$alvo['usuario']} | Tipo: {$tipo}");
        responder_usr(['ok' => true]);
        break;

    case 'remover_config_usuario':
        $idAlvo = $corpo['id'] ?? '';
        $tipo = $corpo['tipo'] ?? '';
        $usuarios = db_read('usuarios');
        $alvo = null;
        foreach ($usuarios as $u) {
            if ($u['id'] === $idAlvo) { $alvo = $u; break; }
        }
        if (!$alvo) {
            responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        }
        if (!pode_gerenciar_config_de($usuarioLogado, $alvo)) {
            responder_usr(['ok' => false, 'erro' => 'Você não tem permissão para editar a configuração deste usuário.'], 403);
        }

        $chavePorTipo = ['smtp' => 'smtp', 'sms' => 'sms_gateway', 'pix' => 'pix_manual', 'mensagens' => 'mensagens'];
        if (!isset($chavePorTipo[$tipo])) {
            responder_usr(['ok' => false, 'erro' => 'Tipo de configuração inválido.'], 400);
        }

        db_update('usuarios', function (&$us) use ($idAlvo, $chavePorTipo, $tipo) {
            foreach ($us as &$u) {
                if ($u['id'] === $idAlvo) {
                    unset($u[$chavePorTipo[$tipo]]);
                    break;
                }
            }
        });
        auditoria_log($usuarioLogado['usuario'], 'CONFIG_USUARIO_REMOVIDA', "Alvo: {$alvo['usuario']} | Tipo: {$tipo}");
        responder_usr(['ok' => true]);
        break;

        responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        break;

    case 'editar':
        $id = $corpo['id'] ?? '';
        $atualizado = db_update('usuarios', function (&$usuarios) use ($id, $corpo) {
            foreach ($usuarios as &$u) {
                if ($u['id'] === $id) {
                    foreach (['nome_completo', 'email', 'ativo'] as $campo) {
                        if (array_key_exists($campo, $corpo)) $u[$campo] = $corpo[$campo];
                    }
                    if (!empty($corpo['nova_senha'])) {
                        $u['senha_hash'] = password_hash($corpo['nova_senha'], PASSWORD_DEFAULT);
                    }
                    $r = $u;
                    unset($r['senha_hash']);
                    return $r;
                }
            }
            return null;
        });
        if (!$atualizado) responder_usr(['ok' => false, 'erro' => 'Usuário não encontrado.'], 404);
        auditoria_log($usuarioLogado['usuario'], 'USUARIO_EDITADO', $id);
        responder_usr(['ok' => true, 'usuario' => $atualizado]);
        break;

    case 'deletar':
        exigir_nivel(['ADM', 'REVENDA']);
        $id = $corpo['id'] ?? '';
        db_update('usuarios', function (&$usuarios) use ($id) {
            $usuarios = array_values(array_filter($usuarios, fn($u) => $u['id'] !== $id));
        });
        auditoria_log($usuarioLogado['usuario'], 'USUARIO_DELETADO', $id);
        responder_usr(['ok' => true]);
        break;

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