import { Hono } from "hono";
import { createClient } from "../../src/compat/supabase.js";
import * as kv from "./kv_store.tsx";
import * as empresasModule from "./empresas.tsx";
import * as modulos from "./modulos.tsx";
import * as pagamentos from "./pagamentos.tsx";
import * as usuarios from "./usuarios.tsx";
import * as permissoes from "./permissoes.tsx";
import * as auditoria from "./auditoria.tsx";
import * as subscricoes from "./subscricoes.tsx";
import * as mpesa from "./mpesa.tsx";
import * as tonlineConfig from "./tonline-config.tsx";
import * as exerciciosEconomicos from "./exercicios-economicos.tsx";
import * as backups from "./backups.tsx";
import * as revendedores from "./revendedores.tsx";
import {
  validarSuperAdminTonlineRequest,
  validarAcessoEmpresaRequest,
  validarGestaoUsuariosRequest,
  validarAcessoUsuarioAlvoRequest,
  bloquearEscaladaPrivilegioUsuario,
  isUsuarioSuperAdminTonline,
  lerBodyJsonSeguro,
  reservarChavesPagamento,
  libertarReservasPagamento,
  marcarReservasPagamento,
  criarSnapshotPagamento,
  RESERVA_RENOVACAO_TTL_MS,
} from "./admin-shared-helpers.tsx";

// Rotas de Administração (Gestão de Empresas, Utilizadores e Permissões,
// Auditoria e Logs, Backup e Restauração, Migração de Dados, Planos e
// Pagamentos), extraídas de index.tsx para esta função separada
// (admin-server-7249dcd9) como Fase 1 do plano de redução do cold-start.
// Cada handler é uma cópia verbatim do handler original em index.tsx — ver
// C:\Users\admin\.claude\plans\consegues-ter-acesso-ao-greedy-rivest.md.

const adminRouter = new Hono();

// ========== EMPRESAS ==========

