"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { useCallback, useEffect, useRef, useState } from "react";
import { ArrowLeft, ExternalLink, Eye, Loader2, Save, Store, Trash2 } from "lucide-react";

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

import { ConteudoDoCurso } from "./conteudo";
import { CertificadoDoCurso } from "./certificado-do-curso";
import { PaginaDeVenda, PrecoEAcesso } from "./pagina-de-venda";
import type { Ficha, RespostaDoCurso } from "./tipos";

/*
 * O editor do curso (prévia 8): abas Conteúdo, Página de venda, Preço e
 * acesso, Certificado e Alunos. O conteúdo se salva sozinho a cada mudança;
 * a página de venda e o preço vão pelo botão Salvar da barra de baixo.
 */

type Aba = "conteudo" | "pagina" | "preco" | "certificado" | "alunos";

function fichaDe(resposta: RespostaDoCurso): Ficha {
  const { produto } = resposta;
  return { nome: produto.nome, descricao: produto.descricao, preco: produto.preco, imagem: produto.imagem, config: produto.config };
}

/* A ficha sem o resumo do conteúdo (que muda sozinho, pelo servidor). */
function retrato(ficha: Ficha) {
  const curso = ficha.config.curso ? { ...ficha.config.curso, conteudo: null } : null;
  return JSON.stringify({ ...ficha, config: { ...ficha.config, curso, recebe: null } });
}

type AlunoDoCurso = {
  chave: string;
  nome: string;
  email: string | null;
  produtoId: string;
  situacao: string;
  progresso: number | null;
  ultimoAcessoEm: string | null;
  certificado?: { codigo: string; emitidoEm: string } | null;
};

function AlunosDoCurso({ cursoId }: { cursoId: string }) {
  const [alunos, setAlunos] = useState<AlunoDoCurso[] | null>(null);
  const [erro, setErro] = useState<string | null>(null);
  useEffect(() => {
    let cancelado = false;
    pedirDigitais<{ alunos: AlunoDoCurso[] }>("/api/digitais/alunos")
      .then((resposta) => {
        if (!cancelado) setAlunos(resposta.alunos.filter((a) => a.produtoId === cursoId));
      })
      .catch((e: unknown) => {
        if (!cancelado) setErro(e instanceof Error ? e.message : "Não foi possível carregar os clientes.");
      });
    return () => {
      cancelado = true;
    };
  }, [cursoId]);

  if (erro) return <p className="py-8 text-center text-sm text-[var(--ks-color-text-muted)]">{erro}</p>;
  if (!alunos) return <CarregandoArea texto="Carregando os clientes..." />;
  return (
    <section className="rounded-2xl border border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-elevated)] p-3 shadow-[var(--ks-shadow-subtle)] sm:p-4">
      {alunos.length === 0 ? (
        <p className="px-2 py-10 text-center text-sm text-[var(--ks-color-text-muted)]">
          Ninguém neste conteúdo ainda. Quem comprar aparece aqui sozinho, e você pode dar acesso de cortesia em Clientes e acessos.
        </p>
      ) : (
        <ul>
          {alunos.map((aluno) => (
            <li key={aluno.chave} className={`grid grid-cols-[minmax(0,1fr)_160px_110px] items-center gap-4 px-2 py-3 ${FIO_DA_LINHA}`}>
              <span className="min-w-0">
                <span className="block truncate text-sm font-bold text-[var(--ks-color-text-primary)]">{aluno.nome}</span>
                <span className="block truncate text-xs text-[var(--ks-color-text-muted)]">{aluno.email || "sem e-mail"}</span>
              </span>
              <span className="flex items-center gap-2">
                <span className="h-1.5 flex-1 overflow-hidden rounded-full bg-[var(--ks-color-bg-inset)]">
                  <span
                    className="block h-full rounded-full"
                    style={{ width: `${aluno.progresso ?? 0}%`, background: (aluno.progresso ?? 0) >= 100 ? "var(--ks-emerald)" : "var(--ks-brand-600)" }}
                  />
                </span>
                <span className="ks-num w-10 text-right text-xs text-[var(--ks-color-text-secondary)]">{aluno.progresso ?? 0}%</span>
              </span>
              <span className="text-xs text-[var(--ks-color-text-muted)]">
                {aluno.ultimoAcessoEm ? new Date(aluno.ultimoAcessoEm).toLocaleDateString("pt-BR") : "não entrou"}
                {aluno.certificado ? <span className="block font-semibold text-[var(--ks-emerald)]">certificado emitido</span> : null}
              </span>
            </li>
          ))}
        </ul>
      )}
      <p className="px-2 pt-3 text-xs text-[var(--ks-color-text-muted)]">
        Para dar acesso, mudar o prazo ou bloquear, use{" "}
        <Link href="/dashboard/digitais/alunos" className="font-semibold text-[var(--ks-brand-600)] hover:underline">
          Clientes e acessos
        </Link>
        .
      </p>
    </section>
  );
}

