import { Hono } from "hono";
import * as colaboradores from "./colaboradores.tsx";
import * as presencas from "./presencas.tsx";
import * as ferias from "./ferias.tsx";
import * as ausencias from "./ausencias.tsx";
import * as parametrosFiscaisRH from "./parametros-fiscais-rh.tsx";
import * as folhaPagamento from "./folha-pagamento.tsx";
import * as relatoriosFiscaisRH from "./relatorios-fiscais-rh.tsx";
import * as cessacaoContrato from "./cessacao-contrato.tsx";
import * as dependentes from "./dependentes.tsx";
import * as historicoColaborador from "./historico-colaborador.tsx";
import * as fotoColaborador from "./foto-colaborador.tsx";
import * as documentosColaborador from "./documentos-colaborador.tsx";
import * as rubricasSalariais from "./rubricas-salariais.tsx";
import * as periodoFolhaPagamento from "./periodo-folha-pagamento.tsx";
import * as ficheiroTransferenciaRH from "./ficheiro-transferencia-rh.tsx";
import * as feriadosRH from "./feriados-rh.tsx";
import * as calendariosTrabalho from "./calendarios-trabalho.tsx";
import * as historicoPresenca from "./historico-presenca.tsx";
import * as mapaPresencas from "./mapa-presencas.tsx";
import * as configuracaoPresencas from "./configuracao-presencas.tsx";
import * as autorizacaoHoraExtra from "./autorizacao-hora-extra.tsx";
import * as bancoHoras from "./banco-horas.tsx";
import * as relatoriosPresencas from "./relatorios-presencas.tsx";
import * as guiaPagamentoINSS from "./guia-pagamento-inss.tsx";
import * as comunicacaoINSS from "./comunicacao-inss.tsx";
import * as livroRegistoINSS from "./livro-registo-inss.tsx";
import { simularImpactoIRPS } from "./simulacao-impacto-irps.tsx";
import * as certificadoRetencaoIRPS from "./certificado-retencao-irps.tsx";
import * as comunicacaoDependentesIRPS from "./comunicacao-dependentes-irps.tsx";
import * as livroRegistoIRPS from "./livro-registo-irps.tsx";
import * as dashboardRH from "./dashboard-rh.tsx";
import { obterUsuarioAutenticadoRequest, validarAcessoEmpresaRequest, validarSuperAdminTonlineRequest } from "./admin-shared-helpers.tsx";

// Rotas do modulo de Recursos Humanos, servidas pela funcao dedicada
// rh-server-7249dcd9 (mesmo padrao de admin-server-7249dcd9/admin-router.tsx).
//
// Auth: usa APENAS validarAcessoEmpresaRequest (admin-shared-helpers.tsx),
// o mesmo mecanismo, ja comprovado, do admin-server-7249dcd9. Uma primeira
// versao usava tambem requireAnyPermission (permission-middleware.tsx), que
// tem o seu proprio loadUserFromToken independente (client Supabase por
// service-role + procura por authUserId) — esse caminho devolvia 401 para
// utilizadores validos (confirmado: no mesmo instante, o mesmo token
// funcionava no admin-server-7249dcd9). Para nao ter dois mecanismos de
// autenticacao divergentes a competir, a verificacao granular
// "rh.colaborador.<acao>" passa a ser feita aqui, sobre o `usuario` ja
// carregado por validarAcessoEmpresaRequest.
// Ver plano em C:\Users\admin\.claude\plans\consegues-ter-acesso-ao-greedy-rivest.md

const rhRouter = new Hono();

rhRouter.get("/health", (c) => {
  return c.json({ success: true, status: "ok" });
});

type AcaoRH = "criar" | "editar" | "deletar" | "visualizar";
type EntidadeRH =
  | "colaborador" | "presenca" | "ferias" | "ausencia" | "processamento" | "cessacao" | "dependente"
  | "documento" | "rubrica" | "calendario" | "configuracaoPresencas" | "autorizacaoHoraExtra" | "bancoHoras"
  | "guiaInss" | "comunicacaoInss" | "simulacaoIrps" | "certificadoIrps" | "comunicacaoIrps";

function ehAdminRH(usuario: any): boolean {
  const nivel = String(usuario?.nivel || "").trim().toLowerCase();
  return nivel === "super_admin" || nivel === "admin" || nivel === "admin_empresa";
}

function temPermissaoRH(usuario: any, entidade: EntidadeRH, acao: AcaoRH): boolean {
  if (ehAdminRH(usuario)) return true;
  return usuario?.permissoesModulos?.rh?.[entidade]?.[acao] === true;
}

function respostaSemPermissao(c: any, acao: AcaoRH) {
  return c.json(
    { success: false, error: `Não tem permissão para '${acao}' em Recursos Humanos > Colaboradores` },
    403,
  );
}

// ========== DASHBOARD ==========

rhRouter.get("/empresas/:empresaId/dashboard/estatisticas", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "colaborador", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const estatisticas = await dashboardRH.obterEstatisticasDashboardRH(empresaId);
    return c.json({ success: true, data: estatisticas });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

// ========== COLABORADORES ==========

rhRouter.get("/empresas/:empresaId/colaboradores", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "colaborador", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { ativo, estado } = c.req.query();
    const filtros: { ativo?: boolean; estado?: colaboradores.EstadoColaborador } = {};
    if (ativo !== undefined) filtros.ativo = ativo === "true";
    if (estado !== undefined) filtros.estado = estado as colaboradores.EstadoColaborador;

    const lista = await colaboradores.listarColaboradores(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.get("/colaboradores/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const colaborador = await colaboradores.buscarColaboradorPorId(id);
    if (!colaborador) {
      return c.json({ success: false, error: "Colaborador não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, colaborador.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "colaborador", "visualizar")) return respostaSemPermissao(c, "visualizar");

    return c.json({ success: true, data: colaborador });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/colaboradores", async (c) => {
  try {
    const dados = await c.req.json();
    const acesso = await validarAcessoEmpresaRequest(c, dados.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "colaborador", "criar")) return respostaSemPermissao(c, "criar");

    const resultado = await colaboradores.criarColaborador(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);
  }
});

rhRouter.put("/colaboradores/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await colaboradores.buscarColaboradorPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Colaborador não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "colaborador", "editar")) return respostaSemPermissao(c, "editar");

    const dados = await c.req.json();
    const alteradoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await colaboradores.atualizarColaborador(id, dados, alteradoPor);
    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);
  }
});

rhRouter.get("/colaboradores/:id/historico-alteracoes", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await colaboradores.buscarColaboradorPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Colaborador não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "colaborador", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const lista = await historicoColaborador.listarAlteracoesColaborador(existente.empresaId, id);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/colaboradores/:id/foto", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await colaboradores.buscarColaboradorPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Colaborador não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "colaborador", "editar")) return respostaSemPermissao(c, "editar");

    const formData = await c.req.formData();
    const file = formData.get("file") as File;
    if (!file) {
      return c.json({ success: false, error: "Ficheiro não fornecido" }, 400);
    }

    const resultado = await fotoColaborador.uploadFotoColaborador(existente.empresaId, id, file);
    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);
  }
});

