"use client";

import Link from "next/link";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Check, Copy, Loader2, Mail, MessageCircle, Search, ShieldAlert, Unlock } from "lucide-react";

import { AreaFechada, CarregandoArea, ErroDaArea, FalhaDaArea, moeda, pedirDigitais } from "@/components/digitais/comum";
import { Aviso } from "@/components/ui/aviso";
import CaixaDeConfirmacao, { type Confirmacao } from "@/components/ui/caixa-de-confirmacao";
import { FIO_DA_LINHA } from "@/components/ui/folha-de-ajustes";
import { PageHeader } from "@/components/ui/page-header";

import { EncomendasDaLoja, type Encomenda } from "./encomendas";

type SituacaoDoEmail = "enviado" | "na_fila" | "falhou" | "sem_email" | "cancelado";

type Entrega = {
  pedidoId: string;
  numero: number | null;
  numeroNaLoja: number | null;
  data: string | null;
  cliente: string;
  emailDoCliente: string | null;
  produtos: string[];
  itens: number;
  acesso: "liberado" | "preparando" | "fechado";
  email: { situacao: SituacaoDoEmail; destino: string | null; enviadoEm: string | null; erro: string | null };
  /* O que ainda espera: código, arquivo final (sob encomenda) ou a data da pré-venda. */
  esperando?: { codigos: number; arquivosFinais: number; preVendaEm: string | null };
  /* O freio de compartilhamento pausou o acesso. */
  pausadoPeloFreio?: boolean;
};

type Pendencia = { pedidoId: string; numero: number | null; motivo: "sem_cliente" | "sem_entregavel"; data: string };
type Esperando = { pedidoId: string; numero: number | null; data: string; cliente: string; total: number; produtos: string[] };

type Resposta = { podeEditar: boolean; entregas: Entrega[]; pendencias: Pendencia[]; esperando: Esperando[]; encomendas?: Encomenda[] };

/* O que a entrega ainda espera, numa linha ("Esperando 2 códigos · Pré-venda: libera 01/11"). */
function textoDaEspera(entrega: Entrega): string | null {
  const espera = entrega.esperando;
  if (!espera) return null;
  const partes: string[] = [];
  if (espera.codigos) partes.push(`Esperando ${espera.codigos} ${espera.codigos === 1 ? "código" : "códigos"} (adicione no produto)`);
  if (espera.arquivosFinais) partes.push(`${espera.arquivosFinais} ${espera.arquivosFinais === 1 ? "arquivo" : "arquivos"} para fazer`);
  if (espera.preVendaEm) partes.push(`Pré-venda: libera ${new Date(espera.preVendaEm).toLocaleDateString("pt-BR", { timeZone: "America/Sao_Paulo" })}`);
  return partes.length ? partes.join(" · ") : null;
}

type Filtro = "todas" | "com_problema" | "na_fila";

/* Precisa da loja: o e-mail não chegou, ou o freio pausou o acesso (reativar fica com ela). */
function temProblema(entrega: Entrega): boolean {
  return entrega.email.situacao === "falhou" || entrega.email.situacao === "sem_email" || Boolean(entrega.pausadoPeloFreio);
}

const SELO_DO_EMAIL: Record<SituacaoDoEmail, { texto: string; classe: string }> = {
  enviado: { texto: "E-mail enviado", classe: "bg-[color:rgba(14,158,112,0.12)] text-[var(--ks-emerald)]" },
  na_fila: { texto: "Na fila", classe: "bg-[color:rgba(234,179,8,0.14)] text-[#a16207]" },
  falhou: { texto: "E-mail falhou", classe: "bg-[color:rgba(225,58,88,0.12)] text-[#c2263f]" },
  sem_email: { texto: "Sem e-mail", classe: "bg-[var(--ks-color-bg-inset)] text-[var(--ks-color-text-muted)]" },
  cancelado: { texto: "Não enviado", classe: "bg-[var(--ks-color-bg-inset)] text-[var(--ks-color-text-muted)]" },
};

