"use client";

import Link from "next/link";
import { useCallback, useEffect, useState } from "react";
import {
  ArrowRight,
  Award,
  BadgeCheck,
  CreditCard,
  FileDown,
  PlayCircle,
  Hand,
  KeyRound,
  Link2,
  Loader2,
  MessageSquare,
  MonitorUp,
  Radio,
  ShoppingBag,
  Ticket,
  Users,
  Video,
} from "lucide-react";

import { Anel, CabecalhoDoPainel, Etiqueta, Eyebrow, FaixaDeAcao, NumeroAnimado, Opcao, Painel, Preco } from "@/components/assinatura/primitivos";
import { Aviso } from "@/components/ui/aviso";
import type { CompraDeLive, PacoteDeLive } from "@/lib/live/servidor/compras";
import { pessoasDoGratis, semLimiteDePessoas } from "@/lib/live/sala";
import type { SaldoDeLives } from "@/lib/live/servidor/lives";

export type PainelDaLive = {
  saldo: SaldoDeLives;
  pacotes: PacoteDeLive[];
  regras: { gratisPorMes: number; gratisPessoas: number; validadeDias: number; vendasAbertas: boolean };
  vendasAbertas: boolean;
  bloqueioDeCompra: string | null;
  compras: CompraDeLive[];
  podeComprar: boolean;
};

class ErroDaAba extends Error {
  readonly status: number;
  readonly motivo: string | null;
  constructor(mensagem: string, status: number, motivo: string | null) {
    super(mensagem);
    this.status = status;
    this.motivo = motivo;
  }
}

async function pedir<T>(url: string, init?: RequestInit): Promise<T> {
  const resposta = await fetch(url, { ...init, headers: { "content-type": "application/json" }, cache: "no-store" });
  const corpo = (await resposta.json().catch(() => null)) as (T & { error?: string; motivo?: string }) | null;
  if (!resposta.ok) throw new ErroDaAba(corpo?.error || "Não foi possível carregar agora.", resposta.status, corpo?.motivo ?? null);
  return corpo as T;
}

const moeda = (valor: number) => new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(Number.isFinite(valor) ? valor : 0);
const plural = (n: number, um: string, varios: string) => `${n} ${n === 1 ? um : varios}`;
const dataCurta = (iso: string) => new Date(iso).toLocaleDateString("pt-BR", { day: "2-digit", month: "short", year: "numeric" });

const STATUS_DA_COMPRA: Record<string, { rotulo: string; cor: string }> = {
  pendente: { rotulo: "Aguardando pagamento", cor: "bg-violet-500/10 text-violet-700" },
  aprovada: { rotulo: "Paga", cor: "bg-emerald-500/10 text-emerald-700" },
  recusada: { rotulo: "Recusada", cor: "bg-rose-500/10 text-rose-700" },
  cancelada: { rotulo: "Cancelada", cor: "bg-slate-500/10 text-slate-600" },
  reembolsada: { rotulo: "Reembolsada", cor: "bg-slate-500/10 text-slate-600" },
  contestada: { rotulo: "Contestada", cor: "bg-rose-500/10 text-rose-700" },
};

const O_QUE_VEM_NA_CRIACAO = [
  { Icone: PlayCircle, texto: "Conteúdo em vídeo com área de membros com a cara da sua loja" },
  { Icone: FileDown, texto: "Arquivos para baixar, com link seguro" },
  { Icone: Link2, texto: "Links de acesso e grupos" },
  { Icone: KeyRound, texto: "Códigos e licenças, um por compra" },
  { Icone: Award, texto: "Certificado de conclusão" },
  { Icone: BadgeCheck, texto: "Entrega na hora, por e-mail e na área de membros" },
];