rhRouter.delete("/colaboradores/:id/foto", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await colaboradores.buscarColaboradorPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Colaborador não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "colaborador", "editar")) return respostaSemPermissao(c, "editar");

    const resultado = await fotoColaborador.removerFotoColaborador(existente.empresaId, 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);
  }
});

rhRouter.post("/colaboradores/:id/cessar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await colaboradores.buscarColaboradorPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Colaborador não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "colaborador", "editar")) return respostaSemPermissao(c, "editar");

    const { dataCessacao } = await c.req.json();
    const resultado = await colaboradores.cessarColaborador(id, dataCessacao);
    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);
  }
});

rhRouter.patch("/colaboradores/:id/toggle", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await colaboradores.buscarColaboradorPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Colaborador não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "colaborador", "editar")) return respostaSemPermissao(c, "editar");

    const { ativo } = await c.req.json();
    const resultado = await colaboradores.toggleColaborador(id, Boolean(ativo));
    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);
  }
});

rhRouter.delete("/colaboradores/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await colaboradores.buscarColaboradorPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Colaborador não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "colaborador", "deletar")) return respostaSemPermissao(c, "deletar");

    const resultado = await colaboradores.deletarColaborador(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);
  }
});

// ========== PRESENCAS ==========

rhRouter.get("/empresas/:empresaId/presencas", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "presenca", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { colaboradorId, dataInicio, dataFim, tipo } = c.req.query();
    const filtros: Parameters<typeof presencas.listarPresencas>[1] = {};
    if (colaboradorId) filtros.colaboradorId = colaboradorId;
    if (dataInicio) filtros.dataInicio = dataInicio;
    if (dataFim) filtros.dataFim = dataFim;
    if (tipo) filtros.tipo = tipo as presencas.TipoPresenca;

    const lista = await presencas.listarPresencas(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/presencas", async (c) => {
  try {
    const dados = await c.req.json();
    const acesso = await validarAcessoEmpresaRequest(c, dados.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "presenca", "criar")) return respostaSemPermissao(c, "criar");

    const resultado = await presencas.criarPresenca(dados, ehAdminRH(acesso.usuario));
    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);
  }
});

rhRouter.put("/presencas/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await presencas.buscarPresencaPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Registo de presença não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "presenca", "editar")) return respostaSemPermissao(c, "editar");

    const { motivo, ...dados } = await c.req.json();
    const alteradoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await presencas.atualizarPresenca(id, dados, motivo, alteradoPor, ehAdminRH(acesso.usuario));
    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);
  }
});

rhRouter.delete("/presencas/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await presencas.buscarPresencaPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Registo de presença não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "presenca", "deletar")) return respostaSemPermissao(c, "deletar");

    const motivo = c.req.query("motivo") || "";
    const alteradoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await presencas.deletarPresenca(id, motivo, alteradoPor, ehAdminRH(acesso.usuario));
    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);
  }
});

rhRouter.get("/colaboradores/:id/historico-presencas", async (c) => {
  try {
    const colaboradorId = c.req.param("id");
    const colaborador = await colaboradores.buscarColaboradorPorId(colaboradorId);
    if (!colaborador) {
      return c.json({ success: false, error: "Colaborador não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, colaborador.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "presenca", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const lista = await historicoPresenca.listarAlteracoesPresenca(colaborador.empresaId, colaboradorId);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.get("/empresas/:empresaId/relatorios/mapa-presencas/:ano/:mes", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "presenca", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const ano = Number(c.req.param("ano"));
    const mes = Number(c.req.param("mes"));
    if (!Number.isInteger(ano) || !Number.isInteger(mes) || mes < 1 || mes > 12) {
      return c.json({ success: false, error: "Ano ou mês inválido" }, 400);
    }

    const mapa = await mapaPresencas.gerarMapaPresencasMensal(empresaId, ano, mes);
    return c.json({ success: true, data: mapa });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

// ========== PEDIDOS DE FERIAS ==========

rhRouter.get("/empresas/:empresaId/pedidos-ferias", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ferias", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { colaboradorId, estado, dataInicio, dataFim } = c.req.query();
    const filtros: Parameters<typeof ferias.listarPedidosFerias>[1] = {};
    if (colaboradorId) filtros.colaboradorId = colaboradorId;
    if (estado) filtros.estado = estado as ferias.EstadoPedidoFerias;
    if (dataInicio) filtros.dataInicio = dataInicio;
    if (dataFim) filtros.dataFim = dataFim;

    const lista = await ferias.listarPedidosFerias(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/pedidos-ferias", async (c) => {
  try {
    const dados = await c.req.json();
    const acesso = await validarAcessoEmpresaRequest(c, dados.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ferias", "criar")) return respostaSemPermissao(c, "criar");

    const resultado = await ferias.criarPedidoFerias(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);
  }
});

rhRouter.put("/pedidos-ferias/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await ferias.buscarPedidoFeriasPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Pedido de férias não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ferias", "editar")) return respostaSemPermissao(c, "editar");

    const dados = await c.req.json();
    const resultado = await ferias.atualizarPedidoFerias(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);
  }
});

rhRouter.post("/pedidos-ferias/:id/aprovar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await ferias.buscarPedidoFeriasPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Pedido de férias não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ferias", "editar")) return respostaSemPermissao(c, "editar");

    const aprovadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await ferias.aprovarPedidoFerias(id, aprovadoPor);
    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);
  }
});

