"use client";

/**
 * Gráficos do relatório da agenda.
 *
 * Tudo em SVG e divs: um relatorio que precisa sair em PDF pelo proprio
 * navegador nao pode depender de canvas, que a impressao costuma perder. E
 * uma biblioteca de graficos pesaria mais que a agenda inteira para desenhar
 * barra, rosca e matriz.
 */

export const PALETA = [
  "#6C3CF0",
  "#10B981",
  "#F59E0B",
  "#3B82F6",
  "#EC4899",
  "#14B8A6",
  "#F97316",
  "#8B5CF6",
  "#0EA5E9",
  "#84CC16",
];

export function Bloco({
  titulo,
  descricao,
  children,
  largo,
}: {
  titulo: string;
  descricao?: string;
  children: React.ReactNode;
  largo?: boolean;
}) {
  return (
    <section
      className={`break-inside-avoid rounded-[14px] border border-[var(--ag-border)] bg-[var(--ag-surface)] p-4 shadow-[var(--ag-sombra-1)] ${
        largo ? "lg:col-span-2" : ""
      }`}
    >
      <h2 className="text-[13.5px] font-semibold text-[var(--ag-text)]">{titulo}</h2>
      {descricao && <p className="mt-[3px] text-[11.5px] text-[var(--ag-text-3)]">{descricao}</p>}
      <div className="mt-3.5">{children}</div>
    </section>
  );
}

export function Vazio({ texto = "Nada no período" }: { texto?: string }) {
  return <p className="py-6 text-center text-[12px] text-[var(--ag-text-5)]">{texto}</p>;
}

/* ---------------- Barras verticais ---------------- */

export function Barras({
  dados,
  altura = 150,
  sufixo = "",
}: {
  dados: { rotulo: string; valor: number; cor?: string; destaque?: boolean }[];
  altura?: number;
  sufixo?: string;
}) {
  const max = Math.max(...dados.map((d) => d.valor), 1);
  if (!dados.length) return <Vazio />;

  return (
    <div className="flex items-end gap-1.5 overflow-x-auto" style={{ height: altura }}>
      {dados.map((d, i) => {
        /* Barra com valor zero ainda desenha um traco de 2px: some por
           completo passaria a ideia de "dia inexistente", nao de "dia vazio". */
        const h = d.valor ? Math.max((d.valor / max) * (altura - 26), 3) : 2;
        return (
          <div key={`${d.rotulo}-${i}`} className="flex min-w-0 flex-1 flex-col items-center justify-end gap-1">
            <span className="text-[9.5px] font-semibold tabular-nums text-[var(--ag-text-3)]">
              {d.valor ? `${d.valor}${sufixo}` : ""}
            </span>
            <div
              className="w-full rounded-[4px] transition-all"
              style={{
                height: h,
                background: d.valor ? (d.cor ?? "#6C3CF0") : "var(--ag-border)",
                opacity: d.destaque === false ? 0.45 : 1,
              }}
              title={`${d.rotulo}: ${d.valor}${sufixo}`}
            />
            <span className="w-full truncate text-center text-[9.5px] font-medium text-[var(--ag-text-4)]">
              {d.rotulo}
            </span>
          </div>
        );
      })}
    </div>
  );
}

/* ---------------- Rosca com legenda ---------------- */

const TAM = 132;
const GROSSURA = 18;
const RAIO = (TAM - GROSSURA) / 2;
const VOLTA = 2 * Math.PI * RAIO;

export function Rosca({
  dados,
  centro,
  legendaCentro,
}: {
  dados: { rotulo: string; valor: number; cor: string }[];
  centro: string;
  legendaCentro: string;
}) {
  const soma = dados.reduce((t, d) => t + d.valor, 0);
  if (!soma) return <Vazio />;

  let acumulado = 0;
  const arcos = dados.map((d) => {
    const fracao = d.valor / soma;
    const comprimento = Math.max(fracao * VOLTA - 2, 1);
    const deslocamento = -acumulado * VOLTA;
    acumulado += fracao;
    return { ...d, comprimento, deslocamento, pct: Math.round(fracao * 100) };
  });

  return (
    <div className="flex flex-wrap items-center gap-5">
      <div className="relative shrink-0" style={{ width: TAM, height: TAM }}>
        <svg width={TAM} height={TAM} viewBox={`0 0 ${TAM} ${TAM}`} className="-rotate-90">
          <circle cx={TAM / 2} cy={TAM / 2} r={RAIO} fill="none" stroke="var(--ag-line-h)" strokeWidth={GROSSURA} />
          {arcos.map((a) => (
            <circle
              key={a.rotulo}
              cx={TAM / 2}
              cy={TAM / 2}
              r={RAIO}
              fill="none"
              stroke={a.cor}
              strokeWidth={GROSSURA}
              strokeDasharray={`${a.comprimento} ${VOLTA - a.comprimento}`}
              strokeDashoffset={a.deslocamento}
            />
          ))}
        </svg>
        <span className="absolute inset-0 flex flex-col items-center justify-center">
          <span className="text-[20px] font-bold tabular-nums leading-none text-[var(--ag-text)]">{centro}</span>
          <span className="mt-1 text-[9.5px] font-medium uppercase tracking-[0.04em] text-[var(--ag-text-5)]">
            {legendaCentro}
          </span>
        </span>
      </div>

      <ul className="min-w-[150px] flex-1 space-y-1.5">
        {arcos.map((a) => (
          <li key={a.rotulo} className="flex items-center gap-2 text-[11.5px]">
            <span aria-hidden className="h-[9px] w-[9px] shrink-0 rounded-full" style={{ background: a.cor }} />
            <span className="min-w-0 flex-1 truncate font-medium text-[var(--ag-text-2)]">{a.rotulo}</span>
            <span className="shrink-0 tabular-nums font-semibold text-[var(--ag-text)]">{a.valor}</span>
            <span className="w-9 shrink-0 text-right tabular-nums text-[var(--ag-text-5)]">{a.pct}%</span>
          </li>
        ))}
      </ul>
    </div>
  );
}