const O_PODER_DA_LIVE = [
  { Icone: Video, titulo: "Sala como a do Meet", texto: "Lives de venda na loja e reuniões com fornecedores, clientes e a equipe, com link curto pronto para mandar." },
  { Icone: Hand, titulo: "Quem fala", texto: "Todo mundo fala, ou quem assiste levanta a mão e você libera o microfone na hora." },
  { Icone: MonitorUp, titulo: "Tela, caneta e ponteiro", texto: "Mostre a tela e destaque o que importa: ponteiro laser, caneta e marca-texto." },
  { Icone: MessageSquare, titulo: "Mensagens na hora", texto: "Aberto, só perguntas para você ou só avisos. Com recado fixado." },
  { Icone: Ticket, titulo: "Cupom e produto na tela", texto: "Um toque e o cupom ou o produto aparece em cima do vídeo, como no TikTok Shop." },
  { Icone: Radio, titulo: "Gravação do seu jeito", texto: "Só a tela e a câmera, ou a sala inteira. Fica na área de membros ou só para você baixar." },
];

/*
 * A aba "Produtos Digitais" da Assinatura: a criação de produtos digitais
 * (grátis por enquanto) e o KtaloguLive, com as lives grátis do mês e os
 * pacotes para mais lives ou mais pessoas, pagos no Mercado Pago da Ktalogu.
 */