rhRouter.post("/pedidos-ferias/:id/rejeitar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await ferias.buscarPedidoFeriasPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Pedido de férias não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ferias", "editar")) return respostaSemPermissao(c, "editar");

    const { motivoRejeicao } = await c.req.json();
    const aprovadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await ferias.rejeitarPedidoFerias(id, aprovadoPor, motivoRejeicao);
    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);
  }
});

rhRouter.post("/pedidos-ferias/:id/cancelar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await ferias.buscarPedidoFeriasPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Pedido de férias não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ferias", "editar")) return respostaSemPermissao(c, "editar");

    const resultado = await ferias.cancelarPedidoFerias(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);
  }
});

rhRouter.delete("/pedidos-ferias/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await ferias.buscarPedidoFeriasPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Pedido de férias não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ferias", "deletar")) return respostaSemPermissao(c, "deletar");

    const resultado = await ferias.deletarPedidoFerias(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);
  }
});

// ========== AUSENCIAS (licencas de varios dias) ==========

rhRouter.get("/empresas/:empresaId/ausencias", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ausencia", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { colaboradorId, estado, tipo, dataInicio, dataFim } = c.req.query();
    const filtros: Parameters<typeof ausencias.listarAusencias>[1] = {};
    if (colaboradorId) filtros.colaboradorId = colaboradorId;
    if (estado) filtros.estado = estado as ausencias.EstadoAusencia;
    if (tipo) filtros.tipo = tipo as ausencias.TipoAusencia;
    if (dataInicio) filtros.dataInicio = dataInicio;
    if (dataFim) filtros.dataFim = dataFim;

    const lista = await ausencias.listarAusencias(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/ausencias", async (c) => {
  try {
    const dados = await c.req.json();
    const acesso = await validarAcessoEmpresaRequest(c, dados.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ausencia", "criar")) return respostaSemPermissao(c, "criar");

    const resultado = await ausencias.criarAusencia(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);
  }
});

rhRouter.put("/ausencias/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await ausencias.buscarAusenciaPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Ausência não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ausencia", "editar")) return respostaSemPermissao(c, "editar");

    const dados = await c.req.json();
    const resultado = await ausencias.atualizarAusencia(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);
  }
});

rhRouter.post("/ausencias/:id/aprovar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await ausencias.buscarAusenciaPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Ausência não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ausencia", "editar")) return respostaSemPermissao(c, "editar");

    const aprovadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await ausencias.aprovarAusencia(id, aprovadoPor);
    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);
  }
});

rhRouter.post("/ausencias/:id/rejeitar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await ausencias.buscarAusenciaPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Ausência não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ausencia", "editar")) return respostaSemPermissao(c, "editar");

    const { motivoRejeicao } = await c.req.json();
    const aprovadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await ausencias.rejeitarAusencia(id, aprovadoPor, motivoRejeicao);
    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);
  }
});

rhRouter.post("/ausencias/:id/cancelar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await ausencias.buscarAusenciaPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Ausência não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ausencia", "editar")) return respostaSemPermissao(c, "editar");

    const resultado = await ausencias.cancelarAusencia(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);
  }
});

rhRouter.delete("/ausencias/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await ausencias.buscarAusenciaPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Ausência não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "ausencia", "deletar")) return respostaSemPermissao(c, "deletar");

    const resultado = await ausencias.deletarAusencia(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);
  }
});

// ========== PARAMETROS FISCAIS DE RH (Fase 2 — scaffolding) ==========
//
// Dados GLOBAIS (nao por empresa): INSS, IRPS e as regras da Lei do
// Trabalho sao identicas para todas as empresas moçambicanas, por isso nao
// usam validarAcessoEmpresaRequest (que exige um empresaId). Leitura:
// qualquer utilizador autenticado (vai ser consumido pelo motor de calculo
// salarial na Fase 3). Escrita: reservada a super-admin da TONLINE, porque
// alterar isto afecta o calculo de TODAS as empresas do sistema, nao so a
// de quem estiver a editar.

rhRouter.get("/parametros-fiscais/:ano", async (c) => {
  try {
    const usuario = await obterUsuarioAutenticadoRequest(c);
    if (!usuario) {
      return c.json({ success: false, error: "Sessao invalida ou expirada" }, 401);
    }

    const ano = Number(c.req.param("ano"));
    if (!Number.isInteger(ano)) {
      return c.json({ success: false, error: "Ano inválido" }, 400);
    }

    const parametros = await parametrosFiscaisRH.obterParametrosFiscaisRH(ano);
    return c.json({ success: true, data: parametros });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.get("/parametros-fiscais", async (c) => {
  try {
    const usuario = await obterUsuarioAutenticadoRequest(c);
    if (!usuario) {
      return c.json({ success: false, error: "Sessao invalida ou expirada" }, 401);
    }

    const anos = await parametrosFiscaisRH.listarAnosConfigurados();
    return c.json({ success: true, data: anos });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.put("/parametros-fiscais/:ano", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const ano = Number(c.req.param("ano"));
    if (!Number.isInteger(ano)) {
      return c.json({ success: false, error: "Ano inválido" }, 400);
    }

    const { confirmadoPor, ...dados } = await c.req.json();
    const resultado = await parametrosFiscaisRH.atualizarParametrosFiscaisRH(ano, dados, confirmadoPor);
    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);
  }
});

// ========== RUBRICAS SALARIAIS ==========

rhRouter.get("/empresas/:empresaId/rubricas-salariais", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "rubrica", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { ativa } = c.req.query();
    const filtros: Parameters<typeof rubricasSalariais.listarRubricasSalariais>[1] = {};
    if (ativa !== undefined) filtros.ativa = ativa === "true";

    const lista = await rubricasSalariais.listarRubricasSalariais(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/rubricas-salariais", async (c) => {
  try {
    const dados = await c.req.json();
    const acesso = await validarAcessoEmpresaRequest(c, dados.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "rubrica", "criar")) return respostaSemPermissao(c, "criar");

    const resultado = await rubricasSalariais.criarRubricaSalarial(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);
  }
});

rhRouter.put("/rubricas-salariais/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await rubricasSalariais.buscarRubricaSalarialPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Rubrica não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "rubrica", "editar")) return respostaSemPermissao(c, "editar");

    const dados = await c.req.json();
    const resultado = await rubricasSalariais.atualizarRubricaSalarial(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);
  }
});

