"use client";

import { useEffect, useState } from "react";
import { ChatTeardropText as MessageSquare, CircleNotch as Loader2, Heart, Storefront as Store } from "@phosphor-icons/react";

import { avisoDaLoja } from "@/components/AvisoDaLoja";
import { getReadableTextColor } from "@/lib/color-contrast";
import type { ComentarioNaTela } from "@/lib/digitais/tipos-do-curso";

import type { TemaDosMembros } from "./tema";

/*
 * Os comentários embaixo da aula: perguntas dos alunos, respostas da loja
 * (com o selo dela) e curtidas. Uma conversa tem um nível de resposta.
 */

type Dados = { ligados: boolean; podeComentar: boolean; comentarios: ComentarioNaTela[]; agora: number };

function quando(iso: string, agora: number): string {
  const t = new Date(iso).getTime();
  if (!Number.isFinite(t)) return "";
  const s = Math.max(0, (agora - t) / 1000);
  if (s < 60) return "agora";
  if (s < 3600) return `há ${Math.floor(s / 60)} min`;
  if (s < 86400) return `há ${Math.floor(s / 3600)} h`;
  const dias = Math.floor(s / 86400);
  if (dias === 1) return "ontem";
  if (dias < 30) return `há ${dias} dias`;
  return new Date(t).toLocaleDateString("pt-BR", { timeZone: "America/Sao_Paulo" });
}

function iniciais(nome: string): string {
  return (
    nome
      .trim()
      .split(/\s+/)
      .filter(Boolean)
      .slice(0, 2)
      .map((p) => p[0]?.toUpperCase())
      .join("") || "?"
  );
}

export function contarComentarios(lista: ComentarioNaTela[]): number {
  return lista.reduce((soma, c) => soma + 1 + c.respostas.length, 0);
}

async function lerComentarios(slug: string, aulaId: string): Promise<Omit<Dados, "agora">> {
  const resposta = await fetch(`/api/digitais/aula/${aulaId}/comentarios?slug=${encodeURIComponent(slug)}`, { cache: "no-store" });
  const corpo = (await resposta.json().catch(() => null)) as (Omit<Dados, "agora"> & { error?: string }) | null;
  if (!resposta.ok || !corpo) throw new Error(corpo?.error || "Não foi possível carregar os comentários.");
  return { ligados: Boolean(corpo.ligados), podeComentar: Boolean(corpo.podeComentar), comentarios: corpo.comentarios ?? [] };
}

