/* Espelha o retorno de get_agenda_range(). Os eventos nao sao guardados em
   lugar nenhum: cada um e lido da tabela de origem a cada consulta, entao
   mudar o vencimento no Financeiro muda a agenda no mesmo instante.

   Orcamento nao aparece aqui: nao ha prazo obrigatorio de execucao antes de
   virar pedido, entao nunca foi um compromisso de verdade. */

export type TipoEvento =
  | "pedido_entrega"
  | "conta_pagar"
  | "conta_receber"
  | "link_pagamento"
  | "comissao"
  | "compra_fornecedor"
  | "cupom"
  | "compromisso";

export type EventoAgenda = {
  tipo: TipoEvento;
  origem_id: string;
  titulo: string;
  subtitulo: string | null;
  data: string;
  valor: number | null;
  situacao: string | null;
  rota: string;
  /* A cor e o nome nao vem mais de um mapa fixo por tipo: vem da categoria de
     verdade, que a pessoa cria e pinta como quiser. get_agenda_range ja
     resolve isso com coalesce, entao aqui os campos nunca chegam vazios. */
  categoria_id: string | null;
  categoria_nome: string;
  categoria_cor: string;
};

export type CategoriaAgenda = {
  id: string;
  name: string;
  color: string;
  is_system: boolean;
  system_key: string | null;
  sort_order: number;
};

/* O horario mora dentro do subtitulo ("HH:MM–HH:MM · Cliente" ou so
   "HH:MM · Cliente"), porque so o compromisso proprio tem hora marcada e
   get_agenda_range junta origens diferentes numa tabela so. Um evento sem
   nenhum dos dois (prazo, vencimento) devolve os dois campos nulos. */
export function horarioDoEvento(evento: Pick<EventoAgenda, "subtitulo">): {
  inicioMin: number | null;
  fimMin: number | null;
} {
  const bruto = String(evento.subtitulo || "");
  const m = bruto.match(/^(\d{2}):(\d{2})(?:[–-](\d{2}):(\d{2}))?/);
  if (!m) return { inicioMin: null, fimMin: null };
  return {
    inicioMin: Number(m[1]) * 60 + Number(m[2]),
    fimMin: m[3] !== undefined ? Number(m[3]) * 60 + Number(m[4]) : null,
  };
}

export type EstiloSituacao = { texto: string; fundo: string; cor: string };

/* So estilo — nenhum dado novo. `situacao` ja vem do banco (status do
   compromisso, do pedido, da conta...); isso so escolhe cor e rotulo pra
   mostrar num selo pequeno. Origem que a agenda nunca viu antes cai no
   generico cinza, com o proprio texto capitalizado — nunca inventa nem
   esconde o que veio. */
export function estiloSituacao(situacao: string | null | undefined): EstiloSituacao {
  const s = String(situacao || "").toLowerCase().trim();
  if (!s) return { texto: "", fundo: "#F3F4F7", cor: "#6B7280" };

  if (["concluido", "delivered", "finished", "paid", "received", "approved"].includes(s)) {
    return { texto: "Concluído", fundo: "#EAF8EF", cor: "#279557" };
  }
  if (["cancelado", "canceled", "rejected"].includes(s)) {
    return { texto: "Cancelado", fundo: "#FDECEC", cor: "#D64D4D" };
  }
  if (s === "overdue") {
    return { texto: "Vencido", fundo: "#FDECEC", cor: "#D64D4D" };
  }
  if (["pending_production", "producing", "in_production"].includes(s)) {
    return { texto: "Em produção", fundo: "#EDF4FF", cor: "#3777D6" };
  }
  if (["agendado", "pending", "sent", "draft"].includes(s)) {
    return { texto: "Agendado", fundo: "#FFF7ED", cor: "#D97706" };
  }

  const legivel = s.charAt(0).toUpperCase() + s.slice(1).replace(/_/g, " ");
  return { texto: legivel, fundo: "#F3F4F7", cor: "#5B6472" };
}

/* Datas em texto puro do banco (AAAA-MM-DD). Passar por new Date() aplicaria
   fuso e jogaria o evento para o dia anterior no Brasil. */
export function chaveDoDia(d: Date) {
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const dia = String(d.getDate()).padStart(2, "0");
  return `${d.getFullYear()}-${m}-${dia}`;
}

export function doTexto(iso: string) {
  const [a, m, d] = iso.split("-").map(Number);
  return new Date(a, (m || 1) - 1, d || 1);
}

export function somaDias(d: Date, n: number) {
  const r = new Date(d);
  r.setDate(r.getDate() + n);
  return r;
}

export function inicioDaSemana(d: Date) {
  const r = new Date(d);
  /* Semana comeca na segunda: a gráfica organiza produção por semana util. */
  const diff = (r.getDay() + 6) % 7;
  r.setDate(r.getDate() - diff);
  return r;
}