rhRouter.delete("/rubricas-salariais/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await rubricasSalariais.buscarRubricaSalarialPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Rubrica não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "rubrica", "deletar")) return respostaSemPermissao(c, "deletar");

    const resultado = await rubricasSalariais.deletarRubricaSalarial(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);
  }
});

// ========== PROCESSAMENTO SALARIAL (Fase 3) ==========

rhRouter.get("/empresas/:empresaId/folhas-pagamento", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { colaboradorId, ano, mes } = c.req.query();
    const filtros: Parameters<typeof folhaPagamento.listarFolhasPagamento>[1] = {};
    if (colaboradorId) filtros.colaboradorId = colaboradorId;
    if (ano) filtros.ano = Number(ano);
    if (mes) filtros.mes = Number(mes);

    const lista = await folhaPagamento.listarFolhasPagamento(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/folhas-pagamento/processar", async (c) => {
  try {
    const { empresaId, colaboradorId, ano, mes, rubricasManuais } = await c.req.json();
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "criar")) return respostaSemPermissao(c, "criar");

    const processadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await folhaPagamento.processarFolhaPagamento(empresaId, colaboradorId, Number(ano), Number(mes), processadoPor, rubricasManuais || []);
    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);
  }
});

rhRouter.post("/folhas-pagamento/processar-lote", async (c) => {
  try {
    const { empresaId, ano, mes } = await c.req.json();
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "criar")) return respostaSemPermissao(c, "criar");

    const processadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await folhaPagamento.processarFolhaPagamentoEmLote(empresaId, Number(ano), Number(mes), processadoPor);
    return c.json({ success: true, data: resultado });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.delete("/folhas-pagamento/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await folhaPagamento.buscarFolhaPagamentoPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Folha de pagamento não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "deletar")) return respostaSemPermissao(c, "deletar");

    const resultado = await folhaPagamento.deletarFolhaPagamento(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);
  }
});

// ========== PERIODO DE FOLHA DE PAGAMENTO (workflow aberto/aprovado/fechado) ==========

rhRouter.get("/empresas/:empresaId/periodo-folha-pagamento/:ano/:mes", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const ano = Number(c.req.param("ano"));
    const mes = Number(c.req.param("mes"));
    const periodo = await periodoFolhaPagamento.obterPeriodoFolhaPagamento(empresaId, ano, mes);
    return c.json({ success: true, data: periodo });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/empresas/:empresaId/periodo-folha-pagamento/:ano/:mes/aprovar", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "criar")) return respostaSemPermissao(c, "criar");

    const ano = Number(c.req.param("ano"));
    const mes = Number(c.req.param("mes"));
    const folhas = await folhaPagamento.listarFolhasPagamento(empresaId, { ano, mes });
    const aprovadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";

    const resultado = await periodoFolhaPagamento.aprovarPeriodoFolhaPagamento(empresaId, ano, mes, folhas.length, aprovadoPor);
    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);
  }
});

rhRouter.post("/empresas/:empresaId/periodo-folha-pagamento/:ano/:mes/fechar", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "criar")) return respostaSemPermissao(c, "criar");

    const ano = Number(c.req.param("ano"));
    const mes = Number(c.req.param("mes"));
    const fechadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";

    const resultado = await periodoFolhaPagamento.fecharPeriodoFolhaPagamento(empresaId, ano, mes, fechadoPor);
    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);
  }
});

rhRouter.post("/empresas/:empresaId/periodo-folha-pagamento/:ano/:mes/reabrir", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "deletar")) return respostaSemPermissao(c, "deletar");

    const ano = Number(c.req.param("ano"));
    const mes = Number(c.req.param("mes"));
    const { motivo } = await c.req.json();
    const reabertoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";

    const resultado = await periodoFolhaPagamento.reabrirPeriodoFolhaPagamento(empresaId, ano, mes, reabertoPor, motivo);
    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);
  }
});

// ========== RELATORIOS FISCAIS (Modelo 19 IRPS + Declaracao SISSMO INSS) ==========

rhRouter.get("/empresas/:empresaId/relatorios/modelo19", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const ano = Number(c.req.query("ano"));
    const mes = Number(c.req.query("mes"));
    if (!Number.isInteger(ano) || !Number.isInteger(mes) || mes < 1 || mes > 12) {
      return c.json({ success: false, error: "Ano ou mês inválido" }, 400);
    }

    const resumo = await relatoriosFiscaisRH.gerarResumoModelo19(empresaId, ano, mes);
    return c.json({ success: true, data: resumo });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/empresas/:empresaId/relatorios/sissmo", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { ano, mes, numeroInscricaoEmpresa } = await c.req.json();
    if (!Number.isInteger(Number(ano)) || !Number.isInteger(Number(mes)) || Number(mes) < 1 || Number(mes) > 12) {
      return c.json({ success: false, error: "Ano ou mês inválido" }, 400);
    }

    const resultado = await relatoriosFiscaisRH.gerarDeclaracaoSissmoINSS(empresaId, Number(ano), Number(mes), numeroInscricaoEmpresa);
    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    const nomeFicheiro = relatoriosFiscaisRH.nomeFicheiroSissmo(numeroInscricaoEmpresa, Number(ano), Number(mes));
    return c.json({ success: true, data: { ...resultado.data, nomeFicheiro } });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

// ========== DEPENDENTES ==========

rhRouter.get("/empresas/:empresaId/dependentes", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "dependente", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { colaboradorId, ativo } = c.req.query();
    const filtros: Parameters<typeof dependentes.listarDependentes>[1] = {};
    if (colaboradorId) filtros.colaboradorId = colaboradorId;
    if (ativo !== undefined) filtros.ativo = ativo === "true";

    const lista = await dependentes.listarDependentes(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/dependentes", async (c) => {
  try {
    const dados = await c.req.json();
    const acesso = await validarAcessoEmpresaRequest(c, dados.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "dependente", "criar")) return respostaSemPermissao(c, "criar");

    const resultado = await dependentes.criarDependente(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);
  }
});

rhRouter.put("/dependentes/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await dependentes.buscarDependentePorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Dependente não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "dependente", "editar")) return respostaSemPermissao(c, "editar");

    const dados = await c.req.json();
    const resultado = await dependentes.atualizarDependente(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);
  }
});

rhRouter.delete("/dependentes/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await dependentes.buscarDependentePorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Dependente não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "dependente", "deletar")) return respostaSemPermissao(c, "deletar");

    const resultado = await dependentes.deletarDependente(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);
  }
});