export default function ComentariosDaAula({
  slug,
  aulaId,
  cor,
  tema,
  previa,
  aoContar,
}: {
  slug: string;
  aulaId: string;
  cor: string;
  tema: TemaDosMembros;
  previa: boolean;
  aoContar?: (quantos: number) => void;
}) {
  const [dados, setDados] = useState<Dados | null>(null);
  const [erro, setErro] = useState<string | null>(null);
  const [texto, setTexto] = useState("");
  const [respondendo, setRespondendo] = useState<string | null>(null);
  const [resposta, setResposta] = useState("");
  const [enviando, setEnviando] = useState(false);
  const [curtindo, setCurtindo] = useState<string | null>(null);

  function recarregar() {
    return lerComentarios(slug, aulaId).then((lidos) => {
      setDados({ ...lidos, agora: Date.now() });
      setErro(null);
      aoContar?.(contarComentarios(lidos.comentarios));
    });
  }

  useEffect(() => {
    let vivo = true;
    lerComentarios(slug, aulaId)
      .then((lidos) => {
        if (!vivo) return;
        setDados({ ...lidos, agora: Date.now() });
        aoContar?.(contarComentarios(lidos.comentarios));
      })
      .catch((e: unknown) => {
        if (vivo) setErro(e instanceof Error ? e.message : "Não foi possível carregar os comentários.");
      });
    return () => {
      vivo = false;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps -- aoContar só avisa a aba; a leitura depende da aula
  }, [slug, aulaId]);

  async function publicar(conteudo: string, respostaA: string | null) {
    const limpo = conteudo.trim();
    if (!limpo || enviando) return;
    setEnviando(true);
    try {
      const r = await fetch(`/api/digitais/aula/${aulaId}/comentarios`, {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ slug, texto: limpo, respostaA }),
      });
      const corpo = (await r.json().catch(() => null)) as { pendente?: boolean; error?: string } | null;
      if (!r.ok) throw new Error(corpo?.error || "Não foi possível publicar agora.");
      if (respostaA) {
        setResposta("");
        setRespondendo(null);
      } else {
        setTexto("");
      }
      if (corpo?.pendente) avisoDaLoja.info("Recebido! Seu comentário aparece para todos depois que a loja aprovar.");
      await recarregar().catch(() => undefined);
    } catch (e) {
      avisoDaLoja.erro(e instanceof Error ? e.message : "Não foi possível publicar agora.");
    } finally {
      setEnviando(false);
    }
  }

  async function curtir(comentario: ComentarioNaTela) {
    if (curtindo) return;
    if (previa) {
      avisoDaLoja.info("Na prévia não dá para curtir.");
      return;
    }
    setCurtindo(comentario.id);
    try {
      const r = await fetch(`/api/digitais/comentarios/${comentario.id}/curtir`, {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ slug }),
      });
      const corpo = (await r.json().catch(() => null)) as { curti?: boolean; curtidas?: number; error?: string } | null;
      if (!r.ok || typeof corpo?.curti !== "boolean") throw new Error(corpo?.error || "Não foi possível agora.");
      const trocar = (c: ComentarioNaTela): ComentarioNaTela =>
        c.id === comentario.id ? { ...c, curti: Boolean(corpo.curti), curtidas: Number(corpo.curtidas) || 0 } : { ...c, respostas: c.respostas.map(trocar) };
      setDados((atual) => (atual ? { ...atual, comentarios: atual.comentarios.map(trocar) } : atual));
    } catch (e) {
      avisoDaLoja.erro(e instanceof Error ? e.message : "Não foi possível agora.");
    } finally {
      setCurtindo(null);
    }
  }

  if (erro && !dados) return <p className={`py-6 text-[14px] ${tema.suave}`}>{erro}</p>;
  if (!dados) {
    return (
      <div className={`flex items-center gap-2 py-6 text-[14px] ${tema.suave}`}>
        <Loader2 className="h-4 w-4 animate-spin" />
        Carregando os comentários…
      </div>
    );
  }

  const corDoTexto = getReadableTextColor(cor);

  const comentario = (c: ComentarioNaTela, ehResposta = false) => (
      <div className="flex gap-3">
        <span
          className={`flex shrink-0 items-center justify-center rounded-full font-bold ${ehResposta ? "h-8 w-8 text-[11px]" : "h-10 w-10 text-[12.5px]"} ${c.daLoja ? "" : tema.realce}`}
          style={c.daLoja ? { backgroundColor: cor, color: corDoTexto } : undefined}
        >
          {c.daLoja ? <Store className="h-4 w-4" /> : iniciais(c.autor)}
        </span>
        <div className="min-w-0 flex-1">
          <div className="flex flex-wrap items-center gap-x-2 gap-y-0.5">
            <span className="text-[13.5px] font-bold">{c.autor}</span>
            {c.daLoja ? (
              <span className="rounded-full px-2 py-0.5 text-[10.5px] font-bold uppercase tracking-wide" style={{ backgroundColor: `${cor}26`, color: tema.escuro ? "#fff" : cor }}>
                Loja
              </span>
            ) : null}
            {c.meu && !c.daLoja ? <span className={`text-[11.5px] ${tema.apagado}`}>(você)</span> : null}
            <span className={`text-[12px] ${tema.apagado}`}>{quando(c.criadoEm, dados?.agora ?? 0)}</span>
          </div>
          {c.pendente ? (
            <div className="mt-1 inline-flex rounded-full bg-amber-400/15 px-2 py-0.5 text-[11px] font-semibold text-amber-500">Aguardando a loja aprovar</div>
          ) : null}
          <p className="mt-1 whitespace-pre-line break-words text-[14px] leading-6">{c.texto}</p>
          <div className={`mt-1.5 flex items-center gap-4 text-[12.5px] font-semibold ${tema.suave}`}>
            <button
              type="button"
              onClick={() => void curtir(c)}
              disabled={c.pendente || curtindo === c.id}
              className="inline-flex items-center gap-1.5 transition hover:opacity-80 disabled:opacity-50"
              aria-pressed={c.curti}
            >
              <Heart weight={c.curti ? "fill" : "bold"} className="h-4 w-4" style={c.curti ? { color: cor } : undefined} />
              {c.curtidas > 0 ? c.curtidas : "Curtir"}
            </button>
            {!ehResposta && dados?.podeComentar && !c.pendente ? (
              <button
                type="button"
                onClick={() => {
                  setRespondendo(respondendo === c.id ? null : c.id);
                  setResposta("");
                }}
                className="transition hover:opacity-80"
              >
                Responder
              </button>
            ) : null}
          </div>
        </div>
      </div>
  );

  const total = contarComentarios(dados.comentarios);

  return (
    <div>
      {!dados.ligados ? (
        <p className={`rounded-xl px-4 py-3 text-[13.5px] ${tema.realce} ${tema.suave}`}>Os comentários deste vídeo estão desligados.</p>
      ) : dados.podeComentar ? (
        <form
          className="space-y-2"
          onSubmit={(e) => {
            e.preventDefault();
            void publicar(texto, null);
          }}
        >
          <textarea
            value={texto}
            onChange={(e) => setTexto(e.target.value.slice(0, 2000))}
            rows={3}
            placeholder="Escreva uma dúvida ou um comentário sobre este vídeo"
            className={`w-full resize-y rounded-xl border-[1.5px] px-3.5 py-3 text-[14px] leading-6 outline-none transition ${tema.campo}`}
          />
          <div className="flex items-center justify-between gap-3">
            <span className={`text-[12px] ${tema.apagado}`}>Os outros clientes veem seu primeiro nome e a inicial.</span>
            <button
              type="submit"
              disabled={enviando || !texto.trim()}
              className="inline-flex h-10 shrink-0 items-center gap-2 rounded-xl px-4 text-[13.5px] font-bold transition hover:opacity-90 disabled:opacity-50"
              style={{ backgroundColor: cor, color: corDoTexto }}
            >
              {enviando && !respondendo ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
              Publicar
            </button>
          </div>
        </form>
      ) : previa ? (
        <p className={`rounded-xl px-4 py-3 text-[13.5px] ${tema.realce} ${tema.suave}`}>
          Na prévia você vê os comentários, mas não comenta. Para responder como a loja, use o painel, em Produtos digitais › Comentários.
        </p>
      ) : null}

      {total ? (
        <ul className="mt-6 space-y-6">
          {dados.comentarios.map((c) => (
            <li key={c.id}>
              {comentario(c)}
              {c.respostas.length || respondendo === c.id ? (
                <div className={`ml-[52px] mt-4 space-y-4 border-l-2 pl-4 ${tema.linha}`}>
                  {c.respostas.map((r) => (
                    <div key={r.id}>{comentario(r, true)}</div>
                  ))}
                  {respondendo === c.id ? (
                    <form
                      className="space-y-2"
                      onSubmit={(e) => {
                        e.preventDefault();
                        void publicar(resposta, c.id);
                      }}
                    >
                      <textarea
                        value={resposta}
                        onChange={(e) => setResposta(e.target.value.slice(0, 2000))}
                        rows={2}
                        autoFocus
                        placeholder={`Responder a ${c.autor}`}
                        className={`w-full resize-y rounded-xl border-[1.5px] px-3.5 py-2.5 text-[14px] leading-6 outline-none transition ${tema.campo}`}
                      />
                      <div className="flex justify-end gap-2">
                        <button type="button" onClick={() => setRespondendo(null)} className={`h-9 rounded-xl px-3 text-[13px] font-semibold ${tema.suave}`}>
                          Cancelar
                        </button>
                        <button
                          type="submit"
                          disabled={enviando || !resposta.trim()}
                          className="inline-flex h-9 items-center gap-2 rounded-xl px-4 text-[13px] font-bold transition hover:opacity-90 disabled:opacity-50"
                          style={{ backgroundColor: cor, color: corDoTexto }}
                        >
                          {enviando ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
                          Responder
                        </button>
                      </div>
                    </form>
                  ) : null}
                </div>
              ) : null}
            </li>
          ))}
        </ul>
      ) : dados.ligados ? (
        <div className={`mt-6 flex items-center gap-2 text-[13.5px] ${tema.suave}`}>
          <MessageSquare className="h-4 w-4" />
          Ninguém comentou ainda. Ficou com dúvida? Pergunte aqui.
        </div>
      ) : null}
    </div>
  );
}