export default function EditorDoCurso({ id }: { id: string }) {
  const router = useRouter();
  const [dados, setDados] = useState<RespostaDoCurso | null>(null);
  const [ficha, setFicha] = useState<Ficha | null>(null);
  const [salva, setSalva] = useState("");
  const [erro, setErro] = useState<Error | null>(null);
  const [aba, setAba] = useState<Aba>("conteudo");
  const [salvando, setSalvando] = useState(false);
  const [publicando, setPublicando] = useState(false);
  const [abrindoPrevia, setAbrindoPrevia] = useState(false);
  const [aviso, setAviso] = useState<{ tom: "bom" | "ruim" | "atencao"; texto: string; faltas?: string[] } | null>(null);
  const [confirmacao, setConfirmacao] = useState<Confirmacao | null>(null);
  const [ocupado, setOcupado] = useState(false);
  const carregouRef = useRef(false);

  const carregar = useCallback(
    () =>
      pedirDigitais<RespostaDoCurso>(`/api/digitais/cursos/${id}`)
        .then((resposta) => {
          setDados(resposta);
          setErro(null);
          if (!carregouRef.current) {
            carregouRef.current = true;
            const nova = fichaDe(resposta);
            setFicha(nova);
            setSalva(retrato(nova));
            return;
          }
          /* Recarregar (o conteúdo mudou) não apaga o que está sendo digitado:
             só atualiza o resumo que o servidor refaz. */
          setFicha((atual) =>
            atual
              ? {
                  ...atual,
                  config: {
                    ...atual.config,
                    recebe: resposta.produto.config.recebe,
                    curso: atual.config.curso && resposta.produto.config.curso ? { ...atual.config.curso, conteudo: resposta.produto.config.curso.conteudo } : resposta.produto.config.curso,
                  },
                }
              : fichaDe(resposta)
          );
        })
        .catch((e: unknown) => setErro(e instanceof Error ? e : new Error("Não foi possível carregar o conteúdo."))),
    [id]
  );

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

  const avisar = useCallback((tom: "bom" | "ruim" | "atencao", texto: string) => setAviso({ tom, texto }), []);
  const mudou = ficha !== null && retrato(ficha) !== salva;

  const salvar = async (): Promise<boolean> => {
    if (!ficha) return false;
    setSalvando(true);
    try {
      await pedirDigitais(`/api/digitais/produtos/${id}`, {
        method: "PUT",
        body: JSON.stringify({ nome: ficha.nome, descricao: ficha.descricao, preco: ficha.preco, imagem: ficha.imagem, config: ficha.config }),
      });
      setSalva(retrato(ficha));
      setAviso({ tom: "bom", texto: "Conteúdo salvo." });
      await carregar();
      return true;
    } catch (e) {
      setAviso({ tom: "ruim", texto: e instanceof Error ? e.message : "Não foi possível salvar." });
      return false;
    } finally {
      setSalvando(false);
    }
  };

  const publicar = async (naLoja: boolean) => {
    if (mudou && !(await salvar())) return;
    setPublicando(true);
    try {
      const resposta = await fetch(`/api/digitais/produtos/${id}`, {
        method: "PUT",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ naLoja }),
      });
      const corpo = (await resposta.json().catch(() => null)) as { error?: string; faltas?: string[] } | null;
      if (!resposta.ok) {
        setAviso({ tom: "atencao", texto: corpo?.error || "Não foi possível publicar.", faltas: corpo?.faltas });
        return;
      }
      setAviso({ tom: "bom", texto: naLoja ? "Pronto: o conteúdo está na loja." : "O conteúdo saiu da loja. Quem comprou continua com acesso." });
      await carregar();
    } finally {
      setPublicando(false);
    }
  };

  const verComoAluno = async () => {
    /* A aba nasce já no clique (depois da resposta o navegador bloquearia). */
    const janela = window.open("", "_blank");
    setAbrindoPrevia(true);
    try {
      const resposta = await pedirDigitais<{ link: string }>(`/api/digitais/cursos/${id}/previa`, { method: "POST", body: "{}" });
      if (janela) janela.location.href = resposta.link;
      else window.location.href = resposta.link;
    } catch (e) {
      janela?.close();
      setAviso({ tom: "ruim", texto: e instanceof Error ? e.message : "Não foi possível abrir a prévia." });
    } finally {
      setAbrindoPrevia(false);
    }
  };

  const pedirParaApagar = () =>
    setConfirmacao({
      titulo: "Apagar este conteúdo?",
      texto: "Some com os módulos e vídeos. Os arquivos continuam na sua biblioteca. Se alguém já comprou, ele não pode ser apagado: tire da loja.",
      confirmar: "Apagar",
      cancelar: "Voltar",
      tom: "perigo",
      aoConfirmar: async () => {
        setOcupado(true);
        try {
          await pedirDigitais(`/api/digitais/produtos/${id}`, { method: "DELETE" });
          router.push("/dashboard/digitais/cursos");
        } catch (e) {
          setAviso({ tom: "ruim", texto: e instanceof Error ? e.message : "Não foi possível apagar." });
          setConfirmacao(null);
        } finally {
          setOcupado(false);
        }
      },
    });

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

  const { produto, podeEditar } = dados;
  const abas: Array<{ valor: Aba; rotulo: string }> = [
    { valor: "conteudo", rotulo: "Conteúdo" },
    { valor: "pagina", rotulo: "Página de venda" },
    { valor: "preco", rotulo: "Preço e acesso" },
    { valor: "certificado", rotulo: "Certificado" },
    { valor: "alunos", rotulo: `Clientes · ${produto.alunos}` },
  ];

  return (
    <div className="space-y-5 pb-4">
      <header className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
        <div className="flex min-w-0 flex-wrap items-center gap-3">
          <Link href="/dashboard/digitais/cursos" className="inline-flex items-center gap-1.5 text-sm font-semibold text-[var(--ks-color-text-muted)] hover:text-[var(--ks-color-text-primary)]">
            <ArrowLeft size={16} />
            Conteúdos em vídeo
          </Link>
          <h1 className="ks-page-title flex min-w-0 flex-wrap items-center gap-3">
            <span className="min-w-0 break-words">{ficha.nome || "Sem nome"}</span>
            <span
              className={`rounded-full px-2.5 py-1 text-xs font-bold ${
                produto.naLoja ? "bg-[color:rgba(14,158,112,0.12)] text-[var(--ks-emerald)]" : "bg-[var(--ks-color-bg-inset)] text-[var(--ks-color-text-muted)]"
              }`}
            >
              {produto.naLoja ? "Na loja" : "Rascunho"}
            </span>
          </h1>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          <button type="button" className="ks-button ks-button-soft" onClick={() => void verComoAluno()} disabled={abrindoPrevia}>
            {abrindoPrevia ? <Loader2 size={16} className="animate-spin" /> : <Eye size={16} />}
            Ver como cliente
          </button>
          {produto.naLoja && produto.enderecoNaLoja ? (
            <a href={produto.enderecoNaLoja} target="_blank" rel="noreferrer" className="ks-button ks-button-soft">
              <ExternalLink size={16} />
              Ver na loja
            </a>
          ) : null}
          {podeEditar && produto.vendas === 0 && produto.alunos === 0 ? (
            <button type="button" onClick={pedirParaApagar} className="ks-button ks-button-ghost" aria-label="Apagar conteúdo">
              <Trash2 size={16} />
            </button>
          ) : null}
        </div>
      </header>

      <nav aria-label="Partes do conteúdo" className="flex gap-1 overflow-x-auto rounded-2xl bg-[var(--ks-color-bg-inset)] p-1">
        {abas.map((item) => (
          <button
            key={item.valor}
            type="button"
            onClick={() => setAba(item.valor)}
            className={`whitespace-nowrap rounded-xl px-4 py-2 text-sm font-semibold transition-colors ${
              aba === item.valor ? "bg-[var(--ks-brand-600)] text-white shadow-sm" : "text-[var(--ks-color-text-secondary)] hover:bg-white"
            }`}
          >
            {item.rotulo}
          </button>
        ))}
      </nav>

      {aviso ? (
        <Aviso tom={aviso.tom} aoFechar={() => setAviso(null)}>
          {aviso.texto}
          {aviso.faltas?.length ? (
            <ul className="mt-1 list-disc pl-5">
              {aviso.faltas.map((falta) => (
                <li key={falta}>{falta}</li>
              ))}
            </ul>
          ) : null}
        </Aviso>
      ) : null}

      {aba === "conteudo" ? (
        <ConteudoDoCurso
          cursoId={id}
          modulos={dados.modulos}
          podeEditar={podeEditar}
          aoMudar={carregar}
          aoAvisar={avisar}
          aoConfirmar={(pedido) =>
            setConfirmacao({
              ...pedido,
              aoConfirmar: async () => {
                setOcupado(true);
                try {
                  await pedido.aoConfirmar();
                } finally {
                  setOcupado(false);
                  setConfirmacao(null);
                }
              },
            })
          }
        />
      ) : null}
      {aba === "pagina" ? <PaginaDeVenda ficha={ficha} podeEditar={podeEditar} modulos={dados.modulos} aoMudar={setFicha} /> : null}
      {aba === "preco" ? <PrecoEAcesso ficha={ficha} podeEditar={podeEditar} aoMudar={setFicha} /> : null}
      {aba === "certificado" ? <CertificadoDoCurso ficha={ficha} podeEditar={podeEditar} aoMudar={setFicha} /> : null}
      {aba === "alunos" ? <AlunosDoCurso cursoId={id} /> : null}

      {podeEditar ? (
        <div className="sticky bottom-3 z-30 flex flex-wrap items-center justify-end gap-3 rounded-2xl border border-[var(--ks-color-border-subtle)] bg-white/95 px-4 py-3 shadow-[0_10px_30px_-18px_rgba(15,23,42,0.45)] backdrop-blur">
          <span className="mr-auto text-sm text-[var(--ks-color-text-muted)]">
            {mudou ? "Há mudanças por salvar." : aba === "conteudo" ? "O conteúdo é salvo sozinho a cada mudança." : ""}
          </span>
          <button type="button" className="ks-button ks-button-soft" disabled={publicando || salvando} onClick={() => void publicar(!produto.naLoja)}>
            {publicando ? <Loader2 size={16} className="animate-spin" /> : <Store size={16} />}
            {produto.naLoja ? "Tirar da loja" : "Publicar na loja"}
          </button>
          <Button type="button" disabled={salvando || !mudou} onClick={() => void salvar()} icon={salvando ? <Loader2 className="h-4 w-4 animate-spin" /> : <Save className="h-4 w-4" />}>
            {salvando ? "Salvando..." : "Salvar"}
          </Button>
        </div>
      ) : null}

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