// ========== DOCUMENTOS DE COLABORADOR (anexos) ==========
//
// Bucket privado (make-7249dcd9-rh-documentos) — acesso so via signed URL
// (rota /documentos/:id/signed-url), nunca URL publica directa, porque
// podem conter dados pessoais sensiveis (BI, atestados medicos, etc.).

rhRouter.get("/empresas/:empresaId/documentos-colaborador", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "documento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const colaboradorId = c.req.query("colaboradorId");
    if (!colaboradorId) {
      return c.json({ success: false, error: "colaboradorId é obrigatório" }, 400);
    }

    const lista = await documentosColaborador.listarDocumentosColaborador(empresaId, colaboradorId);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/colaboradores/:id/documentos", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await colaboradores.buscarColaboradorPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Colaborador não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "documento", "criar")) return respostaSemPermissao(c, "criar");

    const formData = await c.req.formData();
    const file = formData.get("file") as File;
    const tipo = formData.get("tipo") as documentosColaborador.TipoDocumentoColaborador;
    const dataValidade = (formData.get("dataValidade") as string) || undefined;
    const observacoes = (formData.get("observacoes") as string) || undefined;

    if (!file) {
      return c.json({ success: false, error: "Ficheiro não fornecido" }, 400);
    }

    const uploadedPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await documentosColaborador.uploadDocumentoColaborador({
      empresaId: existente.empresaId,
      colaboradorId: id,
      tipo,
      file,
      dataValidade,
      observacoes,
      uploadedPor,
    });

    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);
  }
});

rhRouter.put("/documentos-colaborador/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await documentosColaborador.buscarDocumentoColaboradorPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Documento não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "documento", "editar")) return respostaSemPermissao(c, "editar");

    const dados = await c.req.json();
    const resultado = await documentosColaborador.atualizarDocumentoColaborador(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);
  }
});

rhRouter.get("/documentos-colaborador/:id/signed-url", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await documentosColaborador.buscarDocumentoColaboradorPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Documento não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "documento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const expiresIn = Number(c.req.query("expiresIn")) || 600;
    const resultado = await documentosColaborador.gerarSignedUrlDocumentoColaborador(id, expiresIn);
    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);
  }
});

rhRouter.delete("/documentos-colaborador/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await documentosColaborador.buscarDocumentoColaboradorPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Documento não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "documento", "deletar")) return respostaSemPermissao(c, "deletar");

    const resultado = await documentosColaborador.deletarDocumentoColaborador(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);
  }
});

rhRouter.post("/empresas/:empresaId/relatorios/ficheiro-transferencia", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { ano, mes, dataPagamento } = await c.req.json();
    if (!Number.isInteger(Number(ano)) || !Number.isInteger(Number(mes)) || Number(mes) < 1 || Number(mes) > 12) {
      return c.json({ success: false, error: "Ano ou mês inválido" }, 400);
    }

    const resultado = await ficheiroTransferenciaRH.gerarFicheiroTransferenciaSalarios(empresaId, Number(ano), Number(mes), dataPagamento);
    if (!resultado.success) {
      return c.json(resultado, 400);
    }

    const nomeFicheiro = ficheiroTransferenciaRH.nomeFicheiroTransferencia(Number(ano), Number(mes));
    return c.json({ success: true, data: { ...resultado.data, nomeFicheiro } });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

// ========== CESSACAO DE CONTRATO ==========

rhRouter.get("/empresas/:empresaId/cessacoes", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "cessacao", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { colaboradorId, estado } = c.req.query();
    const filtros: Parameters<typeof cessacaoContrato.listarCessacoes>[1] = {};
    if (colaboradorId) filtros.colaboradorId = colaboradorId;
    if (estado) filtros.estado = estado as cessacaoContrato.EstadoCessacao;

    const lista = await cessacaoContrato.listarCessacoes(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/cessacoes", async (c) => {
  try {
    const dados = await c.req.json();
    const acesso = await validarAcessoEmpresaRequest(c, dados.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "cessacao", "criar")) return respostaSemPermissao(c, "criar");

    const processadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await cessacaoContrato.criarCessacaoContrato(dados, processadoPor);
    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);
  }
});

rhRouter.post("/cessacoes/:id/confirmar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await cessacaoContrato.buscarCessacaoPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Cessação de contrato não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "cessacao", "editar")) return respostaSemPermissao(c, "editar");

    const resultado = await cessacaoContrato.confirmarCessacaoContrato(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);
  }
});

rhRouter.delete("/cessacoes/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await cessacaoContrato.buscarCessacaoPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Cessação de contrato não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "cessacao", "deletar")) return respostaSemPermissao(c, "deletar");

    const resultado = await cessacaoContrato.deletarCessacaoContrato(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);
  }
});

// ========== FERIADOS (Presenças, Grupo A) ==========
//
// Dados GLOBAIS (nao por empresa), tal como parametros-fiscais-rh.tsx: os
// feriados nacionais (Art. 105 n.2) e a tolerancia de ponto (Art. 106) sao
// decretados pelo Ministro do Trabalho e aplicam-se a todas as empresas
// moçambicanas. Leitura: qualquer utilizador autenticado. Escrita
// (feriados locais/tolerancias) reservada a super-admin da TONLINE, porque
// afecta o calendario de TODAS as empresas, nao so a de quem estiver a criar.

rhRouter.get("/feriados/:ano", async (c) => {
  try {
    const usuario = await obterUsuarioAutenticadoRequest(c);
    if (!usuario) {
      return c.json({ success: false, error: "Sessao invalida ou expirada" }, 401);
    }

    const ano = Number(c.req.param("ano"));
    if (!Number.isInteger(ano)) {
      return c.json({ success: false, error: "Ano inválido" }, 400);
    }

    const { provincia } = c.req.query();
    const lista = await feriadosRH.listarFeriados(ano, { provincia });
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/feriados", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const dados = await c.req.json();
    const resultado = await feriadosRH.criarFeriadoLocal(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);
  }
});

rhRouter.delete("/feriados/:id", async (c) => {
  try {
    const acesso = await validarSuperAdminTonlineRequest(c);
    if (!acesso.permitido) return acesso.resposta;

    const id = c.req.param("id");
    const resultado = await feriadosRH.deletarFeriado(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);
  }
});