/* ---------------- Matriz de cruzamento ---------------- */

export function Matriz({
  linhas,
  colunas,
  valor,
  corBase = "#6C3CF0",
}: {
  linhas: string[];
  colunas: string[];
  valor: (linha: string, coluna: string) => number;
  corBase?: string;
}) {
  if (!linhas.length || !colunas.length) return <Vazio />;

  const celulas = linhas.flatMap((l) => colunas.map((c) => valor(l, c)));
  const max = Math.max(...celulas, 1);

  return (
    <div className="overflow-x-auto">
      <table className="w-full border-separate border-spacing-[2px] text-[11px]">
        <thead>
          <tr>
            <th className="sticky left-0 bg-[var(--ag-surface)]" />
            {colunas.map((c) => (
              <th key={c} className="px-1 pb-1 text-center font-semibold text-[var(--ag-text-3)]">
                {c}
              </th>
            ))}
            <th className="pl-2 pb-1 text-right font-semibold text-[var(--ag-text-3)]">Total</th>
          </tr>
        </thead>
        <tbody>
          {linhas.map((l) => {
            const total = colunas.reduce((t, c) => t + valor(l, c), 0);
            return (
              <tr key={l}>
                <th className="sticky left-0 max-w-[150px] truncate bg-[var(--ag-surface)] pr-2 text-left font-medium text-[var(--ag-text-2)]">
                  {l}
                </th>
                {colunas.map((c) => {
                  const n = valor(l, c);
                  /* Intensidade proporcional ao maior valor da matriz: cor
                     chapada em tudo que e diferente de zero esconderia
                     justamente onde a carga se concentra. */
                  const intensidade = n ? 0.1 + (n / max) * 0.85 : 0;
                  return (
                    <td
                      key={c}
                      className="h-[30px] rounded-[5px] text-center tabular-nums"
                      style={{
                        background: n ? `${corBase}${Math.round(intensidade * 255).toString(16).padStart(2, "0")}` : "var(--ag-surface-2)",
                        color: intensidade > 0.55 ? "#FFFFFF" : n ? "var(--ag-text-2)" : "var(--ag-text-5)",
                        fontWeight: n ? 600 : 400,
                      }}
                      title={`${l} · ${c}: ${n}`}
                    >
                      {n || "–"}
                    </td>
                  );
                })}
                <td className="pl-2 text-right font-semibold tabular-nums text-[var(--ag-text)]">{total}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

/* ---------------- Linha de indicador ---------------- */

/**
 * Faixa de indicadores.
 *
 * Uma moldura para os seis, e nao seis molduras: cartao dentro de cartao
 * dentro de grade deixava a tela toda de bordinhas competindo entre si. Aqui
 * o divisor fino separa, e o numero fica sendo a unica coisa em destaque.
 */
export function FaixaDeNumeros({ itens }: { itens: ItemNumero[] }) {
  return (
    <section className="break-inside-avoid overflow-hidden rounded-[14px] border border-[var(--ag-border)] bg-[var(--ag-surface)]">
      <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6">
        {itens.map((it, i) => (
          <div
            key={it.rotulo}
            className={`px-4 py-3.5 ${
              i % 2 === 1 ? "border-l border-[var(--ag-line-h)]" : ""
            } sm:[&:not(:nth-child(3n+1))]:border-l lg:[&:not(:nth-child(6n+1))]:border-l lg:[&:nth-child(3n+1)]:border-l ${
              i >= 2 ? "border-t border-[var(--ag-line-h)] sm:border-t-0" : ""
            } sm:[&:nth-child(n+4)]:border-t lg:[&:nth-child(n+4)]:border-t-0`}
          >
            <p className="truncate text-[10.5px] font-medium uppercase tracking-[0.04em] text-[var(--ag-text-4)]">
              {it.rotulo}
            </p>
            <p
              className="mt-1.5 text-[22px] font-bold leading-none tabular-nums"
              style={{ color: it.cor ?? "var(--ag-text)" }}
            >
              {it.valor}
            </p>
            {it.detalhe && (
              <p className="mt-1.5 truncate text-[11px] text-[var(--ag-text-3)]">{it.detalhe}</p>
            )}
          </div>
        ))}
      </div>
    </section>
  );
}

export type ItemNumero = { rotulo: string; valor: string; detalhe?: string; cor?: string };
