"use client";

import { useEffect, useMemo, useState } from "react";
import { Bar, BarChart, Cell, Pie, PieChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
import type { PainelDeProducao } from "@/lib/orders/eventos-de-producao";
import { formatarDuracao } from "@/lib/orders/ficha-de-producao";
import { quantidadeDoItem } from "@/lib/orders/quantidade-do-item";

/**
 * A análise do pedido: quanto entra, quanto custa, quanto sobra, e quanto
 * disso paga as contas do mês.
 *
 * Números grandes e poucas palavras. O custo e a margem vêm congelados na
 * venda (`pricing_snapshot`); a contribuição e o termômetro do mês vêm da
 * rota `/api/orders/[id]/analise`, que usa a mesma régua da página Ponto de
 * Equilíbrio. Se um número não existe, a tela diz que não existe.
 */

type ItemDaAnalise = {
  id: string;
  title: string;
  quantity: number;
  unit_price: number;
  total_price: number;
  unit_type?: string | null;
  width_m?: number | null;
  height_m?: number | null;
  length_m?: number | null;
  calculated_cost?: number | null;
  pricing_snapshot?: unknown;
};

type PagamentoDaAnalise = { amount: number; payment_method?: string | null };

type PedidoDaAnalise = {
  status: string;
  created_at: string;
  delivery_date?: string | null;
  production_first_started_at?: string | null;
  production_finished_at?: string | null;
  quotes?: { delivery_date?: string | null } | null;
};

type RespostaDaAnalise = {
  ok: true;
  pedido: {
    receita: number;
    desconto: number;
    custoTotal: number;
    custoConhecido: boolean;
    materiaPrima: number;
    variaveisPct: number;
    variaveisValor: number;
    contribuicao: number;
    contribuicaoPct: number;
    lucro: number | null;
  };
  itens: { id: string; title: string; receita: number; custo: number | null; materiais: number | null; origem: string | null }[];
  mes: {
    temFixo: boolean;
    fixoMensal: number;
    cmAcumulada: number;
    receitaMes: number;
    progressoPct: number;
    bateu: boolean;
    lucroAtual: number;
    diasRestantes: number;
    faltaParaEquilibrio: number;
    participacaoDoPedidoPct: number | null;
    pedidosComoEste: number | null;
    custoFixoPorHora: number | null;
    horasQueOPedidoPaga: number | null;
  } | null;
  erroDoMes: string | null;
};

const dinheiro = (n: number) => new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(n);
const pct = (n: number) => `${new Intl.NumberFormat("pt-BR", { maximumFractionDigits: 1 }).format(n)}%`;
const numero = (v: unknown) => {
  const n = Number(v);
  return Number.isFinite(n) ? n : 0;
};

const METODO: Record<string, string> = {
  pix: "Pix",
  cash: "Dinheiro",
  dinheiro: "Dinheiro",
  card: "Cartão",
  credit_card: "Crédito",
  debit_card: "Débito",
  cartao: "Cartão",
  transfer: "Transferência",
  boleto: "Boleto",
};

function custoDoItem(item: ItemDaAnalise): number | null {
  const snap = item.pricing_snapshot && typeof item.pricing_snapshot === "object" ? (item.pricing_snapshot as Record<string, unknown>) : null;
  if (snap && Number.isFinite(Number(snap.custo_total))) return Number(snap.custo_total);
  if (item.calculated_cost !== null && item.calculated_cost !== undefined && Number(item.calculated_cost) > 0) {
    return Number(item.calculated_cost) * numero(item.quantity);
  }
  return null;
}

function diasEntre(a: string | null | undefined, b: string | null | undefined): number | null {
  if (!a || !b) return null;
  const ms = new Date(b).getTime() - new Date(a).getTime();
  return Number.isFinite(ms) ? Math.round(ms / 86400000) : null;
}

export function AnaliseDoPedido({
  orderId,
  order,
  items,
  payments,
  painel,
  totais,
}: {
  orderId: string;
  order: PedidoDaAnalise;
  items: ItemDaAnalise[];
  payments: PagamentoDaAnalise[];
  painel: PainelDeProducao | null;
  totais: { subtotal: number; desconto: number; frete: number; total: number };
}) {
  const [servidor, setServidor] = useState<RespostaDaAnalise | null>(null);
  const [erro, setErro] = useState<string | null>(null);

  useEffect(() => {
    let ativo = true;
    fetch(`/api/orders/${orderId}/analise`, { cache: "no-store" })
      .then(async (res) => {
        const json = (await res.json().catch(() => null)) as (RespostaDaAnalise & { error?: string }) | null;
        if (!ativo) return;
        if (!res.ok || !json || json.error) setErro(json?.error || "Não deu para calcular a análise.");
        else setServidor(json);
      })
      .catch(() => {
        if (ativo) setErro("Não deu para calcular a análise.");
      });
    return () => {
      ativo = false;
    };
  }, [orderId]);

  const local = useMemo(() => {
    const linhas = items.map((item) => {
      const custo = custoDoItem(item);
      const receita = numero(item.total_price) || numero(item.quantity) * numero(item.unit_price);
      const lucro = custo === null ? null : receita - custo;
      return { id: item.id, nome: item.title, quantidade: quantidadeDoItem(item).pecasTexto, receita, custo, lucro, margem: lucro === null || receita <= 0 ? null : (lucro / receita) * 100 };
    });
    const custoConhecido = linhas.length > 0 && linhas.every((l) => l.custo !== null);
    const custoTotal = linhas.reduce((acc, l) => acc + (l.custo ?? 0), 0);
    const receitaDosItens = Math.max(0, totais.subtotal - totais.desconto);
    const lucro = custoConhecido ? receitaDosItens - custoTotal : null;
    const recebido = payments.reduce((acc, p) => acc + numero(p.amount), 0);
    const falta = Math.max(0, totais.total - recebido);
    const porMetodo = new Map<string, number>();
    for (const p of payments) {
      const chave = METODO[(p.payment_method || "").toLowerCase()] || p.payment_method || "Outro";
      porMetodo.set(chave, (porMetodo.get(chave) ?? 0) + numero(p.amount));
    }
    const previsto = painel?.order.minutos_previstos ?? 0;
    const apontado = painel ? painel.itens.reduce((acc, i) => acc + (i.minutos_reais || 0), 0) : 0;
    const emProducao = painel ? painel.resumo.etapas.find((e) => e.status === "in_production") : null;
    const entrega = order.delivery_date || order.quotes?.delivery_date || null;
    const hoje = new Date().toISOString();
    return {
      linhas,
      custoConhecido,
      custoTotal,
      receitaDosItens,
      lucro,
      margem: lucro !== null && receitaDosItens > 0 ? (lucro / receitaDosItens) * 100 : null,
      recebido,
      falta,
      porMetodo: [...porMetodo.entries()].sort((a, b) => b[1] - a[1]),
      previsto,
      apontado,
      uteisNaProducao: emProducao?.minutosUteis ?? 0,
      corridoNaProducao: emProducao?.minutos ?? 0,
      diasParaEntrega: entrega ? diasEntre(hoje.slice(0, 10), String(entrega).slice(0, 10)) : null,
      entregue: order.status === "delivered",
      temEntrega: Boolean(entrega),
    };
  }, [items, payments, painel, totais, order]);

  const a = local;
  const m = servidor?.mes ?? null;
  const contrib = servidor?.pedido ?? null;
  const barraCusto = a.receitaDosItens > 0 ? Math.min(100, (a.custoTotal / a.receitaDosItens) * 100) : 0;
  const barraSobra = a.lucro !== null && a.receitaDosItens > 0 ? Math.max(0, Math.min(100 - barraCusto, (a.lucro / a.receitaDosItens) * 100)) : 0;
  const dadosPorItem = a.linhas.map((l) => ({
    nome: l.nome.length > 22 ? `${l.nome.slice(0, 21)}…` : l.nome,
    Vendido: Math.round(l.receita * 100) / 100,
    Custo: l.custo === null ? 0 : Math.round(l.custo * 100) / 100,
    Sobra: l.lucro === null ? 0 : Math.round(Math.max(0, l.lucro) * 100) / 100,
  }));
  const dadosPagamento = [
    { nome: "Recebido", valor: Math.round(a.recebido * 100) / 100 },
    { nome: "Falta", valor: Math.round(a.falta * 100) / 100 },
  ];

  /* O termômetro: o fixo do mês é a barra inteira; o verde é o que o mês já
     pagou; a fatia roxa, no fim do verde, é a parte deste pedido. */
  const mesPct = m && m.temFixo ? Math.min(100, m.progressoPct) : 0;
  const fatiaDoPedido = m && m.temFixo && m.participacaoDoPedidoPct ? Math.max(0, Math.min(mesPct, m.participacaoDoPedidoPct)) : 0;

  return (
    <div className="min-w-0 space-y-4 overflow-hidden">
      {/* ------------------------------------------------ os quatro números */}
      <section className="ks-surface rounded-xl border border-[var(--ks-color-border-subtle)]">
        <dl className="grid grid-cols-2 divide-y divide-[var(--ks-color-border-subtle)] sm:grid-cols-4 sm:divide-x sm:divide-y-0">
          <Numero rotulo="Vendido" valor={dinheiro(totais.total)} nota={totais.frete > 0 ? `inclui ${dinheiro(totais.frete)} de frete` : undefined} />
          <Numero rotulo="Custo" valor={a.custoConhecido ? dinheiro(a.custoTotal) : "—"} nota={a.custoConhecido ? undefined : "falta custo em algum item"} />
          <Numero rotulo="Sobra" valor={a.lucro === null ? "—" : dinheiro(a.lucro)} nota={a.margem === null ? undefined : `${pct(a.margem)} do vendido em itens`} destaque={a.lucro === null ? null : a.lucro >= 0 ? "bom" : "ruim"} />
          <Numero rotulo="Recebido" valor={dinheiro(a.recebido)} nota={a.falta > 0 ? `falta ${dinheiro(a.falta)}` : "tudo recebido"} destaque={a.falta > 0 ? "atencao" : "bom"} />
        </dl>
        <div className="flex h-2.5 w-full overflow-hidden rounded-b-xl bg-[var(--ks-color-bg-soft)]" title={a.lucro === null ? "" : `Custo ${pct(barraCusto)} · Sobra ${pct(barraSobra)}`}>
          <div className="bg-[var(--ks-color-status-info,#1b7fce)]" style={{ width: `${barraCusto}%` }} />
          <div className="bg-[var(--ks-color-primary)]" style={{ width: `${barraSobra}%` }} />
        </div>
      </section>

      {/* ------------------------------------------------ as contas do mês */}
      <section className="ks-surface rounded-xl border border-[var(--ks-color-border-subtle)] p-4">
        <div className="flex flex-wrap items-baseline justify-between gap-2">
          <h3 className="text-sm font-bold text-[var(--ks-color-text-primary)]">Quanto este pedido paga das contas do mês</h3>
          {contrib ? (
            <span className="text-xs text-[var(--ks-color-text-muted)]">
              contribuição de <span className="ks-num font-semibold text-[var(--ks-color-text-primary)]">{dinheiro(contrib.contribuicao)}</span> ({pct(contrib.contribuicaoPct)} do vendido, já tirando material e {pct(contrib.variaveisPct)} de impostos e taxas)
            </span>
          ) : null}
        </div>

        {!servidor && !erro ? <p className="mt-3 text-xs text-[var(--ks-color-text-muted)]">Calculando…</p> : null}
        {erro ? <p className="mt-3 text-xs text-[var(--ks-color-status-danger)]">{erro}</p> : null}
        {servidor && !m && servidor.erroDoMes ? <p className="mt-3 text-xs text-[var(--ks-color-text-muted)]">{servidor.erroDoMes}</p> : null}
        {m && !m.temFixo ? (
          <p className="mt-3 text-xs text-[var(--ks-color-text-muted)]">
            Cadastre os custos fixos em Precificação → Custos fixos para ver quanto cada pedido ajuda a pagar as contas.
          </p>
        ) : null}

        {m && m.temFixo && contrib ? (
          <div className="mt-3 grid gap-4 lg:grid-cols-[minmax(0,1fr)_auto] lg:items-center">
            <div>
              <div className="flex items-end justify-between text-xs text-[var(--ks-color-text-muted)]">
                <span>
                  Custos fixos do mês: <span className="ks-num font-semibold text-[var(--ks-color-text-primary)]">{dinheiro(m.fixoMensal)}</span>
                </span>
                <span>
                  já pagos: <span className="ks-num font-semibold text-[var(--ks-color-status-success,#16a34a)]">{pct(m.progressoPct)}</span>
                </span>
              </div>
              <div className="mt-1 flex h-5 w-full overflow-hidden rounded-lg bg-[var(--ks-color-bg-soft)]">
                <div className="bg-[var(--ks-color-status-success,#16a34a)]" style={{ width: `${Math.max(0, mesPct - fatiaDoPedido)}%` }} title="Outros pedidos do mês" />
                <div className="bg-[var(--ks-color-primary)]" style={{ width: `${fatiaDoPedido}%` }} title="Este pedido" />
              </div>
              <div className="mt-1 flex flex-wrap gap-x-4 text-[11px] text-[var(--ks-color-text-muted)]">
                <span><span className="inline-block h-2 w-2 rounded-sm bg-[var(--ks-color-status-success,#16a34a)]" /> outros pedidos</span>
                <span><span className="inline-block h-2 w-2 rounded-sm bg-[var(--ks-color-primary)]" /> este pedido</span>
                {m.bateu ? <span>o mês já se pagou: sobra {dinheiro(m.lucroAtual)}</span> : <span>faltam {dinheiro(m.faltaParaEquilibrio)} em {m.diasRestantes} {m.diasRestantes === 1 ? "dia" : "dias"}</span>}
              </div>
            </div>
            <dl className="grid grid-cols-3 gap-4 text-center lg:min-w-[360px]">
              <div>
                <dt className="text-[11px] font-semibold uppercase tracking-wide text-[var(--ks-color-text-soft)]">Este pedido paga</dt>
                <dd className="ks-num text-2xl font-extrabold text-[var(--ks-color-primary)]">{m.participacaoDoPedidoPct === null ? "—" : pct(m.participacaoDoPedidoPct)}</dd>
                <dd className="text-[11px] text-[var(--ks-color-text-muted)]">dos custos fixos</dd>
              </div>
              <div>
                <dt className="text-[11px] font-semibold uppercase tracking-wide text-[var(--ks-color-text-soft)]">Equivale a</dt>
                <dd className="ks-num text-2xl font-extrabold text-[var(--ks-color-text-primary)]">{m.horasQueOPedidoPaga === null ? "—" : formatarDuracao(m.horasQueOPedidoPaga * 60)}</dd>
                <dd className="text-[11px] text-[var(--ks-color-text-muted)]">{m.horasQueOPedidoPaga === null ? "cadastre as horas produtivas do mês" : "de estrutura paga"}</dd>
              </div>
              <div>
                <dt className="text-[11px] font-semibold uppercase tracking-wide text-[var(--ks-color-text-soft)]">Para fechar o mês</dt>
                <dd className="ks-num text-2xl font-extrabold text-[var(--ks-color-text-primary)]">{m.bateu ? "feito" : m.pedidosComoEste === null ? "—" : m.pedidosComoEste}</dd>
                <dd className="text-[11px] text-[var(--ks-color-text-muted)]">{m.bateu ? "já passou do ponto" : "pedidos como este"}</dd>
              </div>
            </dl>
          </div>
        ) : null}
      </section>

      <div className="grid min-w-0 gap-4 lg:grid-cols-5">
        {/* ------------------------------------------------ item a item */}
        <section className="ks-surface min-w-0 overflow-hidden rounded-xl border border-[var(--ks-color-border-subtle)] p-4 lg:col-span-3">
          <h3 className="text-sm font-bold text-[var(--ks-color-text-primary)]">Item a item</h3>
          <div className="mt-2 h-40 w-full">
            <ResponsiveContainer width="100%" height="100%">
              <BarChart data={dadosPorItem} margin={{ top: 4, right: 8, left: 0, bottom: 0 }} barCategoryGap={18}>
                <XAxis dataKey="nome" tick={{ fontSize: 11 }} axisLine={false} tickLine={false} />
                <YAxis tick={{ fontSize: 10 }} axisLine={false} tickLine={false} width={56} tickFormatter={(v: number) => dinheiro(v).replace(/,\d\d$/, "")} />
                <Tooltip formatter={(v) => dinheiro(Number(v))} cursor={{ fill: "rgba(68,37,167,0.06)" }} />
                <Bar dataKey="Vendido" fill="var(--ks-color-brand-dark, #2b1a6b)" radius={[4, 4, 0, 0]} />
                <Bar dataKey="Custo" fill="var(--ks-color-status-info, #1b7fce)" radius={[4, 4, 0, 0]} />
                <Bar dataKey="Sobra" fill="var(--ks-color-primary)" radius={[4, 4, 0, 0]} />
              </BarChart>
            </ResponsiveContainer>
          </div>
          <div className="mt-1 overflow-x-auto">
          <table className="w-full min-w-[420px] text-xs">
            <thead className="text-[10px] uppercase tracking-wide text-[var(--ks-color-text-soft)]">
              <tr>
                <th className="py-1 text-left font-semibold">Item</th>
                <th className="py-1 text-right font-semibold">Vendido</th>
                <th className="py-1 text-right font-semibold">Custo</th>
                <th className="py-1 text-right font-semibold">Sobra</th>
                <th className="py-1 text-right font-semibold">Margem</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-[var(--ks-color-border-subtle)]">
              {a.linhas.map((l) => (
                <tr key={l.id}>
                  <td className="py-1.5 pr-2 text-[var(--ks-color-text-primary)]">
                    {l.nome} <span className="text-[var(--ks-color-text-soft)]">· {l.quantidade}</span>
                  </td>
                  <td className="ks-num py-1.5 text-right">{dinheiro(l.receita)}</td>
                  <td className="ks-num py-1.5 text-right">{l.custo === null ? "—" : dinheiro(l.custo)}</td>
                  <td className={`ks-num py-1.5 text-right font-semibold ${l.lucro !== null && l.lucro < 0 ? "text-[var(--ks-color-status-danger)]" : ""}`}>{l.lucro === null ? "—" : dinheiro(l.lucro)}</td>
                  <td className="ks-num py-1.5 text-right">{l.margem === null ? "—" : pct(l.margem)}</td>
                </tr>
              ))}
            </tbody>
          </table>
          </div>
          {servidor?.itens.some((i) => i.origem === "informado") ? (
            <p className="mt-2 text-[11px] text-[var(--ks-color-text-muted)]">Custo informado à mão na precificação, não pela ficha técnica: {servidor.itens.filter((i) => i.origem === "informado").map((i) => i.title).join(", ")}.</p>
          ) : null}
        </section>

        {/* ------------------------------------------------ pagamento */}
        <section className="ks-surface min-w-0 overflow-hidden rounded-xl border border-[var(--ks-color-border-subtle)] p-4 lg:col-span-2">
          <h3 className="text-sm font-bold text-[var(--ks-color-text-primary)]">Pagamento</h3>
          <div className="mt-1 flex items-center gap-3">
            <div className="h-28 w-28 shrink-0">
              <ResponsiveContainer width="100%" height="100%">
                <PieChart>
                  <Pie data={dadosPagamento} dataKey="valor" nameKey="nome" innerRadius={34} outerRadius={52} startAngle={90} endAngle={-270} stroke="none">
                    <Cell fill="var(--ks-color-status-success, #16a34a)" />
                    <Cell fill="var(--ks-color-bg-soft, #e5e7eb)" />
                  </Pie>
                  <Tooltip formatter={(v) => dinheiro(Number(v))} />
                </PieChart>
              </ResponsiveContainer>
            </div>
            <div className="min-w-0 text-sm">
              <div className="ks-num text-2xl font-extrabold text-[var(--ks-color-text-primary)]">{totais.total > 0 ? pct(Math.min(100, (a.recebido / totais.total) * 100)) : "—"}</div>
              <div className="text-xs text-[var(--ks-color-text-muted)]">recebido</div>
              <ul className="mt-2 space-y-0.5 text-xs">
                {a.porMetodo.length === 0 ? <li className="text-[var(--ks-color-text-muted)]">nenhum pagamento</li> : null}
                {a.porMetodo.map(([metodo, valor]) => (
                  <li key={metodo} className="flex justify-between gap-3">
                    <span className="text-[var(--ks-color-text-muted)]">{metodo}</span>
                    <span className="ks-num font-semibold">{dinheiro(valor)}</span>
                  </li>
                ))}
                {a.falta > 0 ? (
                  <li className="flex justify-between gap-3 border-t border-[var(--ks-color-border-subtle)] pt-1">
                    <span className="font-semibold text-[var(--ks-color-status-danger)]">falta</span>
                    <span className="ks-num font-semibold text-[var(--ks-color-status-danger)]">{dinheiro(a.falta)}</span>
                  </li>
                ) : null}
              </ul>
            </div>
          </div>
        </section>
      </div>

      {/* ------------------------------------------------ tempo e prazo */}
      <section className="ks-surface rounded-xl border border-[var(--ks-color-border-subtle)]">
        <dl className="grid grid-cols-2 divide-y divide-[var(--ks-color-border-subtle)] sm:grid-cols-4 sm:divide-x sm:divide-y-0">
          <Numero rotulo="Previsto na ficha" valor={a.previsto > 0 ? formatarDuracao(a.previsto) : "—"} nota={a.previsto > 0 ? undefined : "sem ficha de tempo"} />
          <Numero
            rotulo="Apontado"
            valor={a.apontado > 0 ? formatarDuracao(a.apontado) : "—"}
            nota={a.apontado > 0 && a.previsto > 0 ? (a.apontado > a.previsto ? `${pct(((a.apontado - a.previsto) / a.previsto) * 100)} acima do previsto` : `${pct(((a.previsto - a.apontado) / a.previsto) * 100)} abaixo do previsto`) : "ninguém apontou"}
            destaque={a.apontado > 0 && a.previsto > 0 ? (a.apontado > a.previsto * 1.2 ? "ruim" : "bom") : null}
          />
          <Numero rotulo="Em produção" valor={a.corridoNaProducao > 0 ? formatarDuracao(a.uteisNaProducao) : "—"} nota={a.corridoNaProducao > 0 ? `úteis · ${formatarDuracao(a.corridoNaProducao)} corridas` : "ainda não entrou"} />
          <Numero
            rotulo="Entrega"
            valor={!a.temEntrega ? "—" : a.entregue ? "entregue" : a.diasParaEntrega === null ? "—" : a.diasParaEntrega < 0 ? `${Math.abs(a.diasParaEntrega)} ${Math.abs(a.diasParaEntrega) === 1 ? "dia" : "dias"} atrasado` : a.diasParaEntrega === 0 ? "hoje" : `${a.diasParaEntrega} ${a.diasParaEntrega === 1 ? "dia" : "dias"}`}
            nota={!a.temEntrega ? "sem data" : a.entregue ? undefined : a.diasParaEntrega !== null && a.diasParaEntrega >= 0 ? "para a entrega" : undefined}
            destaque={a.diasParaEntrega !== null && a.diasParaEntrega < 0 && !a.entregue ? "ruim" : null}
          />
        </dl>
      </section>
    </div>
  );
}

function Numero({ rotulo, valor, nota, destaque }: { rotulo: string; valor: string; nota?: string; destaque?: "bom" | "ruim" | "atencao" | null }) {
  const cor =
    destaque === "bom"
      ? "text-[var(--ks-color-status-success,#16a34a)]"
      : destaque === "ruim"
        ? "text-[var(--ks-color-status-danger)]"
        : destaque === "atencao"
          ? "text-[var(--ks-color-primary)]"
          : "text-[var(--ks-color-text-primary)]";
  return (
    <div className="px-4 py-3">
      <dt className="text-[11px] font-semibold uppercase tracking-wide text-[var(--ks-color-text-soft)]">{rotulo}</dt>
      <dd className={`ks-num mt-0.5 text-xl font-extrabold ${cor}`}>{valor}</dd>
      {nota ? <dd className="text-[11px] text-[var(--ks-color-text-muted)]">{nota}</dd> : null}
    </div>
  );
}