// ========== CALENDARIOS DE TRABALHO (Presenças, Grupo A) ==========

rhRouter.get("/empresas/:empresaId/calendarios-trabalho", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "calendario", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { ativo } = c.req.query();
    const filtros: Parameters<typeof calendariosTrabalho.listarCalendariosTrabalho>[1] = {};
    if (ativo !== undefined) filtros.ativo = ativo === "true";

    const lista = await calendariosTrabalho.listarCalendariosTrabalho(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/calendarios-trabalho", async (c) => {
  try {
    const dados = await c.req.json();
    const acesso = await validarAcessoEmpresaRequest(c, dados.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "calendario", "criar")) return respostaSemPermissao(c, "criar");

    const resultado = await calendariosTrabalho.criarCalendarioTrabalho(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);
  }
});

rhRouter.put("/calendarios-trabalho/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await calendariosTrabalho.buscarCalendarioTrabalhoPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Calendário não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "calendario", "editar")) return respostaSemPermissao(c, "editar");

    const dados = await c.req.json();
    const resultado = await calendariosTrabalho.atualizarCalendarioTrabalho(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);
  }
});

rhRouter.delete("/calendarios-trabalho/:id", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await calendariosTrabalho.buscarCalendarioTrabalhoPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Calendário não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "calendario", "deletar")) return respostaSemPermissao(c, "deletar");

    const resultado = await calendariosTrabalho.deletarCalendarioTrabalho(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);
  }
});

// ========== CONFIGURACAO DE PRESENCAS ==========
//
// Tolerancias/arredondamento/limites internos/fecho de presencas — afecta o
// calculo para TODA a empresa, por isso a escrita segue o mesmo padrao de
// rubrica/calendario (permissao com requiredLevel:'admin' no
// permission-matrix.ts).

rhRouter.get("/empresas/:empresaId/configuracao-presencas", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "configuracaoPresencas", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const configuracao = await configuracaoPresencas.obterConfiguracaoPresencas(empresaId);
    return c.json({ success: true, data: configuracao });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.put("/empresas/:empresaId/configuracao-presencas", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "configuracaoPresencas", "editar")) return respostaSemPermissao(c, "editar");

    const dados = await c.req.json();
    const resultado = await configuracaoPresencas.atualizarConfiguracaoPresencas(empresaId, 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);
  }
});

// ========== AUTORIZACAO DE HORA EXTRA ==========

rhRouter.get("/empresas/:empresaId/autorizacoes-hora-extra", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "autorizacaoHoraExtra", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { colaboradorId, estado, dataInicio, dataFim } = c.req.query();
    const filtros: Parameters<typeof autorizacaoHoraExtra.listarAutorizacoesHoraExtra>[1] = {};
    if (colaboradorId) filtros.colaboradorId = colaboradorId;
    if (estado) filtros.estado = estado as autorizacaoHoraExtra.EstadoAutorizacaoHoraExtra;
    if (dataInicio) filtros.dataInicio = dataInicio;
    if (dataFim) filtros.dataFim = dataFim;

    const lista = await autorizacaoHoraExtra.listarAutorizacoesHoraExtra(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/autorizacoes-hora-extra", async (c) => {
  try {
    const dados = await c.req.json();
    const acesso = await validarAcessoEmpresaRequest(c, dados.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "autorizacaoHoraExtra", "criar")) return respostaSemPermissao(c, "criar");

    const solicitadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await autorizacaoHoraExtra.criarAutorizacaoHoraExtra(dados, solicitadoPor);
    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);
  }
});

rhRouter.post("/autorizacoes-hora-extra/:id/aprovar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await autorizacaoHoraExtra.buscarAutorizacaoHoraExtraPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Autorização não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "autorizacaoHoraExtra", "editar")) return respostaSemPermissao(c, "editar");

    const aprovadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await autorizacaoHoraExtra.aprovarAutorizacaoHoraExtra(id, aprovadoPor);
    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);
  }
});

rhRouter.post("/autorizacoes-hora-extra/:id/rejeitar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await autorizacaoHoraExtra.buscarAutorizacaoHoraExtraPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Autorização não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "autorizacaoHoraExtra", "editar")) return respostaSemPermissao(c, "editar");

    const { motivoRejeicao } = await c.req.json();
    const rejeitadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await autorizacaoHoraExtra.rejeitarAutorizacaoHoraExtra(id, motivoRejeicao, rejeitadoPor);
    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);
  }
});

rhRouter.post("/autorizacoes-hora-extra/:id/cancelar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await autorizacaoHoraExtra.buscarAutorizacaoHoraExtraPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Autorização não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "autorizacaoHoraExtra", "editar")) return respostaSemPermissao(c, "editar");

    const resultado = await autorizacaoHoraExtra.cancelarAutorizacaoHoraExtra(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);
  }
});

// ========== BANCO DE HORAS ==========

rhRouter.get("/empresas/:empresaId/banco-horas/:colaboradorId", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const colaboradorId = c.req.param("colaboradorId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "bancoHoras", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { dataInicio, dataFim } = c.req.query();
    const [movimentos, saldoMinutos] = await Promise.all([
      bancoHoras.listarMovimentosBancoHoras(empresaId, { colaboradorId, dataInicio, dataFim }),
      bancoHoras.calcularSaldoBancoHoras(empresaId, colaboradorId),
    ]);

    return c.json({ success: true, data: { movimentos, saldoMinutos } });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/banco-horas/gozo", async (c) => {
  try {
    const dados = await c.req.json();
    const acesso = await validarAcessoEmpresaRequest(c, dados.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "bancoHoras", "criar")) return respostaSemPermissao(c, "criar");

    const registadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await bancoHoras.registarGozoBancoHoras(
      dados.empresaId, dados.colaboradorId, dados.data, dados.minutos, registadoPor, dados.observacoes,
    );
    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);
  }
});

// ========== RELATORIOS DE CONFORMIDADE (Presencas) ==========