export function AbaProdutosDigitais({ aoFechar }: { aoFechar?: (motivo: string | null) => void }) {
  const [painel, setPainel] = useState<PainelDaLive | null>(null);
  const [erro, setErro] = useState<string | null>(null);
  const [escolhidoId, setEscolhidoId] = useState<string | null>(null);
  const [comprando, setComprando] = useState(false);
  const [compra, setCompra] = useState<CompraDeLive | null>(null);
  const [conferindo, setConferindo] = useState(false);

  const carregar = useCallback(async () => {
    try {
      setPainel(await pedir<PainelDaLive>("/api/live/painel"));
    } catch (e) {
      if (e instanceof ErroDaAba && (e.status === 403 || e.status === 402)) aoFechar?.(e.motivo);
      setErro(e instanceof Error ? e.message : "Não foi possível carregar.");
    }
  }, [aoFechar]);

  useEffect(() => {
    let vivo = true;
    pedir<PainelDaLive>("/api/live/painel")
      .then((json) => {
        if (vivo) setPainel(json);
      })
      .catch((e: unknown) => {
        if (!vivo) return;
        if (e instanceof ErroDaAba && (e.status === 403 || e.status === 402)) aoFechar?.(e.motivo);
        setErro(e instanceof Error ? e.message : "Não foi possível carregar.");
      });
    return () => {
      vivo = false;
    };
  }, [aoFechar]);

  /* Voltou da página de pagamento: confere na hora, sem esperar o aviso. */
  useEffect(() => {
    const compraId = new URLSearchParams(window.location.search).get("compra");
    if (!compraId) return;
    let voltas = 0;
    let parar = false;
    const conferir = async () => {
      voltas += 1;
      if (voltas === 1) setConferindo(true);
      try {
        const json = await pedir<{ compra: CompraDeLive }>(`/api/live/compras/${compraId}`);
        if (parar) return;
        setCompra(json.compra);
        if (json.compra.status !== "pendente" || voltas >= 20) {
          setConferindo(false);
          void carregar();
          return;
        }
      } catch {
        if (voltas >= 3) {
          setConferindo(false);
          return;
        }
      }
      if (!parar) setTimeout(() => void conferir(), 3000);
    };
    const primeira = setTimeout(() => void conferir(), 0);
    return () => {
      clearTimeout(primeira);
      parar = true;
    };
  }, [carregar]);

  const pacotes = painel?.pacotes ?? [];
  const escolhido = pacotes.find((p) => p.id === escolhidoId) ?? pacotes.find((p) => p.destaque) ?? pacotes[0] ?? null;

  const comprar = async () => {
    if (!escolhido) return;
    setComprando(true);
    setErro(null);
    try {
      const json = await pedir<{ checkoutUrl: string }>("/api/live/compras", { method: "POST", body: JSON.stringify({ pacoteId: escolhido.id }) });
      window.location.assign(json.checkoutUrl);
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível abrir o pagamento.");
      setComprando(false);
    }
  };

  const saldo = painel?.saldo;
  const restantesDosPacotes = saldo?.pacotes.reduce((soma, p) => soma + p.restantes, 0) ?? 0;

  return (
    <div className="space-y-6">
      {erro ? (
        <Aviso tom="ruim" aoFechar={() => setErro(null)}>
          {erro}
        </Aviso>
      ) : null}

      {compra ? (
        compra.status === "aprovada" ? (
          <Aviso tom="bom" titulo="Pagamento aprovado" aoFechar={() => setCompra(null)}>
            {plural(compra.lives, "live", "lives")} com até {compra.pessoas} pessoas liberadas
            {compra.valida_ate ? ` até ${dataCurta(compra.valida_ate)}` : ""}. Escolha o pacote na live, em Tamanho da sala.
          </Aviso>
        ) : compra.status === "pendente" ? (
          <Aviso
            tom="neutro"
            titulo={conferindo ? "Conferindo o pagamento…" : "Pagamento em análise"}
            acao={
              compra.checkout_url && !conferindo ? (
                <a href={compra.checkout_url} className="ks-button ks-button-soft ks-button-sm">
                  Continuar pagamento
                </a>
              ) : undefined
            }
          >
            {conferindo ? "Assim que o pagamento for confirmado, as lives entram na sua conta." : "Pix pode levar alguns minutos. As lives entram sozinhas quando o pagamento for confirmado."}
          </Aviso>
        ) : (
          <Aviso tom="ruim" titulo="O pagamento não foi aprovado" aoFechar={() => setCompra(null)}>
            {compra.mp_status_detalhe === "valor_divergente" ? "O valor pago não confere com o do pacote. Fale com o suporte." : "Tente de novo com outra forma de pagamento. Nenhum valor foi cobrado."}
          </Aviso>
        )
      ) : null}

      {/* A criação de produtos digitais: grátis por enquanto. */}
      <Painel>
        <div className="grid gap-6 p-6 lg:grid-cols-[minmax(0,1fr)_minmax(0,1.15fr)] lg:items-center">
          <div>
            <div className="flex flex-wrap items-center gap-3">
              <Eyebrow>Incluído no seu plano</Eyebrow>
              <span className="rounded-full bg-emerald-500/10 px-2.5 py-1 text-[11px] font-bold text-emerald-700">Grátis por enquanto</span>
            </div>
            <h2 className="mt-2 text-2xl font-extrabold tracking-tight text-[var(--ks-color-text-primary)]">Criação de Produtos Digitais</h2>
            <p className="mt-2 max-w-md text-sm leading-6 text-[var(--ks-color-text-muted)]">
              Venda conteúdo em vídeo, arquivos, links e códigos na sua loja, com entrega na hora e uma área de membros com a sua cara. Aproveite: enquanto estiver
              grátis, é só usar.
            </p>
            <Link href="/dashboard/digitais" className="ks-button ks-button-soft mt-4">
              Abrir Produtos digitais
              <ArrowRight size={16} />
            </Link>
          </div>
          <ul className="grid gap-x-6 gap-y-3 sm:grid-cols-2">
            {O_QUE_VEM_NA_CRIACAO.map(({ Icone, texto }) => (
              <li key={texto} className="flex items-start gap-2.5 text-sm text-[var(--ks-color-text-secondary)]">
                <span className="mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-lg bg-[var(--ks-brand-50)] text-[var(--ks-brand-600)]">
                  <Icone size={14} />
                </span>
                {texto}
              </li>
            ))}
          </ul>
        </div>
      </Painel>

      {/* KtaloguLive: o que é e o poder dela. */}
      <Painel atraso={0.04}>
        <div className="border-b border-[var(--ks-color-border-subtle)] p-6">
          <div className="flex flex-wrap items-center gap-3">
            <span className="inline-flex items-center gap-1.5 rounded-md bg-[#ff2d46] px-2 py-1 text-[11px] font-extrabold tracking-[0.12em] text-white">
              <span className="h-1.5 w-1.5 animate-pulse rounded-full bg-white" /> AO VIVO
            </span>
            <Eyebrow>KtaloguLive</Eyebrow>
          </div>
          <h2 className="mt-2 text-2xl font-extrabold tracking-tight text-[var(--ks-color-text-primary)]">Transmissões ao vivo para vender e para conversar, dentro do Ktalogu</h2>
          <p className="mt-2 max-w-3xl text-sm leading-6 text-[var(--ks-color-text-muted)]">
            Faça live de venda na loja virtual (paga, grátis com cadastro para juntar contatos, ou aberta), passe os produtos na tela como no TikTok Shop, ou
            marque uma reunião com fornecedor e mande o link curto. Tudo no mesmo sistema da sua gestão: o dinheiro, os contatos e as gravações ficam com você.
          </p>
        </div>
        <ul className="grid gap-px bg-[var(--ks-color-border-subtle)] sm:grid-cols-2 lg:grid-cols-3">
          {O_PODER_DA_LIVE.map(({ Icone, titulo, texto }) => (
            <li key={titulo} className="flex gap-3 bg-[var(--ks-color-bg-elevated)] p-5">
              <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-[var(--ks-brand-50)] text-[var(--ks-brand-600)]">
                <Icone size={18} />
              </span>
              <span>
                <span className="block text-sm font-bold text-[var(--ks-color-text-primary)]">{titulo}</span>
                <span className="mt-0.5 block text-xs leading-5 text-[var(--ks-color-text-muted)]">{texto}</span>
              </span>
            </li>
          ))}
        </ul>
        <div className="flex flex-col gap-4 border-t border-[var(--ks-color-border-subtle)] p-6 sm:flex-row sm:items-start">
          <span className="flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-[var(--ks-brand-600)] text-white">
            <ShoppingBag size={20} />
          </span>
          <div>
            <p className="text-base font-extrabold text-[var(--ks-color-text-primary)]">Liveshop: venda ao vivo como no TikTok Shop e na Shopee</p>
            <p className="mt-1 max-w-3xl text-sm leading-6 text-[var(--ks-color-text-muted)]">
              Escolha os produtos da live e ela aparece nas páginas deles enquanto estiver no ar. O cliente assiste ali mesmo, num player que continua tocando
              enquanto ele navega pela loja. Você passa os produtos na tela com um toque e o botão “Comprar” leva direto ao produto. Lançamento, queima de
              estoque, demonstração de personalizados: tudo ao vivo.
            </p>
          </div>
        </div>
      </Painel>

      {!painel || !saldo ? (
        <div className="flex justify-center py-12">
          <Loader2 className="h-7 w-7 animate-spin text-[var(--ks-color-primary)]" />
        </div>
      ) : (
        <>
          <div className="grid gap-6 lg:grid-cols-12 lg:items-start">
            <Painel className="lg:col-span-5 xl:col-span-4" atraso={0.08}>
              <div className="p-6">
                <Eyebrow>Lives grátis deste mês</Eyebrow>
                <div className="mt-5 flex items-center gap-5">
                  <Anel fracao={saldo.ilimitado ? 1 : saldo.gratis_por_mes > 0 ? saldo.gratis_restantes / saldo.gratis_por_mes : 0} tamanho={104} espessura={10}>
                    {saldo.ilimitado ? (
                      <span className="text-3xl font-extrabold text-[var(--ks-color-text-primary)]">∞</span>
                    ) : (
                      <>
                        <NumeroAnimado valor={saldo.gratis_restantes} className="text-3xl font-extrabold text-[var(--ks-color-text-primary)]" />
                        <span className="mt-0.5 text-[10px] font-bold uppercase tracking-[0.12em] text-[var(--ks-color-text-soft)]">de {saldo.gratis_por_mes}</span>
                      </>
                    )}
                  </Anel>
                  <div className="min-w-0 text-sm leading-6 text-[var(--ks-color-text-muted)]">
                    <p className="text-lg font-extrabold leading-tight text-[var(--ks-color-text-primary)]">
                      {saldo.ilimitado ? "transmissões sem limite" : saldo.gratis_restantes === 1 ? "live grátis sobrando" : "lives grátis sobrando"}
                    </p>
                    <p className="flex items-center gap-1.5">
                      <Users size={14} /> {pessoasDoGratis(saldo)}{semLimiteDePessoas(saldo) ? "" : " cada"}
                    </p>
                    {restantesDosPacotes ? <p>+ {plural(restantesDosPacotes, "live de pacote", "lives de pacote")}</p> : <p>Renova todo dia 1º.</p>}
                  </div>
                </div>
              </div>
              {saldo.pacotes.length ? (
                <ul className="border-t border-[var(--ks-color-border-subtle)]">
                  {saldo.pacotes.map((p) => (
                    <li key={p.compra_id} className="flex items-center justify-between gap-3 px-6 py-3 text-sm">
                      <span className="min-w-0">
                        <span className="block font-semibold text-[var(--ks-color-text-primary)]">{p.nome}</span>
                        <span className="block text-xs text-[var(--ks-color-text-soft)]">
                          até {p.pessoas} pessoas · vale até {dataCurta(p.valida_ate)}
                        </span>
                      </span>
                      <span className="ks-num shrink-0 font-bold text-[var(--ks-color-text-primary)]">
                        {p.restantes}/{p.lives}
                      </span>
                    </li>
                  ))}
                </ul>
              ) : null}
              <p className="border-t border-[var(--ks-color-border-subtle)] px-6 py-3 text-xs text-[var(--ks-color-text-soft)]">
                A vaga só é gasta quando você clica em “Entrar ao vivo”. Voltar ao ar na mesma live não gasta outra.
              </p>
            </Painel>

            <Painel className="lg:col-span-7 xl:col-span-8" atraso={0.12}>
              <CabecalhoDoPainel
                titulo="Comprar KtaloguLive"
                texto={`Mais lives e salas maiores. Cada pacote vale ${painel.regras.validadeDias} dias, à parte da assinatura.`}
              />
              {!painel.vendasAbertas ? (
                <p className="px-6 py-6 text-sm text-[var(--ks-color-text-muted)]">A venda de pacotes está fechada no momento. Tente mais tarde ou fale com o suporte.</p>
              ) : painel.bloqueioDeCompra ? (
                <div className="p-6">
                  <Aviso tom="atencao" titulo="Compra de pacotes bloqueada">
                    {painel.bloqueioDeCompra}
                  </Aviso>
                </div>
              ) : pacotes.length === 0 ? (
                <p className="px-6 py-6 text-sm text-[var(--ks-color-text-muted)]">Nenhum pacote à venda no momento. As lives grátis do mês continuam valendo.</p>
              ) : (
                <>
                  <div role="radiogroup" aria-label="Pacote KtaloguLive" className="grid gap-4 p-6 sm:grid-cols-2 2xl:grid-cols-[repeat(auto-fit,minmax(13rem,1fr))]">
                    {pacotes.map((pacote) => (
                      <Opcao
                        key={pacote.id}
                        selecionada={escolhido?.id === pacote.id}
                        aoEscolher={() => setEscolhidoId(pacote.id)}
                        titulo={pacote.nome}
                        etiqueta={pacote.destaque ? <Etiqueta>Mais escolhido</Etiqueta> : undefined}
                      >
                        <span className="text-sm text-[var(--ks-color-text-muted)]">
                          <span className="ks-num text-base font-bold text-[var(--ks-color-text-primary)]">{pacote.lives}</span> {pacote.lives === 1 ? "live" : "lives"} · até{" "}
                          <span className="ks-num font-bold text-[var(--ks-color-text-primary)]">{pacote.pessoas}</span> pessoas
                        </span>
                        <span className="flex flex-col gap-1">
                          <Preco valor={moeda(pacote.preco)} unidade="" />
                          <span className="text-xs text-[var(--ks-color-text-muted)]">{moeda(pacote.preco / pacote.lives)} por live</span>
                        </span>
                        {pacote.descricao ? <span className="text-xs leading-5 text-[var(--ks-color-text-muted)]">{pacote.descricao}</span> : null}
                      </Opcao>
                    ))}
                  </div>
                  <FaixaDeAcao
                    resumo={
                      escolhido ? (
                        <>
                          <span className="font-semibold text-[var(--ks-color-text-primary)]">{escolhido.nome}</span> · {plural(escolhido.lives, "live", "lives")} até{" "}
                          {escolhido.pessoas} pessoas · <span className="ks-num">{moeda(escolhido.preco)}</span>
                        </>
                      ) : null
                    }
                  >
                    {painel.podeComprar ? (
                      <button type="button" onClick={() => void comprar()} disabled={comprando || !escolhido} className="ks-button ks-button-primary w-full sm:w-auto">
                        {comprando ? <Loader2 size={16} className="animate-spin" /> : <ShoppingBag size={16} />}
                        Comprar
                      </button>
                    ) : (
                      <span className="text-xs text-[var(--ks-color-text-soft)]">Só quem gerencia a assinatura pode comprar.</span>
                    )}
                  </FaixaDeAcao>
                  <p className="flex flex-wrap items-center gap-x-2 gap-y-1 border-t border-[var(--ks-color-border-subtle)] px-6 py-3 text-xs text-[var(--ks-color-text-soft)]">
                    <CreditCard size={14} />
                    Pix ou cartão. As lives entram na sua conta assim que o pagamento é confirmado.
                  </p>
                </>
              )}
            </Painel>
          </div>

          {painel.compras.length ? (
            <Painel atraso={0.16}>
              <CabecalhoDoPainel titulo="Compras do KtaloguLive" />
              <ul>
                {painel.compras.map((item) => {
                  const status = STATUS_DA_COMPRA[item.status] ?? STATUS_DA_COMPRA.pendente;
                  return (
                    <li key={item.id} className="flex flex-wrap items-center gap-3 border-t border-slate-100/60 px-6 py-3 first:border-t-0 hover:bg-[var(--ks-color-bg-hover)]">
                      <div className="min-w-[11rem] flex-1">
                        <p className="text-sm font-semibold text-[var(--ks-color-text-primary)]">
                          {item.pacote_nome} · {plural(item.lives, "live", "lives")} até {item.pessoas} pessoas
                        </p>
                        <p className="text-[11px] text-[var(--ks-color-text-soft)]">
                          {dataCurta(item.aprovada_em || item.created_at)}
                          {item.valida_ate && item.status === "aprovada" ? ` · vale até ${dataCurta(item.valida_ate)}` : ""}
                        </p>
                      </div>
                      <span className="ks-num text-sm font-semibold text-[var(--ks-color-text-primary)]">{moeda(Number(item.preco))}</span>
                      <span className={`rounded-full px-2.5 py-1 text-[11px] font-bold ${status.cor}`}>{status.rotulo}</span>
                      {item.status === "pendente" && item.checkout_url ? (
                        <a href={item.checkout_url} className="ks-button ks-button-soft ks-button-sm">
                          Pagar
                        </a>
                      ) : null}
                    </li>
                  );
                })}
              </ul>
            </Painel>
          ) : null}
        </>
      )}
    </div>
  );
}
