"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { FileUp, KeyRound, Loader2, Plus, Trash2 } from "lucide-react";

import { pedirDigitais } from "@/components/digitais/comum";
import { AreaDeTexto, FIO_DA_LINHA } from "@/components/ui/folha-de-ajustes";

/*
 * Os códigos e licenças do produto: quantos sobram, colar ou importar mais,
 * e quem levou cada um. O código inteiro nunca volta para a tela depois de
 * salvo (só o final dele); quem comprou vê o seu na área de membros.
 */

type CodigoNaTela = {
  id: string;
  mascarado: string;
  situacao: "livre" | "entregue";
  entregueEm: string | null;
  cliente: string | null;
  pedido: number | null;
  criadoEm: string;
};

type Resposta = {
  livres: number;
  entregues: number;
  esperando: number;
  reservados: number;
  aVenda: number;
  avisarCom: number;
  situacao: "esgotado" | "acabando" | "ok";
  codigos: CodigoNaTela[];
};

const data = (iso: string | null) => (iso ? new Date(iso).toLocaleDateString("pt-BR", { timeZone: "America/Sao_Paulo" }) : "");

export function CodigosDoProduto({
  produtoId,
  podeEditar,
  aoAvisar,
}: {
  produtoId: string;
  podeEditar: boolean;
  aoAvisar: (tom: "bom" | "ruim" | "atencao", texto: string) => void;
}) {
  const [dados, setDados] = useState<Resposta | null>(null);
  const [texto, setTexto] = useState("");
  const [salvando, setSalvando] = useState(false);
  const [tirando, setTirando] = useState<string | null>(null);
  const arquivoRef = useRef<HTMLInputElement>(null);

  const carregar = useCallback(
    () =>
      pedirDigitais<Resposta>(`/api/digitais/produtos/${produtoId}/codigos`)
        .then((resposta) => setDados(resposta))
        .catch((e: unknown) => aoAvisar("ruim", e instanceof Error ? e.message : "Não foi possível ler os códigos.")),
    [produtoId, aoAvisar]
  );

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

  const adicionar = async () => {
    if (!texto.trim() || salvando) return;
    setSalvando(true);
    try {
      const r = await pedirDigitais<{ adicionados: number; repetidos: number; grandesDemais: number; entregues: number }>(
        `/api/digitais/produtos/${produtoId}/codigos`,
        { method: "POST", body: JSON.stringify({ texto }) }
      );
      const partes = [`${r.adicionados} ${r.adicionados === 1 ? "código adicionado" : "códigos adicionados"}`];
      if (r.repetidos) partes.push(`${r.repetidos} ${r.repetidos === 1 ? "repetido ficou" : "repetidos ficaram"} de fora`);
      if (r.grandesDemais) partes.push(`${r.grandesDemais} com mais de 500 letras ${r.grandesDemais === 1 ? "ficou" : "ficaram"} de fora`);
      if (r.entregues) partes.push(`${r.entregues} ${r.entregues === 1 ? "compra que esperava já recebeu" : "compras que esperavam já receberam"}`);
      aoAvisar(r.adicionados ? "bom" : "atencao", `${partes.join(" · ")}.`);
      if (r.adicionados) setTexto("");
      await carregar();
    } catch (e) {
      aoAvisar("ruim", e instanceof Error ? e.message : "Não foi possível adicionar.");
    } finally {
      setSalvando(false);
    }
  };

  const tirar = async (codigo: CodigoNaTela) => {
    if (tirando) return;
    setTirando(codigo.id);
    try {
      await pedirDigitais(`/api/digitais/produtos/${produtoId}/codigos?codigo=${encodeURIComponent(codigo.id)}`, { method: "DELETE" });
      aoAvisar("bom", `O código ${codigo.mascarado} saiu da lista.`);
      await carregar();
    } catch (e) {
      aoAvisar("ruim", e instanceof Error ? e.message : "Não foi possível tirar.");
    } finally {
      setTirando(null);
    }
  };

  const importar = (arquivo: File) => {
    if (arquivo.size > 2 * 1024 * 1024) {
      aoAvisar("ruim", "A planilha passou de 2 MB. Divida em partes.");
      return;
    }
    const leitor = new FileReader();
    leitor.onload = () => {
      const conteudo = String(leitor.result || "");
      setTexto((atual) => (atual.trim() ? `${atual.trim()}\n${conteudo}` : conteudo));
    };
    leitor.onerror = () => aoAvisar("ruim", "Não foi possível ler o arquivo.");
    leitor.readAsText(arquivo);
  };

  if (!dados) {
    return (
      <div className="flex items-center gap-2 py-4 text-sm text-[var(--ks-color-text-muted)]">
        <Loader2 size={15} className="animate-spin" />
        Lendo os códigos…
      </div>
    );
  }

  const linhasNoTexto = texto.split(/\r?\n/).filter((l) => l.trim()).length;

  return (
    <div className="py-2">
      <div className="flex flex-wrap items-center gap-x-5 gap-y-2 py-2">
        <span className="flex items-center gap-2 text-sm">
          <KeyRound size={16} className="text-[var(--ks-brand-600)]" />
          <span className="ks-num font-extrabold text-[var(--ks-color-text-primary)]">{dados.livres}</span>
          <span className="text-[var(--ks-color-text-muted)]">{dados.livres === 1 ? "livre" : "livres"}</span>
        </span>
        <span className="text-sm text-[var(--ks-color-text-muted)]">
          <span className="ks-num font-bold text-[var(--ks-color-text-primary)]">{dados.entregues}</span> {dados.entregues === 1 ? "entregue" : "entregues"}
        </span>
        {dados.reservados > 0 ? (
          <span className="text-sm text-[var(--ks-color-text-muted)]">
            <span className="ks-num font-bold text-[var(--ks-color-text-primary)]">{dados.reservados}</span>{" "}
            {dados.reservados === 1 ? "guardado para a pré-venda" : "guardados para a pré-venda"}
          </span>
        ) : null}
        {dados.situacao !== "ok" ? (
          <span
            className={`rounded-full px-2.5 py-1 text-xs font-bold ${
              dados.situacao === "esgotado" ? "bg-[color:rgba(225,58,88,0.12)] text-[#c2263f]" : "bg-[color:rgba(234,179,8,0.14)] text-[#a16207]"
            }`}
          >
            {dados.situacao === "esgotado" ? "Esgotado: a loja não vende sem código" : `Acabando: restam ${dados.aVenda}`}
          </span>
        ) : null}
      </div>
      {dados.reservados > 0 ? (
        <p className="pb-2 text-[13px] leading-5 text-[var(--ks-color-text-muted)]">
          {dados.reservados === 1
            ? "Uma compra da pré-venda leva um código da lista no dia do lançamento. Até lá ele fica guardado e não entra na venda."
            : `${dados.reservados} compras da pré-venda levam um código da lista no dia do lançamento. Até lá eles ficam guardados e não entram na venda.`}
        </p>
      ) : null}
      {dados.esperando > 0 ? (
        <p className="rounded-xl bg-[color:rgba(225,58,88,0.08)] px-3.5 py-2.5 text-sm font-semibold text-[#c2263f]">
          {dados.esperando} {dados.esperando === 1 ? "compra está esperando código" : "compras estão esperando código"}. Adicione abaixo: elas recebem na hora, com aviso por e-mail.
        </p>
      ) : null}

      {podeEditar ? (
        <div className="mt-3 space-y-2">
          <label className="ks-input-label" htmlFor={`codigos-${produtoId}`}>
            Adicionar códigos
          </label>
          <AreaDeTexto
            id={`codigos-${produtoId}`}
            value={texto}
            rows={5}
            maxLength={2_000_000}
            placeholder={"Um código por linha. Ex.:\nAURO-7K2M-Q9FX\nAURO-3PZT-88LA"}
            onChange={(e) => setTexto(e.target.value)}
            className="font-mono text-[13px]"
          />
          <div className="flex flex-wrap items-center gap-2">
            <button type="button" className="ks-button ks-button-primary ks-button-sm" disabled={salvando || !texto.trim()} onClick={() => void adicionar()}>
              {salvando ? <Loader2 size={15} className="animate-spin" /> : <Plus size={15} />}
              {linhasNoTexto > 1 ? `Adicionar ${linhasNoTexto} códigos` : "Adicionar"}
            </button>
            <button type="button" className="ks-button ks-button-soft ks-button-sm" onClick={() => arquivoRef.current?.click()}>
              <FileUp size={15} />
              Importar planilha (.csv ou .txt)
            </button>
            <span className="text-xs text-[var(--ks-color-text-muted)]">Repetidos ficam de fora sozinhos. Da planilha vale a primeira coluna.</span>
            <input
              ref={arquivoRef}
              type="file"
              accept=".csv,.txt,text/csv,text/plain"
              className="hidden"
              onChange={(evento) => {
                const arquivo = evento.target.files?.[0];
                evento.target.value = "";
                if (arquivo) importar(arquivo);
              }}
            />
          </div>
        </div>
      ) : null}

      {dados.codigos.length ? (
        <ul className="mt-4 max-h-80 overflow-y-auto">
          {dados.codigos.map((codigo) => (
            <li key={codigo.id} className={`flex items-center gap-3 py-2.5 ${FIO_DA_LINHA}`}>
              <span className="w-28 shrink-0 font-mono text-[13px] font-semibold text-[var(--ks-color-text-primary)]">{codigo.mascarado}</span>
              <span className="min-w-0 flex-1 truncate text-xs text-[var(--ks-color-text-muted)]">
                {codigo.situacao === "livre"
                  ? `Livre · adicionado em ${data(codigo.criadoEm)}`
                  : `Entregue${codigo.cliente ? ` para ${codigo.cliente}` : ""}${codigo.pedido ? ` · pedido #${codigo.pedido}` : ""} · ${data(codigo.entregueEm)}`}
              </span>
              <span
                className={`shrink-0 rounded-full px-2 py-0.5 text-[11px] font-bold ${
                  codigo.situacao === "livre" ? "bg-[color:rgba(14,158,112,0.12)] text-[var(--ks-emerald)]" : "bg-[var(--ks-color-bg-inset)] text-[var(--ks-color-text-muted)]"
                }`}
              >
                {codigo.situacao === "livre" ? "Livre" : "Entregue"}
              </span>
              {podeEditar && codigo.situacao === "livre" ? (
                <button
                  type="button"
                  aria-label={`Tirar o código ${codigo.mascarado}`}
                  disabled={Boolean(tirando)}
                  onClick={() => void tirar(codigo)}
                  className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-[var(--ks-color-text-soft)] hover:bg-[color:rgba(214,48,76,0.08)] hover:text-[var(--ks-color-status-danger)] disabled:opacity-40"
                >
                  {tirando === codigo.id ? <Loader2 size={14} className="animate-spin" /> : <Trash2 size={14} />}
                </button>
              ) : (
                <span className="h-8 w-8 shrink-0" aria-hidden />
              )}
            </li>
          ))}
        </ul>
      ) : (
        <p className="mt-3 text-sm text-[var(--ks-color-text-muted)]">Nenhum código ainda. Cada compra leva um, sem repetir.</p>
      )}
    </div>
  );
}