rhRouter.get("/empresas/:empresaId/relatorios/livro-trabalho-excepcional", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "presenca", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { dataInicio, dataFim } = c.req.query();
    if (!dataInicio || !dataFim) {
      return c.json({ success: false, error: "Indique a data de início e de fim do período" }, 400);
    }

    const livro = await relatoriosPresencas.gerarLivroTrabalhoExcepcional(empresaId, dataInicio, dataFim);
    return c.json({ success: true, data: livro });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.get("/empresas/:empresaId/relatorios/assiduidade/:ano/:mes", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "presenca", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const ano = Number(c.req.param("ano"));
    const mes = Number(c.req.param("mes"));
    if (!Number.isInteger(ano) || !Number.isInteger(mes) || mes < 1 || mes > 12) {
      return c.json({ success: false, error: "Ano ou mês inválido" }, 400);
    }

    const relatorio = await relatoriosPresencas.gerarRelatorioAssiduidade(empresaId, ano, mes);
    return c.json({ success: true, data: relatorio });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

// ========== GUIA DE PAGAMENTO INSS ==========

rhRouter.get("/empresas/:empresaId/guias-pagamento-inss", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "guiaInss", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { ano, mes, estado } = c.req.query();
    const filtros: Parameters<typeof guiaPagamentoINSS.listarGuiasPagamentoINSS>[1] = {};
    if (ano) filtros.ano = Number(ano);
    if (mes) filtros.mes = Number(mes);
    if (estado) filtros.estado = estado as guiaPagamentoINSS.EstadoGuiaPagamentoINSS;

    const lista = await guiaPagamentoINSS.listarGuiasPagamentoINSS(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/empresas/:empresaId/guias-pagamento-inss/gerar", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "guiaInss", "criar")) return respostaSemPermissao(c, "criar");

    const { ano, mes } = await c.req.json();
    const geradoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await guiaPagamentoINSS.gerarGuiaPagamentoINSS(empresaId, Number(ano), Number(mes), geradoPor);
    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);
  }
});

rhRouter.post("/guias-pagamento-inss/:id/pagamento", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await guiaPagamentoINSS.buscarGuiaPagamentoINSSPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Guia não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "guiaInss", "editar")) return respostaSemPermissao(c, "editar");

    const { dataPagamento, entidadeBancaria, comprovativoInfo } = await c.req.json();
    const registadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await guiaPagamentoINSS.registarPagamentoGuiaINSS(id, dataPagamento, entidadeBancaria, comprovativoInfo, registadoPor);
    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);
  }
});

rhRouter.post("/guias-pagamento-inss/:id/corrigir", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await guiaPagamentoINSS.buscarGuiaPagamentoINSSPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Guia não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "guiaInss", "editar")) return respostaSemPermissao(c, "editar");

    const { motivo } = await c.req.json();
    const geradoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await guiaPagamentoINSS.corrigirGuiaPagamentoINSS(id, motivo, geradoPor);
    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);
  }
});

// ========== COMUNICACOES INSS (admissao/alteracao salarial/cessacao) ==========

rhRouter.get("/empresas/:empresaId/comunicacoes-inss", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "comunicacaoInss", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { colaboradorId, tipo, estado } = c.req.query();
    const filtros: Parameters<typeof comunicacaoINSS.listarComunicacoesINSS>[1] = {};
    if (colaboradorId) filtros.colaboradorId = colaboradorId;
    if (tipo) filtros.tipo = tipo as comunicacaoINSS.TipoComunicacaoINSS;
    if (estado) filtros.estado = estado as comunicacaoINSS.EstadoComunicacaoINSS;

    const lista = await comunicacaoINSS.listarComunicacoesINSS(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/comunicacoes-inss/:id/enviar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await comunicacaoINSS.buscarComunicacaoINSSPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Comunicação não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "comunicacaoInss", "editar")) return respostaSemPermissao(c, "editar");

    const { numeroProtocolo, observacoes } = await c.req.json();
    const comunicadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await comunicacaoINSS.marcarComunicacaoINSSEnviada(id, comunicadoPor, numeroProtocolo, observacoes);
    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);
  }
});

// ========== HISTORICO DE CONTRIBUICOES + REPROCESSAMENTO EM LOTE ==========

rhRouter.get("/colaboradores/:id/historico-contribuicoes-inss", async (c) => {
  try {
    const id = c.req.param("id");
    const colaborador = await colaboradores.buscarColaboradorPorId(id);
    if (!colaborador) {
      return c.json({ success: false, error: "Colaborador não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, colaborador.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const resultado = await relatoriosFiscaisRH.gerarHistoricoContribuicoesINSS(colaborador.empresaId, 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);
  }
});

rhRouter.post("/empresas/:empresaId/folhas-pagamento/reprocessar-lote", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "editar")) return respostaSemPermissao(c, "editar");

    const { ano, mes } = await c.req.json();
    const processadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await folhaPagamento.reprocessarFolhasPagamentoEmLote(empresaId, Number(ano), Number(mes), processadoPor);
    return c.json({ success: true, data: resultado });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

// ========== RELATORIOS E ANALISES INSS ==========

rhRouter.get("/empresas/:empresaId/relatorios/mapa-encargos-sociais/:ano/:mes", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const ano = Number(c.req.param("ano"));
    const mes = Number(c.req.param("mes"));
    const resultado = await relatoriosFiscaisRH.gerarMapaEncargosSociais(empresaId, ano, mes);
    return c.json({ success: true, data: resultado });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.get("/empresas/:empresaId/relatorios/evolucao-contribuicoes-inss", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { ano, mes, meses } = c.req.query();
    const resultado = await relatoriosFiscaisRH.gerarEvolucaoContribuicoesINSS(
      empresaId, Number(ano), Number(mes), meses ? Number(meses) : 12,
    );
    return c.json({ success: true, data: resultado });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.get("/empresas/:empresaId/relatorios/previsao-contribuicoes-inss", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { ano, mes, meses } = c.req.query();
    const resultado = await relatoriosFiscaisRH.gerarPrevisaoContribuicoesINSS(
      empresaId, Number(ano), Number(mes), meses ? Number(meses) : 6,
    );
    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);
  }
});

rhRouter.get("/empresas/:empresaId/relatorios/livro-registo-inss", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { dataInicio, dataFim } = c.req.query();
    if (!dataInicio || !dataFim) {
      return c.json({ success: false, error: "Indique a data de início e de fim do período" }, 400);
    }

    const resultado = await livroRegistoINSS.gerarLivroRegistoINSS(empresaId, dataInicio, dataFim);
    return c.json({ success: true, data: resultado });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

// ========== SIMULACAO DE IMPACTO IRPS ==========

rhRouter.post("/empresas/:empresaId/simulacoes/irps", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "simulacaoIrps", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { ano, salarioBase, novoSalarioBase, escaloesHipoteticos, irpsIncideSobreRendimentoBrutoHipotetico } = await c.req.json();
    const parametrosAtuais = await parametrosFiscaisRH.obterParametrosFiscaisRH(Number(ano) || new Date().getFullYear());

    const resultado = simularImpactoIRPS(
      {
        salarioBase: Number(salarioBase),
        novoSalarioBase: novoSalarioBase !== undefined ? Number(novoSalarioBase) : undefined,
        escaloesHipoteticos,
        irpsIncideSobreRendimentoBrutoHipotetico,
      },
      parametrosAtuais,
    );

    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);
  }
});

