<?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_srv($d, $c = 200)
{
    http_response_code($c);
    echo json_encode($d, JSON_UNESCAPED_UNICODE);
    exit;
}

/** Só o ADM ou quem criou o servidor pode editar/excluir. */
function pode_gerenciar_servidor(array $usuarioLogado, array $servidor): bool
{
    if ($usuarioLogado['nivel'] === 'ADM') {
        return true;
    }
    return ($servidor['criado_por'] ?? null) === $usuarioLogado['id'];
}

switch ($acao) {
    case 'listar':
        // Cada usuário (ADM, Revenda ou Sub-Revenda) só vê os servidores
        // que ELE MESMO cadastrou — são privados/independentes por nível.
        // O ADM é a única exceção: vê os servidores de todo mundo.
        $servidores = db_read('servidores');
        if ($usuarioLogado['nivel'] !== 'ADM') {
            $servidores = array_values(array_filter($servidores, fn($s) => ($s['criado_por'] ?? null) === $usuarioLogado['id']));
        }
        $clientes = db_read('clientes');
        // Ocupação real = clientes ATIVOS (não-teste) vinculados a cada servidor.
        // Calculado na hora (não armazenado) para nunca ficar dessincronizado.
        $ocupacaoPorServidor = [];
        foreach ($clientes as $c) {
            if (($c['status'] ?? '') === 'Ativo' && ($c['tipo'] ?? 'cliente') !== 'teste') {
                $nomeServidor = $c['servidor'] ?? '';
                $ocupacaoPorServidor[$nomeServidor] = ($ocupacaoPorServidor[$nomeServidor] ?? 0) + 1;
            }
        }
        foreach ($servidores as &$s) {
            $s['estoque_ocupado'] = $ocupacaoPorServidor[$s['nome']] ?? 0;
            $maximo = (int) ($s['estoque_maximo'] ?? 0);
            $s['estoque_livre'] = $maximo > 0 ? max(0, $maximo - $s['estoque_ocupado']) : null;
        }
        responder_srv(['ok' => true, 'servidores' => $servidores]);
        break;

    case 'criar':
        // Qualquer nível pode criar seu próprio servidor (privado, só ele
        // e o ADM enxergam).
        $novo = [
            'id' => gerar_id('SRV-'),
            'nome' => trim($corpo['nome'] ?? ''),
            'estoque_maximo' => (int) ($corpo['estoque_maximo'] ?? 0),
            'estoque_teste_disponivel' => (int) ($corpo['estoque_teste_disponivel'] ?? 0),
            'custo_mensal' => (float) ($corpo['custo_mensal'] ?? 0),
            // Integração externa (opcional): quando preenchidos, toda
            // renovação de um cliente vinculado a este servidor também
            // sincroniza automaticamente com o provedor parceiro via API.
            'dominio' => trim($corpo['dominio'] ?? ''),
            'bearer_token' => trim($corpo['bearer_token'] ?? ''),
            'package_id_padrao' => trim($corpo['package_id_padrao'] ?? ''),
            'criado_por' => $usuarioLogado['id'],
            'criado_em' => date('Y-m-d H:i:s'),
        ];
        db_update('servidores', function (&$s) use ($novo) {
            $s[] = $novo;
        });
        auditoria_log($usuarioLogado['usuario'], 'SERVIDOR_CRIADO', $novo['nome']);
        responder_srv(['ok' => true, 'servidor' => $novo]);
        break;

    case 'editar':
        $id = $corpo['id'] ?? '';
        $servidores = db_read('servidores');
        $alvo = null;
        foreach ($servidores as $s) {
            if ($s['id'] === $id) { $alvo = $s; break; }
        }
        if (!$alvo) {
            responder_srv(['ok' => false, 'erro' => 'Servidor não encontrado.'], 404);
        }
        if (!pode_gerenciar_servidor($usuarioLogado, $alvo)) {
            responder_srv(['ok' => false, 'erro' => 'Você não tem permissão para editar este servidor.'], 403);
        }
        $atualizado = db_update('servidores', function (&$servidores) use ($id, $corpo) {
            foreach ($servidores as &$s) {
                if ($s['id'] === $id) {
                    foreach (['nome', 'estoque_maximo', 'estoque_teste_disponivel', 'custo_mensal', 'dominio', 'bearer_token', 'package_id_padrao'] as $campo) {
                        if (array_key_exists($campo, $corpo)) {
                            if (in_array($campo, ['estoque_maximo', 'estoque_teste_disponivel'], true)) {
                                $s[$campo] = (int) $corpo[$campo];
                            } elseif ($campo === 'custo_mensal') {
                                $s[$campo] = (float) $corpo[$campo];
                            } elseif (in_array($campo, ['dominio', 'bearer_token', 'package_id_padrao'], true)) {
                                $s[$campo] = trim((string) $corpo[$campo]);
                            } else {
                                $s[$campo] = $corpo[$campo];
                            }
                        }
                    }
                    return $s;
                }
            }
            return null;
        });
        if (!$atualizado) responder_srv(['ok' => false, 'erro' => 'Servidor não encontrado.'], 404);
        auditoria_log($usuarioLogado['usuario'], 'SERVIDOR_EDITADO', $id);
        responder_srv(['ok' => true, 'servidor' => $atualizado]);
        break;

    case 'deletar':
        $id = $corpo['id'] ?? '';
        $servidores = db_read('servidores');
        $alvo = null;
        foreach ($servidores as $s) {
            if ($s['id'] === $id) { $alvo = $s; break; }
        }
        if (!$alvo) {
            responder_srv(['ok' => false, 'erro' => 'Servidor não encontrado.'], 404);
        }
        if (!pode_gerenciar_servidor($usuarioLogado, $alvo)) {
            responder_srv(['ok' => false, 'erro' => 'Você não tem permissão para excluir este servidor.'], 403);
        }
        db_update('servidores', function (&$s) use ($id) {
            $s = array_values(array_filter($s, fn($x) => $x['id'] !== $id));
        });
        auditoria_log($usuarioLogado['usuario'], 'SERVIDOR_DELETADO', $id);
        responder_srv(['ok' => true]);
        break;

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