const SELO_DO_ACESSO: Record<Entrega["acesso"], string> = {
  liberado: "Acesso liberado",
  preparando: "Preparando",
  fechado: "Acesso fechado",
};

const dataCurta = (iso: string | null) => (iso ? new Date(iso).toLocaleDateString("pt-BR") : "—");

/* O que a falha do e-mail quer dizer, em português. */
function motivoDoEmail(erro: string | null): string | null {
  if (!erro) return null;
  if (/inválido/i.test(erro)) return "O e-mail do comprador parece errado.";
  if (/cancelado/i.test(erro)) return "O pedido foi cancelado.";
  if (/nenhum acesso/i.test(erro)) return "O acesso deste pedido está fechado.";
  if (/Resend HTTP 4/i.test(erro)) return "O provedor de e-mail recusou este endereço.";
  return "Não conseguimos entregar o e-mail. Confira o endereço e reenvie.";
}

export default function EntregasDigitais() {
  const [dados, setDados] = useState<Resposta | null>(null);
  const [erro, setErro] = useState<Error | null>(null);
  const [filtro, setFiltro] = useState<Filtro>("todas");
  const [busca, setBusca] = useState("");
  const [aviso, setAviso] = useState<{ tom: "bom" | "ruim"; texto: string } | null>(null);
  const [ocupado, setOcupado] = useState<string | null>(null);
  const [confirmacao, setConfirmacao] = useState<Confirmacao | null>(null);
  const [reenviando, setReenviando] = useState<{ pedidoId: string; email: string } | null>(null);
  const [linkCopiado, setLinkCopiado] = useState<string | null>(null);

  const carregar = useCallback(
    () =>
      pedirDigitais<Resposta>("/api/digitais/entregas")
        .then((resposta) => {
          setDados(resposta);
          setErro(null);
        })
        .catch((e: unknown) => setErro(e instanceof Error ? e : new Error("Não foi possível carregar."))),
    []
  );

  useEffect(() => {
    void carregar();
  }, [carregar]);

  const contagem = useMemo(() => {
    const lista = dados?.entregas ?? [];
    return {
      todas: lista.length,
      com_problema: lista.filter(temProblema).length,
      na_fila: lista.filter((e) => e.email.situacao === "na_fila").length,
    } satisfies Record<Filtro, number>;
  }, [dados]);

  const visiveis = useMemo(() => {
    const termo = busca.trim().toLowerCase().replace(/^#/, "");
    return (dados?.entregas ?? [])
      .filter((e) => {
        if (filtro === "com_problema") return temProblema(e);
        if (filtro === "na_fila") return e.email.situacao === "na_fila";
        return true;
      })
      .filter((e) => !termo || `${e.numero ?? ""} ${e.numeroNaLoja ?? ""} ${e.cliente} ${e.emailDoCliente ?? ""} ${e.email.destino ?? ""} ${e.produtos.join(" ")}`.toLowerCase().includes(termo));
  }, [dados, filtro, busca]);

  const agir = async (pedidoId: string, acao: "reenviar" | "link" | "liberar" | "reativar", email?: string) => {
    setOcupado(`${pedidoId}:${acao}`);
    try {
      const resposta = await pedirDigitais<{ destino?: string; link?: string; criados?: number; semEntregavel?: number }>(
        `/api/digitais/entregas/${pedidoId}`,
        { method: "POST", body: JSON.stringify({ acao, email }) }
      );
      if (acao === "link" && resposta.link) {
        try {
          await navigator.clipboard.writeText(resposta.link);
          setLinkCopiado(pedidoId);
          window.setTimeout(() => setLinkCopiado(null), 3000);
          setAviso({ tom: "bom", texto: "Link da entrega copiado. Cole na conversa do WhatsApp com o comprador." });
        } catch {
          setAviso({ tom: "bom", texto: `Link da entrega: ${resposta.link}` });
        }
      } else if (acao === "reenviar") {
        setAviso({ tom: "bom", texto: `O e-mail da entrega está saindo para ${resposta.destino}.` });
        setReenviando(null);
        await carregar();
      } else if (acao === "reativar") {
        setAviso({
          tom: "bom",
          texto: resposta.destino
            ? `Acesso reativado. Os links antigos deixaram de valer e um e-mail novo está saindo para ${resposta.destino}.`
            : "Acesso reativado. Os links antigos deixaram de valer: mande um novo pelo Reenviar ou pelo Copiar link.",
        });
        await carregar();
      } else if (acao === "liberar") {
        setAviso({
          tom: "bom",
          texto: resposta.semEntregavel
            ? "Liberado, mas um dos produtos não tem nada para entregar. Abra o produto e adicione o que o comprador recebe."
            : "Acesso liberado. O comprador recebe o e-mail em instantes.",
        });
        await carregar();
      }
    } catch (e) {
      setAviso({ tom: "ruim", texto: e instanceof Error ? e.message : "Não foi possível agora." });
    } finally {
      setOcupado(null);
      setConfirmacao(null);
    }
  };

  if (erro instanceof ErroDaArea && erro.status === 403) return <AreaFechada erro={erro} />;
  if (erro && !dados) return <FalhaDaArea erro={erro} aoTentarDeNovo={() => void carregar()} />;
  if (!dados) return <CarregandoArea />;

  return (
    <div className="space-y-5">
      <PageHeader
        eyebrow="Quem comprou"
        title="Entregas"
        subtitle="Cada pedido com produto digital: o acesso, o e-mail da entrega e o que precisa de você."
      />

      {aviso ? (
        <Aviso tom={aviso.tom} aoFechar={() => setAviso(null)}>
          {aviso.texto}
        </Aviso>
      ) : null}

      <EncomendasDaLoja
        encomendas={dados.encomendas ?? []}
        podeEditar={dados.podeEditar}
        aoMudar={carregar}
        aoAvisar={(tom, texto) => setAviso({ tom, texto })}
      />

      {dados.pendencias.length ? (
        <section className="rounded-2xl border border-[color:rgba(234,179,8,0.35)] bg-[color:rgba(234,179,8,0.06)] p-4 sm:p-5">
          <h2 className="text-[15px] font-extrabold text-[var(--ks-color-text-primary)]">Precisam de você</h2>
          <ul className="mt-2 space-y-2">
            {dados.pendencias.map((p) => (
              <li key={`${p.pedidoId}:${p.motivo}`} className="flex flex-wrap items-center justify-between gap-3 text-sm">
                <span className="text-[var(--ks-color-text-primary)]">
                  <b>Pedido {p.numero ? `#${p.numero}` : ""}</b> ·{" "}
                  {p.motivo === "sem_cliente"
                    ? "está no cliente genérico do catálogo. Escolha o cliente no pedido e libere aqui."
                    : "tem um produto digital sem nada para entregar. Adicione o que o comprador recebe e libere aqui."}
                </span>
                <span className="flex gap-2">
                  <Link href={`/dashboard/orders/${p.pedidoId}`} className="ks-button ks-button-soft">
                    Abrir o pedido
                  </Link>
                  {dados.podeEditar ? (
                    <button
                      type="button"
                      className="ks-button ks-button-primary"
                      disabled={Boolean(ocupado)}
                      onClick={() => void agir(p.pedidoId, "liberar")}
                    >
                      {ocupado === `${p.pedidoId}:liberar` ? <Loader2 size={15} className="animate-spin" /> : <Unlock size={15} />}
                      Liberar
                    </button>
                  ) : null}
                </span>
              </li>
            ))}
          </ul>
        </section>
      ) : null}

      <div className="flex flex-wrap items-center justify-between gap-3">
        <div className="flex flex-wrap gap-2">
          {(
            [
              { valor: "todas", rotulo: "Todas" },
              { valor: "com_problema", rotulo: "Com problema" },
              { valor: "na_fila", rotulo: "Na fila" },
            ] as Array<{ valor: Filtro; rotulo: string }>
          ).map((f) => {
            const ativo = filtro === f.valor;
            return (
              <button
                key={f.valor}
                type="button"
                onClick={() => setFiltro(f.valor)}
                className={`rounded-full border px-3.5 py-1.5 text-[13px] font-semibold transition-colors ${
                  ativo
                    ? "border-[var(--ks-brand-600)] bg-[var(--ks-brand-600)] text-white"
                    : "border-[var(--ks-color-border-subtle)] bg-white text-[var(--ks-color-text-secondary)] hover:border-[var(--ks-brand-500)]"
                }`}
              >
                {f.rotulo} <span className={`ks-num ml-1 ${ativo ? "text-white/80" : "text-[var(--ks-color-text-soft)]"}`}>{contagem[f.valor]}</span>
              </button>
            );
          })}
        </div>
        <div className="relative w-full sm:w-72">
          <Search size={15} className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-[var(--ks-color-text-soft)]" />
          <input
            value={busca}
            onChange={(e) => setBusca(e.target.value)}
            placeholder="Buscar pedido, pessoa ou e-mail"
            className="h-10 w-full rounded-xl border border-[var(--ks-color-border-subtle)] bg-white pl-9 pr-3 text-sm outline-none focus:border-[var(--ks-brand-500)]"
          />
        </div>
      </div>

      <section className="overflow-hidden rounded-2xl border border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-elevated)] shadow-[var(--ks-shadow-subtle)]">
        <div className="hidden grid-cols-[110px_minmax(0,1fr)_minmax(0,1fr)_minmax(0,1.1fr)_minmax(0,1fr)] gap-4 border-b border-[var(--ks-color-border-subtle)] px-5 py-3 text-[11px] font-bold uppercase tracking-[0.12em] text-[var(--ks-color-text-soft)] xl:grid">
          <span>Pedido</span>
          <span>Comprador</span>
          <span>Produto</span>
          <span>Entrega</span>
          <span />
        </div>
        {visiveis.length === 0 ? (
          <div className="flex flex-col items-center gap-2 px-6 py-14 text-center">
            <p className="text-sm font-semibold text-[var(--ks-color-text-primary)]">
              {dados.entregas.length === 0 ? "Nenhuma entrega ainda." : "Nenhuma entrega neste filtro."}
            </p>
            {dados.entregas.length === 0 ? (
              <p className="max-w-sm text-xs leading-5 text-[var(--ks-color-text-muted)]">
                Quando alguém comprar um produto digital, a entrega sai sozinha e aparece aqui.
              </p>
            ) : null}
          </div>
        ) : (
          <ul className="px-2 sm:px-3">
            {visiveis.map((entrega) => {
              const selo = SELO_DO_EMAIL[entrega.email.situacao];
              const motivo = motivoDoEmail(entrega.email.erro);
              return (
                <li key={entrega.pedidoId} className={FIO_DA_LINHA}>
                  <div className="grid grid-cols-1 items-center gap-3 rounded-xl px-2 py-3 xl:grid-cols-[110px_minmax(0,1fr)_minmax(0,1fr)_minmax(0,1.1fr)_minmax(0,1fr)] xl:gap-4">
                    <span>
                      <Link href={`/dashboard/orders/${entrega.pedidoId}`} className="text-sm font-bold text-[var(--ks-color-text-primary)] hover:underline">
                        {entrega.numero ? `#${entrega.numero}` : "Pedido"}
                      </Link>
                      <span className="block text-xs text-[var(--ks-color-text-muted)]">
                        {entrega.numeroNaLoja ? `loja #${entrega.numeroNaLoja} · ` : ""}
                        {dataCurta(entrega.data)}
                      </span>
                    </span>
                    <span className="min-w-0">
                      <span className="block truncate text-sm font-semibold text-[var(--ks-color-text-primary)]">{entrega.cliente}</span>
                      <span className="block truncate text-xs text-[var(--ks-color-text-muted)]">{entrega.emailDoCliente || "sem e-mail no cadastro"}</span>
                    </span>
                    <span className="min-w-0">
                      <span className="block truncate text-sm text-[var(--ks-color-text-primary)]">{entrega.produtos.join(", ") || "Produto digital"}</span>
                      <span className="block text-xs text-[var(--ks-color-text-muted)]">
                        {SELO_DO_ACESSO[entrega.acesso]} · {entrega.itens} {entrega.itens === 1 ? "item" : "itens"}
                      </span>
                      {textoDaEspera(entrega) ? <span className="block text-xs font-semibold text-[#a16207]">{textoDaEspera(entrega)}</span> : null}
                      {entrega.pausadoPeloFreio ? (
                        <span className="mt-0.5 flex items-center gap-1 text-xs font-bold text-[#c2263f]">
                          <ShieldAlert size={13} />
                          Pausado: aberto em lugares demais
                        </span>
                      ) : null}
                    </span>
                    <span className="min-w-0">
                      <span className={`inline-block rounded-full px-2.5 py-0.5 text-xs font-bold ${selo.classe}`}>{selo.texto}</span>
                      <span className="mt-0.5 block truncate text-xs text-[var(--ks-color-text-muted)]">
                        {entrega.email.destino ? `para ${entrega.email.destino}` : "sem e-mail para mandar"}
                        {entrega.email.enviadoEm ? ` · ${dataCurta(entrega.email.enviadoEm)}` : ""}
                      </span>
                      {motivo ? <span className="block text-xs text-[#c2263f]">{motivo}</span> : null}
                    </span>
                    <span className="flex flex-wrap items-center gap-1.5 xl:justify-end">
                      {dados.podeEditar && entrega.pausadoPeloFreio ? (
                        <button
                          type="button"
                          disabled={Boolean(ocupado)}
                          onClick={() =>
                            setConfirmacao({
                              titulo: "Reativar o acesso?",
                              texto:
                                "O freio pausou porque este acesso foi aberto em muitos lugares diferentes. Reative se você conhece o comprador: a contagem recomeça do zero, os links antigos deixam de valer e ele recebe um e-mail novo.",
                              confirmar: "Reativar",
                              aoConfirmar: () => agir(entrega.pedidoId, "reativar"),
                            })
                          }
                          className="inline-flex h-8 items-center gap-1 rounded-lg px-2.5 text-xs font-semibold text-[#c2263f] hover:bg-[color:rgba(225,58,88,0.08)]"
                        >
                          {ocupado === `${entrega.pedidoId}:reativar` ? <Loader2 size={14} className="animate-spin" /> : <Unlock size={14} />}
                          Reativar
                        </button>
                      ) : null}
                      {dados.podeEditar && entrega.acesso !== "fechado" ? (
                        <>
                          <button
                            type="button"
                            disabled={Boolean(ocupado)}
                            onClick={() =>
                              setReenviando({ pedidoId: entrega.pedidoId, email: entrega.email.destino || entrega.emailDoCliente || "" })
                            }
                            className="inline-flex h-8 items-center gap-1 rounded-lg px-2.5 text-xs font-semibold text-[var(--ks-color-text-secondary)] hover:bg-[var(--ks-color-bg-hover)]"
                          >
                            <Mail size={14} />
                            Reenviar
                          </button>
                          <button
                            type="button"
                            disabled={Boolean(ocupado)}
                            onClick={() => void agir(entrega.pedidoId, "link")}
                            className="inline-flex h-8 items-center gap-1 rounded-lg px-2.5 text-xs font-semibold text-[var(--ks-color-text-secondary)] hover:bg-[var(--ks-color-bg-hover)]"
                          >
                            {ocupado === `${entrega.pedidoId}:link` ? (
                              <Loader2 size={14} className="animate-spin" />
                            ) : linkCopiado === entrega.pedidoId ? (
                              <Check size={14} />
                            ) : (
                              <Copy size={14} />
                            )}
                            {linkCopiado === entrega.pedidoId ? "Copiado" : "Copiar link"}
                          </button>
                        </>
                      ) : null}
                    </span>
                  </div>
                  {reenviando?.pedidoId === entrega.pedidoId ? (
                    <div className="mx-2 mb-3 flex flex-wrap items-center gap-2 rounded-xl bg-[var(--ks-color-bg-inset)] px-3 py-2.5">
                      <span className="text-sm text-[var(--ks-color-text-primary)]">Mandar para</span>
                      <input
                        className="h-9 min-w-[240px] flex-1 rounded-lg border border-[var(--ks-color-border-subtle)] bg-white px-3 text-sm"
                        type="email"
                        value={reenviando.email}
                        onChange={(e) => setReenviando({ ...reenviando, email: e.target.value })}
                      />
                      <button type="button" className="ks-button ks-button-soft" onClick={() => setReenviando(null)}>
                        Cancelar
                      </button>
                      <button
                        type="button"
                        className="ks-button ks-button-primary"
                        disabled={Boolean(ocupado)}
                        onClick={() => void agir(entrega.pedidoId, "reenviar", reenviando.email)}
                      >
                        {ocupado === `${entrega.pedidoId}:reenviar` ? <Loader2 size={15} className="animate-spin" /> : <Mail size={15} />}
                        Reenviar e-mail
                      </button>
                    </div>
                  ) : null}
                </li>
              );
            })}
          </ul>
        )}
      </section>

      {dados.esperando.length ? (
        <section className="overflow-hidden rounded-2xl border border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-elevated)] shadow-[var(--ks-shadow-subtle)]">
          <div className="border-b border-[var(--ks-color-border-subtle)] px-5 py-3">
            <h2 className="text-[15px] font-extrabold text-[var(--ks-color-text-primary)]">Esperando pagamento</h2>
            <p className="text-xs text-[var(--ks-color-text-muted)]">
              A entrega sai sozinha quando o pedido fica pago. Recebeu por fora? Registre o pagamento no pedido, ou libere aqui.
            </p>
          </div>
          <ul className="px-2 sm:px-3">
            {dados.esperando.map((pedido) => (
              <li key={pedido.pedidoId} className={FIO_DA_LINHA}>
                <div className="flex flex-wrap items-center justify-between gap-3 rounded-xl px-2 py-3">
                  <span className="min-w-0">
                    <Link href={`/dashboard/orders/${pedido.pedidoId}`} className="text-sm font-bold text-[var(--ks-color-text-primary)] hover:underline">
                      {pedido.numero ? `#${pedido.numero}` : "Pedido"}
                    </Link>
                    <span className="ml-2 text-sm text-[var(--ks-color-text-secondary)]">{pedido.cliente}</span>
                    <span className="block truncate text-xs text-[var(--ks-color-text-muted)]">
                      {pedido.produtos.join(", ")} · {moeda(pedido.total)} · {dataCurta(pedido.data)}
                    </span>
                  </span>
                  {dados.podeEditar ? (
                    <button
                      type="button"
                      className="ks-button ks-button-soft"
                      disabled={Boolean(ocupado)}
                      onClick={() =>
                        setConfirmacao({
                          titulo: "Liberar sem o pagamento registrado?",
                          texto: "O comprador recebe o acesso agora. Use quando o pagamento já entrou por fora (dinheiro, transferência).",
                          confirmar: "Liberar agora",
                          aoConfirmar: () => agir(pedido.pedidoId, "liberar"),
                        })
                      }
                    >
                      {ocupado === `${pedido.pedidoId}:liberar` ? <Loader2 size={15} className="animate-spin" /> : <Unlock size={15} />}
                      Liberar agora
                    </button>
                  ) : null}
                </div>
              </li>
            ))}
          </ul>
        </section>
      ) : null}

      <p className="flex items-center gap-2 text-xs text-[var(--ks-color-text-muted)]">
        <MessageCircle size={14} />
        &quot;Copiar link&quot; gera um link de entrega para mandar pelo WhatsApp. Ele abre só este pedido, nunca o portal do cliente.
      </p>

      <CaixaDeConfirmacao pedido={confirmacao} ocupado={Boolean(ocupado)} aoFechar={() => setConfirmacao(null)} />
    </div>
  );
}