// ========== CERTIFICADO DE RETENCAO ANUAL IRPS ==========

rhRouter.get("/empresas/:empresaId/certificados-retencao-irps", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "certificadoIrps", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { colaboradorId, ano, estado } = c.req.query();
    const filtros: Parameters<typeof certificadoRetencaoIRPS.listarCertificadosRetencaoIRPS>[1] = {};
    if (colaboradorId) filtros.colaboradorId = colaboradorId;
    if (ano) filtros.ano = Number(ano);
    if (estado) filtros.estado = estado as certificadoRetencaoIRPS.EstadoCertificadoRetencaoIRPS;

    const lista = await certificadoRetencaoIRPS.listarCertificadosRetencaoIRPS(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/empresas/:empresaId/certificados-retencao-irps/gerar", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "certificadoIrps", "criar")) return respostaSemPermissao(c, "criar");

    const { colaboradorId, ano } = await c.req.json();
    const emitidoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await certificadoRetencaoIRPS.gerarCertificadoRetencaoIRPS(empresaId, colaboradorId, Number(ano), emitidoPor);
    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);
  }
});

rhRouter.post("/certificados-retencao-irps/:id/anular", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await certificadoRetencaoIRPS.buscarCertificadoRetencaoIRPSPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Certificado não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "certificadoIrps", "deletar")) return respostaSemPermissao(c, "deletar");

    const { motivo } = await c.req.json();
    const anuladoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await certificadoRetencaoIRPS.anularCertificadoRetencaoIRPS(id, motivo, anuladoPor);
    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);
  }
});

// ========== COMUNICACOES DE ALTERACAO DE DEPENDENTES (IRPS) ==========

rhRouter.get("/empresas/:empresaId/comunicacoes-dependentes-irps", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "comunicacaoIrps", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { colaboradorId, tipo, estado } = c.req.query();
    const filtros: Parameters<typeof comunicacaoDependentesIRPS.listarComunicacoesDependentesIRPS>[1] = {};
    if (colaboradorId) filtros.colaboradorId = colaboradorId;
    if (tipo) filtros.tipo = tipo as comunicacaoDependentesIRPS.TipoComunicacaoDependenteIRPS;
    if (estado) filtros.estado = estado as comunicacaoDependentesIRPS.EstadoComunicacaoDependenteIRPS;

    const lista = await comunicacaoDependentesIRPS.listarComunicacoesDependentesIRPS(empresaId, filtros);
    return c.json({ success: true, data: lista });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.post("/comunicacoes-dependentes-irps/:id/enviar", async (c) => {
  try {
    const id = c.req.param("id");
    const existente = await comunicacaoDependentesIRPS.buscarComunicacaoDependenteIRPSPorId(id);
    if (!existente) {
      return c.json({ success: false, error: "Comunicação não encontrada" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, existente.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "comunicacaoIrps", "editar")) return respostaSemPermissao(c, "editar");

    const { numeroProtocolo, observacoes } = await c.req.json();
    const comunicadoPor = acesso.usuario?.nome || acesso.usuario?.email || "Utilizador do sistema";
    const resultado = await comunicacaoDependentesIRPS.marcarComunicacaoDependenteIRPSEnviada(id, comunicadoPor, numeroProtocolo, observacoes);
    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);
  }
});

// ========== HISTORICO DE RETENCOES + RELATORIOS E ANALISES IRPS ==========

rhRouter.get("/colaboradores/:id/historico-retencoes-irps", async (c) => {
  try {
    const id = c.req.param("id");
    const colaborador = await colaboradores.buscarColaboradorPorId(id);
    if (!colaborador) {
      return c.json({ success: false, error: "Colaborador não encontrado" }, 404);
    }

    const acesso = await validarAcessoEmpresaRequest(c, colaborador.empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const resultado = await relatoriosFiscaisRH.gerarHistoricoRetencoesIRPS(colaborador.empresaId, 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);
  }
});

rhRouter.get("/empresas/:empresaId/relatorios/mapa-anual-irps/:ano", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const ano = Number(c.req.param("ano"));
    const resultado = await relatoriosFiscaisRH.gerarMapaAnualIRPS(empresaId, ano);
    return c.json({ success: true, data: resultado });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

rhRouter.get("/empresas/:empresaId/relatorios/progressividade-irps", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { ano, mes } = c.req.query();
    const resultado = await relatoriosFiscaisRH.gerarAnaliseProgressividadeIRPS(empresaId, Number(ano), Number(mes));
    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);
  }
});

rhRouter.get("/empresas/:empresaId/relatorios/previsao-irps", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { ano, mes, meses } = c.req.query();
    const resultado = await relatoriosFiscaisRH.gerarPrevisaoIRPS(empresaId, Number(ano), Number(mes), meses ? Number(meses) : 6);
    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);
  }
});

rhRouter.get("/empresas/:empresaId/relatorios/livro-registo-irps", async (c) => {
  try {
    const empresaId = c.req.param("empresaId");
    const acesso = await validarAcessoEmpresaRequest(c, empresaId);
    if (!acesso.permitido) return acesso.resposta;
    if (!temPermissaoRH(acesso.usuario, "processamento", "visualizar")) return respostaSemPermissao(c, "visualizar");

    const { dataInicio, dataFim } = c.req.query();
    if (!dataInicio || !dataFim) {
      return c.json({ success: false, error: "Indique a data de início e de fim do período" }, 400);
    }

    const resultado = await livroRegistoIRPS.gerarLivroRegistoIRPS(empresaId, dataInicio, dataFim);
    return c.json({ success: true, data: resultado });
  } catch (error: any) {
    return c.json({ success: false, error: error.message || String(error) }, 500);
  }
});

export default rhRouter;