adminRouter.get("/empresas", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const empresas = await empresasModule.listarEmpresas();

    const empresasComConta = await Promise.all(
      empresas.map(async (emp) => {
        const conta = await pagamentos.obterContaCorrente(emp.id);
        return {
          ...emp,
          paymentStatus: conta?.statusPagamento || "em-dia",
          diasEmAtraso: conta?.diasEmAtraso || 0,
        };
      })
    );

    return c.json({ success: true, data: empresasComConta });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

adminRouter.get("/empresas/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoEmpresaRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    const empresa = await empresasModule.buscarEmpresaPorId(id);

    if (!empresa) {
      return c.json({ success: false, error: "Empresa não encontrada" }, 404);
    }

    return c.json({ success: true, data: empresa });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

adminRouter.post("/empresas", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const dados = await lerBodyJsonSeguro(c);
    const resultado = await empresasModule.criarEmpresa(dados);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado, 201);
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

adminRouter.put("/empresas/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoEmpresaRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    let dados;
    try {
      dados = await c.req.json();
    } catch (parseError) {
      return c.json({ success: false, error: "JSON inválido no body" }, 400);
    }

    const resultado = await empresasModule.atualizarEmpresa(id, dados);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

adminRouter.post("/empresas/:id/congelar-documentos", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const id = c.req.param("id");
    const resultado = await empresasModule.congelarSnapshotsDocumentosEmpresa(id);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

adminRouter.delete("/empresas/:id", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const id = c.req.param("id");
    const resultado = await empresasModule.deletarEmpresa(id);

    if (!resultado.success) {
      return c.json(resultado, 404);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

adminRouter.patch("/empresas/:id/status", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const id = c.req.param("id");
    const { status } = await c.req.json();
    const resultado = await empresasModule.alterarStatusEmpresa(id, status);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

// ========== CONFIGURAÇÃO TONLINE / EXERCÍCIOS ECONÓMICOS (admin) ==========

adminRouter.get("/tonline/subscricao-config", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const config = await tonlineConfig.obterSubscricaoConfig();
    return c.json({ success: true, data: config });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

adminRouter.put("/tonline/subscricao-config", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const dados = await lerBodyJsonSeguro(c);
    const config = await tonlineConfig.salvarSubscricaoConfig(dados, acesso.usuario?.id);
    return c.json({ success: true, data: config });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

// Comissão do Programa de Revendedores - percentual (sobre a avença) e
// activação, personalizáveis pela Tonline na aba "Planos e Pagamentos".
adminRouter.get("/revendedores/config", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const config = await revendedores.obterConfigRevendedores();
    return c.json({ success: true, data: config });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

adminRouter.put("/revendedores/config", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const dados = await lerBodyJsonSeguro(c);
    const resultado = await revendedores.atualizarConfigRevendedores(dados);
    if (!resultado.success) {
      return c.json(resultado, 400);
    }
    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

adminRouter.post("/tonline/empresas/:id/exercicios-economicos", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const empresaId = c.req.param("id");
    const dados = await lerBodyJsonSeguro(c);
    const exercicios = await exerciciosEconomicos.salvarExercicioEmpresa(empresaId, dados, acesso.usuario?.id);
    return c.json({ success: true, data: exercicios });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 400);
  }
});

adminRouter.put("/tonline/empresas/:id/exercicios-economicos/:exercicioId", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const empresaId = c.req.param("id");
    const exercicioId = c.req.param("exercicioId");
    const dados = await lerBodyJsonSeguro(c);
    const exercicios = await exerciciosEconomicos.salvarExercicioEmpresa(
      empresaId,
      { ...dados, id: exercicioId },
      acesso.usuario?.id,
    );
    return c.json({ success: true, data: exercicios });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 400);
  }
});

adminRouter.patch("/tonline/empresas/:id/exercicios-economicos/:exercicioId/estado", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const empresaId = c.req.param("id");
    const exercicioId = c.req.param("exercicioId");
    const dados = await lerBodyJsonSeguro(c);
    const exercicios = await exerciciosEconomicos.alterarEstadoExercicioEmpresa(
      empresaId,
      exercicioId,
      dados.estado,
      acesso.usuario?.id,
      dados.observacoes,
    );
    return c.json({ success: true, data: exercicios });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 400);
  }
});

// ========== MÓDULOS DA EMPRESA ==========

adminRouter.get("/empresas/:id/modulos", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoEmpresaRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    const modulosEmpresa = await modulos.obterModulosEmpresa(id);
    const totais = modulos.calcularTotais(modulosEmpresa);

    return c.json({
      success: true,
      data: {
        modulos: modulosEmpresa,
        totais
      }
    });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

adminRouter.post("/empresas/:id/modulos", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const id = c.req.param("id");
    const { modulos: modulosData } = await c.req.json();
    const resultado = await modulos.configurarModulosEmpresa(id, modulosData);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

adminRouter.post("/empresas/:id/aplicar-plano", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const id = c.req.param("id");
    const { planoId } = await c.req.json();

    let subscricaoJaExistia = false;

    const subscricaoResult = await subscricoes.criarSubscricao(id, planoId, {
      licencaPaga: true,
    });

    if (!subscricaoResult.success) {
      if (subscricaoResult.error?.includes("já possui subscrição")) {
        subscricaoJaExistia = true;

        const mudancaResult = await subscricoes.mudarPlano(id, planoId, {
          motivo: "Mudança de plano via interface",
        });

        if (!mudancaResult.success) {
          return c.json(mudancaResult, 400);
        }
      } else {
        return c.json(subscricaoResult, 400);
      }
    }

    const sincronizacaoResult = await subscricoes.sincronizarModulosComSubscricao(id);

    if (!sincronizacaoResult.success) {
      return c.json({ success: false, error: sincronizacaoResult.error }, 400);
    }

    const plano = await modulos.obterPlanoConfiguradoPorId(planoId);

    if (plano) {
      const dadosAtualizacao = {
        plano: plano.nome,
        valorAvenca: plano.avencaTotal,
        taxaInscricao: plano.taxaInscricaoTotal,
        paymentStatus: "pendente",
      };

      const atualizacao = await empresasModule.atualizarEmpresaSemValidacao(id, dadosAtualizacao);

      if (!atualizacao.success) {
        return c.json(atualizacao, 400);
      }

      if (!subscricaoJaExistia && plano.taxaInscricaoTotal > 0) {
        await pagamentos.registrarMovimento({
          empresaId: id,
          tipo: "inscricao",
          descricao: `Taxa de Inscrição - ${plano.nome}`,
          valor: -plano.taxaInscricaoTotal,
          dataMovimento: new Date().toISOString(),
          status: "pago",
          observacoes: `Subscrição ao plano ${plano.nome}`,
        });

        await pagamentos.registrarMovimento({
          empresaId: id,
          tipo: "inscricao",
          descricao: `Pagamento Taxa de Inscrição - ${plano.nome}`,
          valor: plano.taxaInscricaoTotal,
          dataMovimento: new Date().toISOString(),
          status: "pago",
          observacoes: `Pagamento da subscrição ao plano ${plano.nome}`,
        });
      }
    }

    return c.json({ success: true, message: "Plano aplicado e módulos sincronizados com sucesso" });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

// DESABILITADO NA FASE 4 - Módulos são controlados pela subscrição
adminRouter.patch("/empresas/:id/modulos/:moduloId", async (c) => {
  try {
    const id = c.req.param("id");
    const moduloId = c.req.param("moduloId");
    const { ativo } = await c.req.json();

    console.warn(`[API] Tentativa de ativar/desativar módulo manualmente bloqueada (Fase 4) - Empresa: ${id}, Módulo: ${moduloId}, Ativo: ${ativo}`);

    return c.json({
      success: false,
      error: "Módulos não podem ser ativados/desativados manualmente. Use a mudança de plano para adicionar ou remover módulos.",
      mensagem: "Para ativar/desativar módulos, altere o plano da empresa no endpoint /empresas/:id/aplicar-plano",
    }, 403);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

// ========== SUBSCRIÇÕES ==========

adminRouter.get("/empresas/:id/subscricao", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoEmpresaRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    const statusResult = await subscricoes.obterStatusSubscricao(id);

    if (!statusResult.success) {
      return c.json(statusResult, 404);
    }

    return c.json(statusResult);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/empresas/:id/subscricao/renovar", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const dados = await lerBodyJsonSeguro(c);

    const subscricaoAntesRenovar = await subscricoes.obterSubscricao(id);
    const reservasRenovacaoManual = subscricaoAntesRenovar
      ? [`manual_renewal:${id}:${subscricaoAntesRenovar.id}:${subscricaoAntesRenovar.dataProximaRenovacao}`]
      : [];
    const reservaRenovacaoManual = reservasRenovacaoManual.length
      ? await reservarChavesPagamento(
          reservasRenovacaoManual,
          { tipo: "renovacao", empresaId: id, subscricaoId: subscricaoAntesRenovar!.id, dataVencimentoAnterior: subscricaoAntesRenovar!.dataProximaRenovacao },
          RESERVA_RENOVACAO_TTL_MS,
        )
      : { success: true };

    if (!reservaRenovacaoManual.success) {
      return c.json({
        success: false,
        error: "Ja existe uma renovacao em processamento para este ciclo. Aguarde antes de tentar novamente.",
      }, 409);
    }

    const resultado = await subscricoes.registrarRenovacao(id, dados);

    if (!resultado.success) {
      if (reservasRenovacaoManual.length) await libertarReservasPagamento(reservasRenovacaoManual);
      return c.json(resultado, 400);
    }

    await revendedores.registrarComissaoSeAplicavel(
      id,
      Number(dados?.valorPago || 0),
      dados?.movimentoFinanceiroId,
    );

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/empresas/:id/subscricao/mpesa-renovar", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoEmpresaRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    const dados = await lerBodyJsonSeguro(c);
    const telefoneMpesa = String(dados?.telefoneMpesa || "").trim();
    const planoIdEscolhido = dados?.planoId ? String(dados.planoId) : "";

    if (!telefoneMpesa) {
      return c.json({ success: false, error: "Telefone M-Pesa e obrigatorio" }, 400);
    }

    try {
      mpesa.normalizarTelefoneMpesa(telefoneMpesa);
    } catch (error: any) {
      return c.json({ success: false, error: error.message || "Telefone M-Pesa invalido" }, 400);
    }

    const empresa = await empresasModule.buscarEmpresaPorId(id);
    if (!empresa) {
      return c.json({ success: false, error: "Empresa nao encontrada" }, 404);
    }

    const subscricao = await subscricoes.obterSubscricao(id);
    if (!subscricao) {
      return c.json({ success: false, error: "Subscricao nao encontrada" }, 404);
    }

    if (subscricao.estado === "CANCELED") {
      return c.json({ success: false, error: "Subscricao cancelada. Contacte o suporte para activar um novo plano." }, 400);
    }

    const planoAtual = await modulos.obterPlanoConfiguradoPorId(subscricao.planoId);
    if (!planoAtual) {
      return c.json({ success: false, error: "Plano da subscricao nao encontrado" }, 400);
    }

    const plano = planoIdEscolhido ? await modulos.obterPlanoConfiguradoPorId(planoIdEscolhido as any) : planoAtual;
    if (!plano || plano.legado) {
      return c.json({ success: false, error: "Ciclo de pagamento invalido" }, 400);
    }

    const cicloMeses = plano.cicloMeses || 1;
    const valorRecorrente = Number(plano.avencaTotal || 0);

    if (!Number.isFinite(valorRecorrente) || valorRecorrente <= 0) {
      return c.json({ success: false, error: "Valor da renovacao invalido" }, 400);
    }

    const dataVencimentoAnterior = subscricao.dataProximaRenovacao;
    const reservasRenovacao = [
      `mpesa_renewal:${empresa.id}:${subscricao.id}:${dataVencimentoAnterior}`,
    ];
    const reservaRenovacao = await reservarChavesPagamento(
      reservasRenovacao,
      {
        tipo: "renovacao",
        empresaId: empresa.id,
        subscricaoId: subscricao.id,
        planoId: plano.id,
        planoAnteriorId: planoAtual.id,
        dataVencimentoAnterior,
      },
      RESERVA_RENOVACAO_TTL_MS,
    );

    if (!reservaRenovacao.success) {
      return c.json({
        success: false,
        error: "Ja existe um pagamento M-Pesa em processamento para este ciclo. Aguarde a confirmacao antes de tentar novamente.",
      }, 409);
    }

    const checkoutResult = await mpesa.criarCheckoutC2B({
      planoId: plano.id,
      planoNome: plano.nome,
      nomeComercial: empresa.nomeComercial || empresa.nomeEmpresa,
      nuit: empresa.nuit,
      emailAdmin: empresa.email,
      telefoneMpesa,
      valorPlano: valorRecorrente,
      taxaLicenca: 0,
      cicloMeses,
    });

    const checkout = checkoutResult.checkout;

    if (!checkoutResult.success || !checkout || checkout.status !== "PAID") {
      if (mpesa.checkoutMpesaTemResultadoAmbiguo(checkout)) {
        return c.json({
          success: false,
          pending: true,
          status: "PENDING",
          error: checkoutResult.error || "O resultado do pagamento M-Pesa esta pendente. Aguarde antes de tentar novamente.",
          data: { checkout, pagamentoPendente: true },
        }, 202);
      }

      await libertarReservasPagamento(reservasRenovacao);
      return c.json({
        success: false,
        error: checkoutResult.error || "Pagamento M-Pesa nao confirmado",
        data: { checkout },
      }, checkout?.status === "CONFIG_ERROR" ? 500 : 400);
    }

    const numeroDocumento = checkout.transactionId || checkout.thirdPartyReference;
    const observacoes = `Renovacao M-Pesa confirmada. Referencia: ${checkout.thirdPartyReference}`;
    const snapshotRenovacao = criarSnapshotPagamento({
      tipo: "renovacao",
      plano,
      valorRecorrente,
      taxaLicenca: 0,
      cicloMeses,
      checkout,
      dataVencimentoAnterior,
    });

    const pagamentoResult = await pagamentos.registrarPagamentoAvenca(
      empresa.id,
      valorRecorrente,
      plano.nome,
      "mpesa",
      numeroDocumento,
      undefined,
      observacoes,
      cicloMeses,
      snapshotRenovacao
    );

    if (!pagamentoResult.success) {
      await marcarReservasPagamento(reservasRenovacao, "REVIEW_REQUIRED", {
        checkoutId: checkout.id,
        empresaId: empresa.id,
        subscricaoId: subscricao.id,
        thirdPartyReference: checkout.thirdPartyReference,
        erroProvisionamento: pagamentoResult.error,
      });
      return c.json({
        success: false,
        error: `Pagamento confirmado, mas o historico financeiro nao foi registado: ${pagamentoResult.error}`,
        data: { checkout, pagamentoConfirmado: true },
      }, 202);
    }

    const renovacaoResult = await subscricoes.registrarRenovacao(empresa.id, {
      valorPago: valorRecorrente,
      metodoPagamento: "mpesa",
      movimentoFinanceiroId: pagamentoResult.data?.id,
      mesesPagos: cicloMeses,
      planoId: plano.id,
      observacoes,
      snapshotPlano: snapshotRenovacao,
    });

    if (!renovacaoResult.success) {
      await marcarReservasPagamento(reservasRenovacao, "REVIEW_REQUIRED", {
        checkoutId: checkout.id,
        empresaId: empresa.id,
        subscricaoId: subscricao.id,
        movimentoFinanceiroId: pagamentoResult.data?.id,
        thirdPartyReference: checkout.thirdPartyReference,
        erroProvisionamento: renovacaoResult.error,
      });
      return c.json({
        success: false,
        error: `Pagamento confirmado, mas a subscricao nao foi renovada: ${renovacaoResult.error}`,
        data: { checkout, pagamento: pagamentoResult.data, pagamentoConfirmado: true },
      }, 202);
    }

    await revendedores.registrarComissaoSeAplicavel(
      empresa.id,
      valorRecorrente,
      pagamentoResult.data?.id,
    );

    const statusAtualizado = await subscricoes.obterStatusSubscricao(empresa.id);
    const proximoPagamento = statusAtualizado.data?.subscricao?.dataProximaRenovacao?.split("T")[0];

    await empresasModule.atualizarEmpresaSemValidacao(empresa.id, {
      paymentStatus: "em-dia",
      plano: plano.nome,
      valorAvenca: valorRecorrente,
      proximoPagamento,
    });

    const checkoutAtualizado = await mpesa.marcarProvisionado(checkout.id, {
      empresaId: empresa.id,
    });
    await marcarReservasPagamento(reservasRenovacao, "COMPLETED", {
      checkoutId: checkout.id,
      empresaId: empresa.id,
      subscricaoId: subscricao.id,
      movimentoFinanceiroId: pagamentoResult.data?.id,
      thirdPartyReference: checkout.thirdPartyReference,
      dataProximaRenovacao: renovacaoResult.data?.dataProximaRenovacao || proximoPagamento,
    });

    return c.json({
      success: true,
      message: "Pagamento M-Pesa confirmado. Subscricao renovada com sucesso.",
      data: {
        checkout: checkoutAtualizado || checkout,
        pagamento: pagamentoResult.data,
        subscricao: statusAtualizado.data?.subscricao,
        proximoPagamento,
      },
    });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

adminRouter.post("/subscricoes/migrar-todas", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const empresas = await empresasModule.listarEmpresas();
    const resultados = {
      total: empresas.length,
      migradas: 0,
      jaExistiam: 0,
      erros: 0,
      detalhes: [] as any[],
    };

    for (const empresa of empresas) {
      if (empresa.id === "empresa_tonline") {
        continue;
      }

      const resultado = await subscricoes.migrarEmpresaParaSubscricao(empresa.id, {
        plano: empresa.plano,
        valorAvenca: empresa.valorAvenca,
        paymentStatus: empresa.paymentStatus,
        proximoPagamento: empresa.proximoPagamento,
      });

      if (resultado.success) {
        if (resultado.data) {
          resultados.migradas++;
          resultados.detalhes.push({
            empresaId: empresa.id,
            nomeComercial: empresa.nomeComercial,
            status: "migrada",
            subscricaoId: resultado.data.id,
          });
        } else {
          resultados.jaExistiam++;
          resultados.detalhes.push({
            empresaId: empresa.id,
            nomeComercial: empresa.nomeComercial,
            status: "ja_existia",
          });
        }
      } else {
        resultados.erros++;
        resultados.detalhes.push({
          empresaId: empresa.id,
          nomeComercial: empresa.nomeComercial,
          status: "erro",
          erro: resultado.error,
        });
      }
    }

    return c.json({ success: true, data: resultados });
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/subscricoes/sincronizar-todas", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const resultado = await subscricoes.sincronizarTodasAsEmpresas();

    if (!resultado.success) {
      return c.json(resultado, 500);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

// Chamada tanto pelo cron diario (com X-Renovacoes-Secret, sem sessao de
// utilizador) como manualmente por um super-admin.
adminRouter.post("/subscricoes/processar-renovacoes", async (c) => {
  try {
    const segredoConfigurado = Deno.env.get("RENOVACOES_CRON_SECRET");
    const segredoFornecido = c.req.header("X-Renovacoes-Secret");
    const autenticadoPorSegredo = !!segredoConfigurado && segredoFornecido === segredoConfigurado;

    if (!autenticadoPorSegredo) {
      const acesso = await validarSuperAdminTonlineRequest(c);
      if (!acesso.permitido) return acesso.resposta;
    }

    const resultado = await subscricoes.processarRenovacoes();

    if (!resultado.success) {
      return c.json(resultado, 500);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.get("/subscricoes/por-estado/:estado", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const estado = c.req.param("estado") as any;
    const subscricoes_lista = await subscricoes.listarSubscricoesPorEstado(estado);

    return c.json({ success: true, data: subscricoes_lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.get("/subscricoes/vencimentos", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const dias = parseInt(c.req.query("dias") || "7");
    const resultado = await subscricoes.obterRelatorioVencimentos(dias);

    if (!resultado.success) {
      return c.json(resultado, 500);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.get("/subscricoes/estatisticas", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const resultado = await subscricoes.obterEstatisticas();

    if (!resultado.success) {
      return c.json(resultado, 500);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

// ========== PAGAMENTOS ==========

adminRouter.post("/pagamentos", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const dados = await lerBodyJsonSeguro(c);
    const resultado = await pagamentos.registrarMovimento(dados);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado, 201);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/empresas/:id/pagar-avenca", async (c) => {
  const { id } = c.req.param();
  const { valor, mesReferencia, mesesAdiantados = 1, metodoPagamento, numeroDocumento, observacoes, planoId } = await c.req.json();
  let reservasPagarAvenca: string[] = [];

  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    // planoId e opcional: quando enviado (ex: admin escolheu "12 Meses -
    // Anual"), a subscricao passa a reflectir esse plano (preco recorrente e
    // ciclo) em vez de manter apenas o plano anterior. Sem isto, um pagamento
    // que muda o ciclo do cliente (ex: mensal -> anual) so estendia a data de
    // renovacao, deixando planoId/valorRecorrenteAtual desactualizados.
    let planoEscolhido: Awaited<ReturnType<typeof modulos.obterPlanoConfiguradoPorId>> = null;
    if (planoId) {
      planoEscolhido = await modulos.obterPlanoConfiguradoPorId(planoId);
      if (!planoEscolhido || planoEscolhido.legado) {
        return c.json({ success: false, error: "Plano seleccionado invalido" }, 400);
      }
    }

    const subscricaoAntesPagarAvenca = await subscricoes.obterSubscricao(id);
    if (subscricaoAntesPagarAvenca) {
      reservasPagarAvenca = [
        `manual_renewal:${id}:${subscricaoAntesPagarAvenca.id}:${subscricaoAntesPagarAvenca.dataProximaRenovacao}`,
      ];
      const reservaPagarAvenca = await reservarChavesPagamento(
        reservasPagarAvenca,
        { tipo: "renovacao", empresaId: id, subscricaoId: subscricaoAntesPagarAvenca.id, dataVencimentoAnterior: subscricaoAntesPagarAvenca.dataProximaRenovacao },
        RESERVA_RENOVACAO_TTL_MS,
      );
      if (!reservaPagarAvenca.success) {
        return c.json({
          success: false,
          error: "Ja existe um pagamento de avenca em processamento para este ciclo. Aguarde antes de tentar novamente.",
        }, 409);
      }
    }

    const valorPorMes = valor / mesesAdiantados;
    const hoje = new Date();

    const vencimentoActualPagarAvenca = subscricaoAntesPagarAvenca
      ? new Date(subscricaoAntesPagarAvenca.dataProximaRenovacao)
      : null;
    const baseProximaDataPagarAvenca =
      vencimentoActualPagarAvenca && !Number.isNaN(vencimentoActualPagarAvenca.getTime()) && vencimentoActualPagarAvenca > hoje
        ? vencimentoActualPagarAvenca
        : hoje;
    const proximaData = new Date(baseProximaDataPagarAvenca);
    proximaData.setMonth(proximaData.getMonth() + mesesAdiantados);

    const descricaoPagamento = mesesAdiantados > 1
      ? `Pagamento de Avença - ${mesesAdiantados} Meses (${mesReferencia})`
      : `Pagamento de Avença - ${mesReferencia}`;

    const movimentoPagarAvencaResult = await pagamentos.registrarMovimento({
      empresaId: id,
      tipo: "avenca",
      descricao: descricaoPagamento,
      valor: valor,
      dataMovimento: hoje.toISOString(),
      dataPagamento: hoje.toISOString(),
      proximaDataPagamento: proximaData.toISOString(),
      metodoPagamento,
      numeroDocumento,
      status: "pago",
      observacoes: observacoes || `Pagamento adiantado de ${mesesAdiantados} meses`,
    });

    await revendedores.registrarComissaoSeAplicavel(
      id,
      valor,
      movimentoPagarAvencaResult.data?.id,
    );

    for (let i = 0; i < mesesAdiantados; i++) {
      const mesData = new Date(mesReferencia);
      mesData.setMonth(mesData.getMonth() + i);
      const mesFormatado = mesData.toISOString().slice(0, 7);

      await pagamentos.registrarMovimento({
        empresaId: id,
        tipo: "avenca",
        descricao: `Avença Mensal - ${mesFormatado}`,
        valor: -valorPorMes,
        dataMovimento: hoje.toISOString(),
        dataPagamento: hoje.toISOString(),
        status: "pago",
        observacoes: `Pago antecipadamente em ${hoje.toLocaleDateString('pt-MZ')}`,
      });
    }

    const renovacaoResult = await subscricoes.registrarRenovacao(id, {
      valorPago: valor,
      metodoPagamento,
      mesesPagos: mesesAdiantados,
      planoId: planoEscolhido?.id,
      observacoes: `Pagamento de ${mesesAdiantados} ${mesesAdiantados === 1 ? 'mês' : 'meses'}`,
    });

    if (!renovacaoResult.success) {
      if (reservasPagarAvenca.length) await libertarReservasPagamento(reservasPagarAvenca);
      return c.json(renovacaoResult, 400);
    }

    // Sem isto, empresa.paymentStatus ficava preso em "pendente" (valor
    // definido por /aplicar-plano) para sempre, mesmo com a subscricao
    // renovada com sucesso acima — ao contrario do fluxo mpesa-renovar, que
    // ja sincroniza este campo. UI que le empresa.paymentStatus directamente
    // (em vez do estado da subscricao) ficava a mostrar "pendente" indevido.
    const statusAtualizadoPagarAvenca = await subscricoes.obterStatusSubscricao(id);
    const proximoPagamentoPagarAvenca = statusAtualizadoPagarAvenca.data?.subscricao?.dataProximaRenovacao?.split("T")[0];
    await empresasModule.atualizarEmpresaSemValidacao(id, {
      paymentStatus: "em-dia",
      proximoPagamento: proximoPagamentoPagarAvenca,
      ...(planoEscolhido ? { plano: planoEscolhido.nome } : {}),
    });

    return c.json({ success: true, message: "Pagamento registrado com sucesso" });
  } catch (error: any) {
    if (reservasPagarAvenca.length) await libertarReservasPagamento(reservasPagarAvenca);
    return c.json({ success: false, error: error.message }, 500);
  }
});

// Agenda uma mudança de plano para entrar em vigor só no início do próximo
// ciclo (fim do ciclo actual já pago) — ao contrário de /aplicar-plano, que
// troca o plano de imediato sem cobrança. O novo plano é cobrado já, na
// hora, mas só passa a valer (módulos, valor recorrente, ciclo) quando
// processarRenovacoes() detectar que o ciclo actual terminou. Ver
// subscricoes.agendarMudancaPlano().
adminRouter.post("/empresas/:id/agendar-mudanca-plano", async (c) => {
  const { id } = c.req.param();
  const { planoId, metodoPagamento, numeroDocumento, observacoes } = await c.req.json();
  let reservasAgendarMudanca: string[] = [];

  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    if (!planoId) {
      return c.json({ success: false, error: "planoId é obrigatório" }, 400);
    }

    const planoNovo = await modulos.obterPlanoConfiguradoPorId(planoId);
    if (!planoNovo || planoNovo.legado) {
      return c.json({ success: false, error: "Plano seleccionado inválido" }, 400);
    }

    const subscricaoActualAgendarMudanca = await subscricoes.obterSubscricao(id);
    if (!subscricaoActualAgendarMudanca) {
      return c.json({ success: false, error: "Subscrição não encontrada" }, 404);
    }

    if (planoId === subscricaoActualAgendarMudanca.planoId) {
      return c.json({ success: false, error: "A empresa já está neste plano" }, 400);
    }

    reservasAgendarMudanca = [
      `plano_agendado:${id}:${subscricaoActualAgendarMudanca.id}:${subscricaoActualAgendarMudanca.dataProximaRenovacao}`,
    ];
    const reservaAgendarMudanca = await reservarChavesPagamento(
      reservasAgendarMudanca,
      {
        tipo: "renovacao",
        empresaId: id,
        subscricaoId: subscricaoActualAgendarMudanca.id,
        dataVencimentoAnterior: subscricaoActualAgendarMudanca.dataProximaRenovacao,
      },
      RESERVA_RENOVACAO_TTL_MS,
    );
    if (!reservaAgendarMudanca.success) {
      return c.json({
        success: false,
        error: "Já existe uma operação de pagamento em processamento para este ciclo. Aguarde antes de tentar novamente.",
      }, 409);
    }

    const valorPago = planoNovo.avencaTotal;
    const dataEfetivacao = subscricaoActualAgendarMudanca.dataProximaRenovacao;
    const hoje = new Date().toISOString();

    const movimentoAgendarMudancaResult = await pagamentos.registrarMovimento({
      empresaId: id,
      tipo: "avenca",
      descricao: `Pagamento antecipado - mudança para ${planoNovo.nome} (efectiva em ${dataEfetivacao.split("T")[0]})`,
      valor: valorPago,
      dataMovimento: hoje,
      dataPagamento: hoje,
      metodoPagamento,
      numeroDocumento,
      status: "pago",
      observacoes: observacoes || "Mudança de plano paga antecipadamente — só entra em vigor no início do próximo ciclo.",
    });

    if (!movimentoAgendarMudancaResult.success) {
      await libertarReservasPagamento(reservasAgendarMudanca);
      return c.json(movimentoAgendarMudancaResult, 400);
    }

    const cicloNovoAgendarMudanca = planoNovo.cicloMeses || 1;
    await pagamentos.registrarMovimento({
      empresaId: id,
      tipo: "avenca",
      descricao: `1º ciclo de ${planoNovo.nome} (${cicloNovoAgendarMudanca} ${cicloNovoAgendarMudanca === 1 ? "mês" : "meses"}), a partir de ${dataEfetivacao.split("T")[0]}`,
      valor: -valorPago,
      dataMovimento: hoje,
      dataPagamento: hoje,
      status: "pago",
      observacoes: "Pago antecipadamente — aguarda o fim do ciclo actual para entrar em vigor.",
    });

    const resultadoAgendarMudanca = await subscricoes.agendarMudancaPlano(id, planoId, {
      movimentoFinanceiroId: movimentoAgendarMudancaResult.data?.id,
      motivo: "Mudança de plano agendada via interface (Planos e Pagamentos)",
    });

    if (!resultadoAgendarMudanca.success) {
      await libertarReservasPagamento(reservasAgendarMudanca);
      return c.json(resultadoAgendarMudanca, 400);
    }

    return c.json({
      success: true,
      message: `Mudança para ${planoNovo.nome} agendada e paga com sucesso — entra em vigor em ${resultadoAgendarMudanca.data?.dataEfetivacao?.split("T")[0]}.`,
      data: resultadoAgendarMudanca.data,
    });
  } catch (error: any) {
    if (reservasAgendarMudanca.length) await libertarReservasPagamento(reservasAgendarMudanca);
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/empresas/:id/cancelar-mudanca-plano-agendada", async (c) => {
  const { id } = c.req.param();

  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const corpo = await c.req.json().catch(() => ({ motivo: undefined }));
    const resultado = await subscricoes.cancelarMudancaPlanoAgendada(
      id,
      corpo?.motivo || "Cancelado via interface",
    );
    if (!resultado.success) return c.json(resultado, 400);

    return c.json({ success: true, message: "Mudança de plano agendada foi cancelada." });
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.get("/empresas/:id/movimentos", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoEmpresaRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    const movimentos = await pagamentos.listarMovimentosEmpresa(id);

    return c.json({ success: true, data: movimentos });
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.get("/empresas/:id/conta-corrente", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoEmpresaRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    const contaCorrente = await pagamentos.obterContaCorrente(id);

    if (!contaCorrente) {
      return c.json({ success: false, error: "Conta corrente não encontrada" }, 404);
    }

    return c.json({ success: true, data: contaCorrente });
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.get("/empresas/:id/anos-fiscais", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoEmpresaRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    const exercicios = await exerciciosEconomicos.listarExerciciosEmpresa(id);
    const anos = Array.from(
      new Set(
        exercicios
          .map((item) => Number(item?.ano))
          .filter((ano) => Number.isFinite(ano) && ano > 0),
      ),
    ).sort((a, b) => a - b);

    return c.json({ success: true, data: anos });
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.patch("/pagamentos/:id/status", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const id = c.req.param("id");
    const { status, dataPagamento } = await c.req.json();
    const resultado = await pagamentos.atualizarStatusPagamento(id, status, dataPagamento);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.delete("/pagamentos/:id", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const id = c.req.param("id");
    const { motivo } = await c.req.json();
    const resultado = await pagamentos.cancelarMovimento(id, motivo);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

// ========== UTILIZADORES ==========

adminRouter.get("/usuarios", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const todosUsuarios = await usuarios.listarTodosUsuarios();

    return c.json({ success: true, data: todosUsuarios });
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/usuarios", async (c) => {
  try {
    const gestao = await validarGestaoUsuariosRequest(c);
    if (!gestao.permitido) return gestao.resposta;

    const dados = await c.req.json();

    if (!isUsuarioSuperAdminTonline(gestao.usuario)) {
      dados.empresaId = gestao.usuario.empresaId;
    }
    const bloqueio = bloquearEscaladaPrivilegioUsuario(c, gestao.usuario, dados);
    if (bloqueio) return bloqueio;

    const resultado = await usuarios.criarUsuario(dados);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado, 201);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.put("/usuarios/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoUsuarioAlvoRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    const dados = await c.req.json();
    const bloqueio = bloquearEscaladaPrivilegioUsuario(c, acesso.usuario, dados);
    if (bloqueio) return bloqueio;

    const resultado = await usuarios.atualizarUsuario(id, dados);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/usuarios/:id/resetar-senha", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoUsuarioAlvoRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    const { novaSenha } = await c.req.json();

    if (!novaSenha || novaSenha.length < 6) {
      return c.json({
        success: false,
        error: "Senha deve ter pelo menos 6 caracteres"
      }, 400);
    }

    const resultado = await usuarios.atualizarUsuario(id, { password: novaSenha });

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json({
      success: true,
      message: "Senha resetada com sucesso"
    });
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/usuarios/:id/modulos", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoUsuarioAlvoRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    const { modulosPermitidos } = await c.req.json();
    const resultado = await usuarios.atribuirModulos(id, modulosPermitidos);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.patch("/usuarios/:id/toggle", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoUsuarioAlvoRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    const { ativo } = await c.req.json();
    const resultado = await usuarios.toggleUsuario(id, ativo);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.delete("/usuarios/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const acesso = await validarAcessoUsuarioAlvoRequest(c, id);
    if (!acesso.permitido) return acesso.resposta;

    const resultado = await usuarios.deletarUsuario(id);

    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    return c.json(resultado);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

// ========== BACKUP E RESTAURAÇÃO ==========
// (a validacao de acesso a cada rota vive agora dentro de backups.tsx —
// antes desta extracao, nenhuma destas rotas tinha qualquer verificacao)

adminRouter.get("/empresas/:empresaId/backups", backups.listarBackups);
adminRouter.post("/empresas/:empresaId/backups", backups.criarBackupManual);
adminRouter.post("/empresas/:empresaId/backups/recuperar-facturas", backups.recuperarFacturasEmpresa);
adminRouter.get("/empresas/:empresaId/backups/:backupId/download", backups.gerarBackupDownloadUrl);
adminRouter.post("/empresas/:empresaId/backups/:backupId/restaurar", backups.restaurarBackup);
adminRouter.post("/backups/recuperar-facturas", backups.recuperarFacturasTodasEmpresas);
adminRouter.post("/backups/recuperar-facturas-payload", backups.recuperarFacturasPayload);
adminRouter.post("/backups/regularizar-sequencia-facturas", backups.regularizarSequenciaFacturas);
adminRouter.post("/backups/automatico-diario", backups.executarBackupAutomaticoDiario);

// ========== MIGRAÇÃO DE DADOS ==========

adminRouter.post("/migrar-formato-numeros", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const todasCotacoes = await kv.getByPrefix("cotacao:");
    const todasFacturas = await kv.getByPrefix("factura:");
    const todosRecibos = await kv.getByPrefix("recibo:");
    const todasVDs = await kv.getByPrefix("venda-dinheiro:");
    const todosAdiantamentos = await kv.getByPrefix("adiantamento:");

    let totalAtualizados = 0;

    for (const cotacao of todasCotacoes) {
      if (cotacao.numeroDocumento && !cotacao.numeroDocumento.includes(" nº ")) {
        const match = cotacao.numeroDocumento.match(/^Cotação\s+(\d+\/\d{4})$/);
        if (match) {
          cotacao.numeroDocumento = `Cotação nº ${match[1]}`;
          await kv.set(cotacao.id, cotacao);
          totalAtualizados++;
        }
      }
    }

    for (const factura of todasFacturas) {
      if (factura.numeroDocumento && !factura.numeroDocumento.includes(" nº ")) {
        const match = factura.numeroDocumento.match(/^Factura\s+(\d+\/\d{4})$/);
        if (match) {
          factura.numeroDocumento = `Factura nº ${match[1]}`;
          await kv.set(factura.id, factura);
          totalAtualizados++;
        }
      }
    }

    for (const recibo of todosRecibos) {
      if (recibo.numeroDocumento && !recibo.numeroDocumento.includes(" nº ")) {
        const match = recibo.numeroDocumento.match(/^Recibo\s+(\d+\/\d+\/\d{4})$/);
        if (match) {
          recibo.numeroDocumento = `Recibo nº ${match[1]}`;
          await kv.set(recibo.id, recibo);
          totalAtualizados++;
        }
      }
    }

    for (const vd of todasVDs) {
      if (vd.numeroDocumento && !vd.numeroDocumento.includes(" nº ")) {
        const match = vd.numeroDocumento.match(/^VD\s+(\d+\/\d{4})$/);
        if (match) {
          vd.numeroDocumento = `VD nº ${match[1]}`;
          await kv.set(vd.id, vd);
          totalAtualizados++;
        }
      }
    }

    for (const adiantamento of todosAdiantamentos) {
      if (adiantamento.numeroDocumento && !adiantamento.numeroDocumento.includes(" nº ")) {
        const match = adiantamento.numeroDocumento.match(/^Adiantamento\s+(\d+\/\d{4})$/);
        if (match) {
          adiantamento.numeroDocumento = `Adiantamento nº ${match[1]}`;
          await kv.set(adiantamento.id, adiantamento);
          totalAtualizados++;
        }
      }
    }

    return c.json({
      success: true,
      message: `Migração concluída! ${totalAtualizados} documentos atualizados.`,
      detalhes: {
        cotacoes: todasCotacoes.length,
        facturas: todasFacturas.length,
        recibos: todosRecibos.length,
        vds: todasVDs.length,
        adiantamentos: todosAdiantamentos.length,
        totalAtualizados
      }
    });
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

// ========== ROTAS DE DEBUG DE UTILIZADORES (reparação de dados) ==========
// Gated pela mesma variavel ENABLE_DEBUG_ENDPOINTS que a funcao principal
// (ver middleware em admin-server-7249dcd9/index.ts).

adminRouter.post("/debug/verificar-empresaid", async (c) => {
  try {
    const acessoDebugVerificar = await validarSuperAdminTonlineRequest(c);
    if (!acessoDebugVerificar.permitido) return acessoDebugVerificar.resposta;

    const body = await c.req.json();
    const { email } = body;

    const supabase = createClient(
      Deno.env.get('SUPABASE_URL') ?? '',
      Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
    );

    const { data: todosUsuarios } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .like('key', 'usuario:%');

    const ocorrencias = todosUsuarios?.filter((item: any) => {
      return item.value.email?.toLowerCase() === email.toLowerCase();
    }) || [];

    if (ocorrencias.length === 0) {
      const emailsDisponiveis = todosUsuarios?.slice(0, 5).map((u: any) => u.value.email).filter(Boolean) || [];
      return c.json({
        success: false,
        error: `Usuário ${email} não encontrado`,
        emailsDisponiveis
      }, 404);
    }

    const todasEmpresas = await kv.getByPrefix('empresa:');
    const empresasMap = new Map();
    todasEmpresas.forEach((e: any) => {
      empresasMap.set(e.id, e);
    });

    const analise = ocorrencias.map((item: any) => {
      const usuario = item.value;
      const chaveEmpresa = `empresa:${usuario.empresaId}`;
      const empresa = empresasMap.get(chaveEmpresa);

      return {
        chave: item.key,
        usuario: {
          nome: usuario.nome,
          email: usuario.email,
          empresaId: usuario.empresaId,
          nivel: usuario.nivel,
          modulosPermitidos: usuario.modulosPermitidos,
          dataCriacao: usuario.dataCriacao
        },
        empresa: empresa ? {
          id: chaveEmpresa,
          nome: empresa.nomeComercial || empresa.nomeEmpresa,
          nuit: empresa.nuit
        } : {
          id: usuario.empresaId,
          nome: 'EMPRESA NÃO EXISTE',
          nuit: null
        },
        VALIDO: !!empresa
      };
    });

    const problemas = [];
    if (ocorrencias.length > 1) {
      problemas.push(`${ocorrencias.length} DUPLICATAS ENCONTRADAS!`);
    }
    const empresasInvalidas = analise.filter(a => !a.VALIDO);
    if (empresasInvalidas.length > 0) {
      problemas.push(`${empresasInvalidas.length} registro(s) com empresa inexistente!`);
    }

    return c.json({
      success: true,
      email,
      totalOcorrencias: ocorrencias.length,
      ocorrencias: analise,
      problemas,
      empresasDisponiveis: todasEmpresas.map((e: any) => ({
        id: e.id,
        nome: e.nomeComercial || e.nomeEmpresa,
        nuit: e.nuit
      })),
      CRITICO: problemas.length > 0
    });

  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/debug/migrar-usuario", async (c) => {
  try {
    const acessoDebugMigrar = await validarSuperAdminTonlineRequest(c);
    if (!acessoDebugMigrar.permitido) return acessoDebugMigrar.resposta;

    const body = await c.req.json();
    const { busca } = body;

    const supabase = createClient(
      Deno.env.get('SUPABASE_URL') ?? '',
      Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
    );

    const { data: todosUsuarios, error } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .like('key', 'usuario:%');

    if (error) {
      return c.json({ success: false, error: error.message }, 500);
    }

    const usuarioEncontrado = todosUsuarios?.find((item: any) => {
      const usuario = item.value;
      return usuario.nome?.toLowerCase().includes(busca.toLowerCase()) ||
             usuario.email?.toLowerCase().includes(busca.toLowerCase());
    });

    if (!usuarioEncontrado) {
      return c.json({
        success: false,
        error: `Usuário ${busca} não encontrado`
      }, 404);
    }

    const chave = usuarioEncontrado.key;
    const usuario = usuarioEncontrado.value;

    if (usuario.nivel === 'usuario' && !usuario.modulosPermitidos && usuario.permissoesModulos) {
      const modulosPermitidos: string[] = [];

      for (const [categoria, modulos] of Object.entries(usuario.permissoesModulos)) {
        if (typeof modulos === 'object' && modulos !== null) {
          for (const [modulo, permissoes] of Object.entries(modulos)) {
            if (typeof permissoes === 'object' && permissoes !== null) {
              const temPermissao = Object.values(permissoes).some((p: any) => p === true);
              if (temPermissao) {
                const moduloId = `${categoria}.${modulo}`;
                if (!modulosPermitidos.includes(moduloId)) {
                  modulosPermitidos.push(moduloId);
                }
              }
            }
          }
        }
      }

      const usuarioMigrado = {
        ...usuario,
        modulosPermitidos: modulosPermitidos
      };

      const { error: updateError } = await supabase
        .from('kv_store_7249dcd9')
        .update({ value: usuarioMigrado })
        .eq('key', chave);

      if (updateError) {
        return c.json({ success: false, error: updateError.message }, 500);
      }

      return c.json({
        success: true,
        message: 'Usuário migrado com sucesso!',
        antes: {
          modulosPermitidos: usuario.modulosPermitidos
        },
        depois: {
          modulosPermitidos: modulosPermitidos
        },
        totalModulos: modulosPermitidos.length
      });
    }

    if (usuario.nivel === 'admin' || usuario.nivel === 'super_admin' || usuario.nivel === 'admin_empresa') {
      return c.json({
        success: true,
        message: `Usuário é ${usuario.nivel}, não precisa de modulosPermitidos`,
        info: 'Admins têm acesso a todos os módulos automaticamente'
      });
    }

    if (usuario.modulosPermitidos) {
      return c.json({
        success: true,
        message: 'Usuário já tem modulosPermitidos',
        modulosPermitidos: usuario.modulosPermitidos
      });
    }

    return c.json({
      success: false,
      message: 'Usuário não tem permissoesModulos para extrair'
    });

  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/debug/corrigir-tenant", async (c) => {
  try {
    const acessoDebugCorrigirTenant = await validarSuperAdminTonlineRequest(c);
    if (!acessoDebugCorrigirTenant.permitido) return acessoDebugCorrigirTenant.resposta;

    const body = await c.req.json();
    const { email, empresaIdCorreta } = body;

    const supabase = createClient(
      Deno.env.get('SUPABASE_URL') ?? '',
      Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
    );

    const { data: todosUsuarios } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .like('key', 'usuario:%');

    const ocorrencias = todosUsuarios?.filter((item: any) => {
      return item.value.email?.toLowerCase() === email.toLowerCase();
    }) || [];

    if (ocorrencias.length === 0) {
      return c.json({ success: false, error: 'Usuário não encontrado' }, 404);
    }

    const { data: empresaData } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .eq('key', `empresa:${empresaIdCorreta}`)
      .single();

    if (!empresaData) {
      return c.json({ success: false, error: `Empresa não existe: ${empresaIdCorreta}` }, 400);
    }

    const registroPrincipal = ocorrencias.reduce((prev: any, current: any) => {
      const prevData = new Date(prev.value.dataCriacao || 0);
      const currentData = new Date(current.value.dataCriacao || 0);
      return prevData < currentData ? prev : current;
    });

    const usuarioCorrigido = {
      ...registroPrincipal.value,
      empresaId: empresaIdCorreta
    };

    await supabase
      .from('kv_store_7249dcd9')
      .update({ value: usuarioCorrigido })
      .eq('key', registroPrincipal.key);

    const duplicatas = ocorrencias.filter((o: any) => o.key !== registroPrincipal.key);
    for (const dup of duplicatas) {
      await supabase
        .from('kv_store_7249dcd9')
        .delete()
        .eq('key', dup.key);
    }

    return c.json({
      success: true,
      message: 'Tenant corrigido!',
      resultado: {
        chave: registroPrincipal.key,
        empresaAntes: registroPrincipal.value.empresaId,
        empresaDepois: empresaIdCorreta,
        duplicatasRemovidas: duplicatas.length,
        empresa: empresaData.value.nomeComercial
      }
    });

  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/debug/diagnosticar-usuario", async (c) => {
  try {
    const acessoDebugDiagnosticar = await validarSuperAdminTonlineRequest(c);
    if (!acessoDebugDiagnosticar.permitido) return acessoDebugDiagnosticar.resposta;

    const body = await c.req.json();
    const { busca } = body;

    const supabase = createClient(
      Deno.env.get('SUPABASE_URL') ?? '',
      Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
    );

    const { data: todosUsuarios, error } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .like('key', 'usuario:%');

    if (error) {
      return c.json({ success: false, error: error.message }, 500);
    }

    const ocorrencias = todosUsuarios?.filter((item: any) => {
      const usuario = item.value;
      return usuario.nome?.toLowerCase().includes(busca.toLowerCase()) ||
             usuario.email?.toLowerCase().includes(busca.toLowerCase());
    }) || [];

    const diagnostico = ocorrencias.map((item: any) => {
      const inconsistencias = [];

      if (item.value.id !== item.key) {
        inconsistencias.push(`ID interno (${item.value.id}) != Chave (${item.key})`);
      }

      if (!item.value.permissoes || typeof item.value.permissoes !== 'object') {
        inconsistencias.push('Permissoes inválidas');
      }

      if (!item.value.empresaId) {
        inconsistencias.push('Sem empresaId');
      }

      return {
        chave: item.key,
        idInterno: item.value.id,
        nome: item.value.nome,
        email: item.value.email,
        empresaId: item.value.empresaId,
        nivel: item.value.nivel,
        inconsistencias: inconsistencias,
        temProblemas: inconsistencias.length > 0
      };
    });

    return c.json({
      success: true,
      busca: busca,
      totalOcorrencias: ocorrencias.length,
      ocorrencias: diagnostico,
      temDuplicatas: ocorrencias.length > 1,
      temProblemas: diagnostico.some((d: any) => d.temProblemas)
    });
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/debug/reparar-usuario", async (c) => {
  try {
    const acessoDebugReparar = await validarSuperAdminTonlineRequest(c);
    if (!acessoDebugReparar.permitido) return acessoDebugReparar.resposta;

    const body = await c.req.json();
    const { busca } = body;

    const supabase = createClient(
      Deno.env.get('SUPABASE_URL') ?? '',
      Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
    );

    const { data: todosUsuarios, error } = await supabase
      .from('kv_store_7249dcd9')
      .select('*')
      .like('key', 'usuario:%');

    if (error) {
      return c.json({ success: false, error: error.message }, 500);
    }

    const ocorrencias = todosUsuarios?.filter((item: any) => {
      const usuario = item.value;
      return usuario.nome?.toLowerCase().includes(busca.toLowerCase()) ||
             usuario.email?.toLowerCase().includes(busca.toLowerCase());
    }) || [];

    if (ocorrencias.length === 0) {
      return c.json({
        success: false,
        error: `Usuário ${busca} não encontrado`
      }, 404);
    }

    if (ocorrencias.length > 1) {
      const usuarioBase = ocorrencias[0].value;
      const chaveCorreta = ocorrencias[0].key;

      for (const item of ocorrencias) {
        await supabase
          .from('kv_store_7249dcd9')
          .delete()
          .eq('key', item.key);
      }

      const usuarioCorrigido = {
        ...usuarioBase,
        id: chaveCorreta
      };

      const { error: insertError } = await supabase
        .from('kv_store_7249dcd9')
        .insert({
          key: chaveCorreta,
          value: usuarioCorrigido
        });

      if (insertError) {
        return c.json({ success: false, error: insertError.message }, 500);
      }

      return c.json({
        success: true,
        message: `${ocorrencias.length} duplicatas removidas e usuário recriado!`,
        acao: 'LIMPEZA_COMPLETA',
        chaveFinal: chaveCorreta
      });
    }

    const chaveAtual = ocorrencias[0].key;
    const usuario = ocorrencias[0].value;

    const problemaDetectado = usuario.id !== chaveAtual;

    if (!problemaDetectado) {
      return c.json({
        success: true,
        message: 'Usuário está correto, não precisa reparar',
        usuario: {
          chave: chaveAtual,
          nome: usuario.nome,
          email: usuario.email
        }
      });
    }

    const usuarioCorrigido = {
      ...usuario,
      id: chaveAtual
    };

    const { error: updateError } = await supabase
      .from('kv_store_7249dcd9')
      .update({ value: usuarioCorrigido })
      .eq('key', chaveAtual);

    if (updateError) {
      return c.json({ success: false, error: updateError.message }, 500);
    }

    return c.json({
      success: true,
      message: 'Usuário reparado com sucesso!',
      acao: 'CORRECAO_ID',
      antes: {
        chave: chaveAtual,
        idValue: usuario.id
      },
      depois: {
        chave: chaveAtual,
        idValue: chaveAtual
      }
    });
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

// ========== UTILIZADORES E PERMISSÕES (usuarios-permissoes) ==========

adminRouter.get("/empresas/:empresaId/usuarios-permissoes", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;

    const resultSync = await permissoes.sincronizarUsuariosEmpresa(empresaId);

    if (resultSync.success && resultSync.data && resultSync.data.length > 0) {
      return c.json(resultSync);
    }

    const result = await permissoes.buscarUsuariosPorEmpresa(empresaId);
    return c.json(result);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/usuarios-permissoes/migrar-auth-ids", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const todosUsuarios = await kv.getByPrefixWithKeys('usuario:');

    let migrados = 0;
    let erros = 0;
    let jaTemAuthUserId = 0;

    for (const item of todosUsuarios) {
      if (!item || !item.key) {
        continue;
      }

      if (item.key.includes('email:')) {
        continue;
      }

      const usuario = item.value;

      if (!usuario || typeof usuario !== 'object' || !usuario.id) {
        continue;
      }

      if (usuario.authUserId) {
        jaTemAuthUserId++;
        continue;
      }

      usuario.authUserId = usuario.id;

      try {
        await kv.set(item.key, usuario);
        migrados++;
      } catch (error) {
        erros++;
      }
    }

    return c.json({
      success: true,
      message: 'Migração concluída',
      migrados,
      jaTemAuthUserId,
      erros
    });
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.post("/usuarios-permissoes", async (c) => {
  try {
    const gestao = await validarGestaoUsuariosRequest(c);
    if (!gestao.permitido) return gestao.resposta;

    const body = await c.req.json();
    const { dadosUsuario, criadoPor } = body;

    if (!isUsuarioSuperAdminTonline(gestao.usuario)) {
      dadosUsuario.empresaId = gestao.usuario.empresaId;
    }
    const bloqueio = bloquearEscaladaPrivilegioUsuario(c, gestao.usuario, dadosUsuario);
    if (bloqueio) return bloqueio;

    const result = await permissoes.criarUsuario(dadosUsuario, criadoPor);

    if (result.success) {
      const mensagem = `${body.criadoPorNome || 'Sistema'} criou o usuario ${dadosUsuario.nome}${dadosUsuario.email ? ` (${dadosUsuario.email})` : ''} com nivel ${dadosUsuario.nivel}.`;
      await auditoria.registrarLog({
        empresaId: dadosUsuario.empresaId,
        usuarioId: criadoPor,
        usuarioNome: body.criadoPorNome || 'Sistema',
        usuarioEmail: body.criadoPorEmail || '',
        operacao: 'criar_usuario',
        documentoTipo: 'usuario',
        documentoNumero: dadosUsuario.nome,
        entidadeTipo: 'usuario',
        entidadeNome: dadosUsuario.nome,
        modulo: 'permissoes',
        moduloNome: 'Usuarios e Permissoes',
        titulo: `Usuario criado - ${dadosUsuario.nome}`,
        mensagem,
        detalhes: mensagem,
        detalhesTexto: mensagem,
        metadata: {
          usuarioCriado: {
            nome: dadosUsuario.nome,
            email: dadosUsuario.email,
            nivel: dadosUsuario.nivel,
            ativo: dadosUsuario.ativo ?? true,
          },
        },
        origem: 'backend',
        tags: ['usuarios', 'permissoes'],
      });
    }

    return c.json(result);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.patch("/usuarios-permissoes/:usuarioId/permissoes", async (c) => {
  try {
    const usuarioId = c.req.param("usuarioId");
    const acesso = await validarAcessoUsuarioAlvoRequest(c, usuarioId);
    if (!acesso.permitido) return acesso.resposta;

    const body = await c.req.json();
    const { novasPermissoes, atualizadoPor, atualizadoPorNome, atualizadoPorEmail, empresaId } = body;
    const bloqueio = bloquearEscaladaPrivilegioUsuario(c, acesso.usuario, { permissoes: novasPermissoes });
    if (bloqueio) return bloqueio;

    const usuarioAlvoAntes = await auditoria.buscarUsuarioAuditoria(usuarioId, empresaId);
    const permissoesAntes = usuarioAlvoAntes?.raw?.permissoes || {};
    const permissoesDepois = { ...permissoesAntes, ...(novasPermissoes || {}) };
    const result = await permissoes.atualizarPermissoes(usuarioId, novasPermissoes, atualizadoPor);

    if (result.success) {
      const alteracoes = auditoria.compararObjetosLegivel(permissoesAntes, permissoesDepois);
      const detalhes = auditoria.criarDetalhePermissoes(alteracoes, usuarioAlvoAntes);
      await auditoria.registrarLog({
        empresaId,
        usuarioId: atualizadoPor,
        usuarioNome: atualizadoPorNome || 'Sistema',
        usuarioEmail: atualizadoPorEmail || '',
        operacao: 'alterar_permissoes',
        documentoId: usuarioAlvoAntes?.chave || usuarioId,
        documentoTipo: 'usuario',
        documentoNumero: usuarioAlvoAntes?.nome || usuarioId,
        entidadeTipo: 'usuario',
        entidadeId: usuarioAlvoAntes?.chave || usuarioId,
        entidadeNome: usuarioAlvoAntes?.nome || usuarioId,
        modulo: 'permissoes',
        moduloNome: 'Usuarios e Permissoes',
        titulo: `Permissoes alteradas - ${usuarioAlvoAntes?.nome || usuarioId}`,
        mensagem: detalhes,
        detalhes,
        detalhesTexto: detalhes,
        alteracoes,
        metadata: {
          usuarioAfetado: {
            id: usuarioAlvoAntes?.id || usuarioId,
            nome: usuarioAlvoAntes?.nome || usuarioId,
            email: usuarioAlvoAntes?.email || '',
            nivel: usuarioAlvoAntes?.nivel || '',
          },
          permissoesAntes,
          permissoesDepois,
          novasPermissoes,
        },
        origem: 'backend',
        tags: ['usuarios', 'permissoes'],
      });
    }

    return c.json(result);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.patch("/usuarios-permissoes/:usuarioId/desativar", async (c) => {
  try {
    const usuarioId = c.req.param("usuarioId");
    const acesso = await validarAcessoUsuarioAlvoRequest(c, usuarioId);
    if (!acesso.permitido) return acesso.resposta;

    const body = await c.req.json();
    const { desativadoPor, desativadoPorNome, desativadoPorEmail, empresaId } = body;

    const usuarioAlvoAntes = await auditoria.buscarUsuarioAuditoria(usuarioId, empresaId);
    const result = await permissoes.desativarUsuario(usuarioId, desativadoPor);

    if (result.success) {
      const alvo = `${usuarioAlvoAntes?.nome || usuarioId}${usuarioAlvoAntes?.email ? ` (${usuarioAlvoAntes.email})` : ''}`;
      const mensagem = `${desativadoPorNome || 'Sistema'} desativou o usuario ${alvo}.`;
      await auditoria.registrarLog({
        empresaId,
        usuarioId: desativadoPor,
        usuarioNome: desativadoPorNome || 'Sistema',
        usuarioEmail: desativadoPorEmail || '',
        operacao: 'desativar_usuario',
        documentoId: usuarioAlvoAntes?.chave || usuarioId,
        documentoTipo: 'usuario',
        documentoNumero: usuarioAlvoAntes?.nome || usuarioId,
        entidadeTipo: 'usuario',
        entidadeId: usuarioAlvoAntes?.chave || usuarioId,
        entidadeNome: usuarioAlvoAntes?.nome || usuarioId,
        modulo: 'permissoes',
        moduloNome: 'Usuarios e Permissoes',
        titulo: `Usuario desativado - ${usuarioAlvoAntes?.nome || usuarioId}`,
        mensagem,
        detalhes: mensagem,
        detalhesTexto: mensagem,
        metadata: {
          usuarioAfetado: {
            id: usuarioAlvoAntes?.id || usuarioId,
            nome: usuarioAlvoAntes?.nome || usuarioId,
            email: usuarioAlvoAntes?.email || '',
            nivel: usuarioAlvoAntes?.nivel || '',
          },
        },
        origem: 'backend',
        nivel: 'aviso',
        tags: ['usuarios', 'permissoes'],
      });
    }

    return c.json(result);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.patch("/usuarios-permissoes/:usuarioId/permissoes-modulos", async (c) => {
  try {
    const usuarioId = c.req.param("usuarioId");
    const acesso = await validarAcessoUsuarioAlvoRequest(c, usuarioId);
    if (!acesso.permitido) return acesso.resposta;

    const body = await c.req.json();
    const { permissoesModulos, atualizadoPor, atualizadoPorNome, atualizadoPorEmail, empresaId } = body;

    const usuarioAlvoAntes = await auditoria.buscarUsuarioAuditoria(usuarioId, empresaId);
    const permissoesAntes = usuarioAlvoAntes?.raw?.permissoesModulos || {};
    const result = await permissoes.atualizarPermissoesModulos(
      usuarioId,
      permissoesModulos,
      atualizadoPor,
      atualizadoPorNome,
      atualizadoPorEmail,
      empresaId
    );

    if (result.success) {
      const alteracoes = auditoria.compararObjetosLegivel(permissoesAntes, permissoesModulos || {}, { limite: 120 });
      const detalhes = auditoria.criarDetalhePermissoes(alteracoes, usuarioAlvoAntes);
      await auditoria.registrarLog({
        empresaId,
        usuarioId: atualizadoPor,
        usuarioNome: atualizadoPorNome || 'Sistema',
        usuarioEmail: atualizadoPorEmail || '',
        operacao: 'alterar_permissoes',
        documentoId: usuarioAlvoAntes?.chave || usuarioId,
        documentoTipo: 'usuario',
        documentoNumero: usuarioAlvoAntes?.nome || usuarioId,
        entidadeTipo: 'usuario',
        entidadeId: usuarioAlvoAntes?.chave || usuarioId,
        entidadeNome: usuarioAlvoAntes?.nome || usuarioId,
        modulo: 'permissoes',
        moduloNome: 'Usuarios e Permissoes',
        titulo: `Permissoes por modulo alteradas - ${usuarioAlvoAntes?.nome || usuarioId}`,
        mensagem: detalhes,
        detalhes,
        detalhesTexto: detalhes,
        alteracoes,
        metadata: {
          usuarioAfetado: {
            id: usuarioAlvoAntes?.id || usuarioId,
            nome: usuarioAlvoAntes?.nome || usuarioId,
            email: usuarioAlvoAntes?.email || '',
            nivel: usuarioAlvoAntes?.nivel || '',
          },
          permissoesModulosAntes: permissoesAntes,
          permissoesModulosDepois: permissoesModulos,
        },
        origem: 'backend',
        tags: ['usuarios', 'permissoes', 'permissoes_modulos'],
      });
    }

    return c.json(result);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

// ========== AUDITORIA E LOGS ==========
// ✅ CORREÇÃO DE SEGURANÇA: estas 4 rotas nao tinham NENHUMA verificacao de
// acesso em index.tsx — qualquer pessoa com a chave publica anon conseguia
// ler o log de auditoria de qualquer empresa. Adicionada validacao aqui.

adminRouter.get("/empresas/:empresaId/auditoria", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;

    const filtros = {
      usuarioId: c.req.query("usuarioId"),
      operacao: c.req.query("operacao") as any,
      documentoTipo: c.req.query("documentoTipo"),
      dataInicio: c.req.query("dataInicio"),
      dataFim: c.req.query("dataFim"),
    };

    const result = await auditoria.buscarLogsPorEmpresa(empresaId, filtros);
    return c.json(result);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.get("/auditoria/documento/:documentoId", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const documentoId = c.req.param("documentoId");
    const result = await auditoria.buscarLogsPorDocumento(documentoId);
    return c.json(result);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.get("/auditoria/usuario/:usuarioId", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const usuarioId = c.req.param("usuarioId");
    const limite = parseInt(c.req.query("limite") || "50");
    const result = await auditoria.buscarAtividadesUsuario(usuarioId, limite);
    return c.json(result);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

adminRouter.get("/empresas/:empresaId/auditoria/estatisticas", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;

    const dataInicio = c.req.query("dataInicio");
    const dataFim = c.req.query("dataFim");

    const periodo = dataInicio && dataFim ? { dataInicio, dataFim } : undefined;
    const result = await auditoria.obterEstatisticasAuditoria(empresaId, periodo);
    return c.json(result);
  } catch (error: any) {
    return c.json({ success: false, error: error.message }, 500);
  }
});

export default adminRouter;
