"use client";

import Link from "next/link";
import { useCallback, useEffect, useState } from "react";
import { Check, EyeOff, Eye, Loader2, MessageSquare, Store, Trash2 } from "lucide-react";

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

/*
 * Comentários (prévia 9): as dúvidas que os alunos deixam embaixo das aulas.
 * A resposta da loja aparece para todos os alunos, com o nome e o selo da
 * loja. Dá para aprovar o que espera aprovação, ocultar e apagar.
 */

type Situacao = "publicado" | "pendente" | "oculto";
type Filtro = "sem_resposta" | "pendentes" | "todos" | "ocultos";

type Resposta = { id: string; texto: string; status: Situacao; criadoEm: string; daLoja: boolean; minha: boolean; autor: string };
type Comentario = {
  id: string;
  texto: string;
  status: Situacao;
  criadoEm: string;
  curtidas: number;
  daLoja: boolean;
  minha: boolean;
  aluno: { id: string; nome: string; email: string | null } | null;
  aula: { id: string; titulo: string };
  curso: { id: string; nome: string };
  respondido: boolean;
  respostas: Resposta[];
};
type Dados = {
  podeResponder: boolean;
  nomeDaLoja: string;
  contagem: { semResposta: number; pendentes: number };
  cursos: Array<{ id: string; nome: string }>;
  comentarios: Comentario[];
  maisAntigos: string | null;
};

const FILTROS: Array<{ valor: Filtro; rotulo: string }> = [
  { valor: "sem_resposta", rotulo: "Sem resposta" },
  { valor: "pendentes", rotulo: "Esperando aprovação" },
  { valor: "todos", rotulo: "Todos" },
  { valor: "ocultos", rotulo: "Ocultos" },
];

const VAZIO: Record<Filtro, string> = {
  sem_resposta: "Nenhuma pergunta esperando você. Quando um cliente comentar num vídeo, aparece aqui.",
  pendentes: "Nada esperando aprovação. Para aprovar antes de aparecer, ligue isso em Configurações › Comentários.",
  todos: "Ainda não há comentários nos vídeos.",
  ocultos: "Nenhum comentário oculto.",
};

/* O menu do painel recontar as perguntas sem resposta. */
const avisarMenu = () => window.dispatchEvent(new Event("ks:comentarios-mudaram"));

const CORES = ["#E5484D", "#2F80ED", "#0E9E70", "#F2994A", "#7B61FF", "#D9488F"];

function corDoNome(nome: string) {
  let soma = 0;
  for (const letra of nome) soma = (soma + letra.charCodeAt(0)) % 997;
  return CORES[soma % CORES.length];
}

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

function haQuanto(iso: string, agora: number): string {
  const minutos = Math.round((agora - new Date(iso).getTime()) / 60000);
  if (minutos < 2) return "agora";
  if (minutos < 60) return `há ${minutos} min`;
  const horas = Math.round(minutos / 60);
  if (horas < 24) return `há ${horas} h`;
  const dias = Math.round(horas / 24);
  if (dias === 1) return "ontem";
  if (dias < 30) return `há ${dias} dias`;
  return new Date(iso).toLocaleDateString("pt-BR");
}

function SeloDaSituacao({ status }: { status: Situacao }) {
  if (status === "pendente") {
    return <span className="rounded-full bg-[color:rgba(234,179,8,0.14)] px-2 py-0.5 text-[11px] font-bold text-[#a16207]">Esperando aprovação</span>;
  }
  if (status === "oculto") {
    return <span className="rounded-full bg-[var(--ks-color-bg-inset)] px-2 py-0.5 text-[11px] font-bold text-[var(--ks-color-text-muted)]">Oculto</span>;
  }
  return null;
}

export default function ComentariosDasAulas({ filtroInicial = "sem_resposta" }: { filtroInicial?: Filtro }) {
  const [filtro, setFiltro] = useState<Filtro>(filtroInicial);
  const [curso, setCurso] = useState("");
  const [dados, setDados] = useState<(Dados & { agora: number; chave: string }) | null>(null);
  const [erro, setErro] = useState<Error | null>(null);
  const [respondendo, setRespondendo] = useState<string | null>(null);
  const [rascunhos, setRascunhos] = useState<Record<string, string>>({});
  const [ocupado, setOcupado] = useState<string | null>(null);
  const [carregandoMais, setCarregandoMais] = useState(false);
  const [aviso, setAviso] = useState<{ tom: "bom" | "ruim"; texto: string } | null>(null);
  const [confirmacao, setConfirmacao] = useState<Confirmacao | null>(null);

  const chave = `${filtro}|${curso}`;
  const endereco = useCallback(
    (antes?: string | null) =>
      `/api/digitais/comentarios?filtro=${filtro}${curso ? `&curso=${encodeURIComponent(curso)}` : ""}${antes ? `&antes=${encodeURIComponent(antes)}` : ""}`,
    [filtro, curso]
  );

  const carregar = useCallback(
    () =>
      pedirDigitais<Dados>(endereco())
        .then((resposta) => {
          setDados({ ...resposta, agora: Date.now(), chave });
          setErro(null);
        })
        .catch((e: unknown) => setErro(e instanceof Error ? e : new Error("Não foi possível carregar."))),
    [endereco, chave]
  );

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

  const maisAntigos = async () => {
    if (!dados?.maisAntigos || carregandoMais) return;
    setCarregandoMais(true);
    try {
      const resposta = await pedirDigitais<Dados>(endereco(dados.maisAntigos));
      setDados((atual) => (atual ? { ...atual, comentarios: [...atual.comentarios, ...resposta.comentarios], maisAntigos: resposta.maisAntigos } : atual));
    } catch (e) {
      setAviso({ tom: "ruim", texto: e instanceof Error ? e.message : "Não foi possível carregar mais." });
    } finally {
      setCarregandoMais(false);
    }
  };

  const responder = async (comentario: Comentario) => {
    const texto = (rascunhos[comentario.id] ?? "").trim();
    if (!texto || ocupado) return;
    setOcupado(comentario.id);
    try {
      await pedirDigitais(`/api/digitais/comentarios/${comentario.id}/responder`, { method: "POST", body: JSON.stringify({ texto }) });
      setRascunhos((atual) => ({ ...atual, [comentario.id]: "" }));
      setRespondendo(null);
      setAviso({ tom: "bom", texto: `Resposta publicada. ${comentario.aluno?.nome.split(" ")[0] || "O cliente"} vê no vídeo, com o selo da loja.` });
      await carregar();
      avisarMenu();
    } catch (e) {
      setAviso({ tom: "ruim", texto: e instanceof Error ? e.message : "Não foi possível responder." });
    } finally {
      setOcupado(null);
    }
  };

  const mudar = async (id: string, status: "publicado" | "oculto") => {
    if (ocupado) return;
    setOcupado(id);
    try {
      await pedirDigitais(`/api/digitais/comentarios/${id}`, { method: "PUT", body: JSON.stringify({ status }) });
      setAviso({ tom: "bom", texto: status === "oculto" ? "Comentário oculto: os clientes não veem mais." : "Comentário publicado: os clientes já veem." });
      await carregar();
      avisarMenu();
    } catch (e) {
      setAviso({ tom: "ruim", texto: e instanceof Error ? e.message : "Não foi possível salvar." });
    } finally {
      setOcupado(null);
    }
  };

  const apagar = (id: string, principal: boolean) =>
    setConfirmacao({
      titulo: principal ? "Apagar a conversa?" : "Apagar esta resposta?",
      texto: principal ? "O comentário e todas as respostas somem para todos os clientes. Não dá para desfazer." : "A resposta some para todos os clientes. Não dá para desfazer.",
      confirmar: "Apagar",
      tom: "perigo",
      aoConfirmar: async () => {
        setOcupado(id);
        try {
          await pedirDigitais(`/api/digitais/comentarios/${id}`, { method: "DELETE" });
          setAviso({ tom: "bom", texto: principal ? "Conversa apagada." : "Resposta apagada." });
          await carregar();
          avisarMenu();
        } catch (e) {
          setAviso({ tom: "ruim", texto: e instanceof Error ? e.message : "Não foi possível apagar." });
        } 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 />;

  const atualizando = dados.chave !== chave;
  const contagemDoFiltro: Partial<Record<Filtro, number>> = { sem_resposta: dados.contagem.semResposta, pendentes: dados.contagem.pendentes };
  const botao =
    "inline-flex h-8 items-center gap-1.5 rounded-full border border-[var(--ks-color-border-subtle)] bg-white px-3 text-[12.5px] font-semibold text-[var(--ks-color-text-secondary)] transition hover:border-[var(--ks-brand-500)] disabled:opacity-50";

  return (
    <div className="space-y-5">
      <PageHeader
        eyebrow="Quem comprou"
        title="Comentários"
        subtitle="As dúvidas que os clientes deixam embaixo dos vídeos. Sua resposta aparece para todos, com o selo da loja."
      />

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

      <div className="flex flex-wrap items-center justify-between gap-3">
        <div className="flex flex-wrap gap-2">
          {FILTROS.map((f) => {
            const ativo = filtro === f.valor;
            const numero = contagemDoFiltro[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}
                {typeof numero === "number" ? <span className={`ks-num ml-1 ${ativo ? "text-white/80" : "text-[var(--ks-color-text-soft)]"}`}>{numero}</span> : null}
              </button>
            );
          })}
        </div>
        {dados.cursos.length > 1 ? (
          <select
            value={curso}
            onChange={(e) => setCurso(e.target.value)}
            className="h-9 rounded-xl border border-[var(--ks-color-border-subtle)] bg-white px-3 text-[13px] text-[var(--ks-color-text-primary)] outline-none focus:border-[var(--ks-brand-500)]"
            aria-label="Conteúdo"
          >
            <option value="">Todos os conteúdos</option>
            {dados.cursos.map((c) => (
              <option key={c.id} value={c.id}>
                {c.nome}
              </option>
            ))}
          </select>
        ) : null}
      </div>

      <section className={`rounded-2xl border border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-elevated)] shadow-[var(--ks-shadow-subtle)] transition-opacity ${atualizando ? "opacity-60" : ""}`}>
        {dados.comentarios.length ? (
          <ul className="divide-y divide-[var(--ks-color-border-subtle)]">
            {dados.comentarios.map((c) => {
              const nome = c.aluno?.nome ?? dados.nomeDaLoja;
              const aberto = respondendo === c.id;
              return (
                <li key={c.id} className="flex gap-3 px-4 py-4 sm:px-5">
                  <span
                    className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full text-[12.5px] font-bold text-white"
                    style={{ backgroundColor: c.daLoja ? "var(--ks-brand-600)" : corDoNome(nome) }}
                  >
                    {c.daLoja ? <Store size={16} /> : iniciais(nome)}
                  </span>
                  <div className="min-w-0 flex-1">
                    <div className="flex flex-wrap items-center gap-x-1.5 gap-y-1 text-[12.5px] text-[var(--ks-color-text-muted)]">
                      <span className="text-[14px] font-bold text-[var(--ks-color-text-primary)]" title={c.aluno?.email ?? undefined}>
                        {nome}
                      </span>
                      <span>· Vídeo “{c.aula.titulo}”</span>
                      {dados.cursos.length > 1 ? <span>· {c.curso.nome}</span> : null}
                      <span>· {haQuanto(c.criadoEm, dados.agora)}</span>
                      <SeloDaSituacao status={c.status} />
                    </div>
                    <p className="mt-1 whitespace-pre-line break-words text-[14px] leading-6 text-[var(--ks-color-text-primary)]">{c.texto}</p>

                    {c.respostas.length ? (
                      <div className="mt-3 space-y-2">
                        {c.respostas.map((r) => (
                          <div
                            key={r.id}
                            className={`group rounded-xl px-3.5 py-2.5 ${r.daLoja ? "bg-[color:rgba(95,49,214,0.07)]" : "bg-[var(--ks-color-bg-inset)]"}`}
                          >
                            <div className="flex flex-wrap items-center gap-x-1.5 gap-y-1 text-[12.5px]">
                              <span className={`font-bold ${r.daLoja ? "text-[var(--ks-brand-600)]" : "text-[var(--ks-color-text-primary)]"}`}>
                                {r.autor}
                                {r.daLoja ? " · respondeu" : ""}
                              </span>
                              {r.minha ? <span className="text-[var(--ks-color-text-muted)]">(você)</span> : null}
                              <span className="text-[var(--ks-color-text-muted)]">· {haQuanto(r.criadoEm, dados.agora)}</span>
                              <SeloDaSituacao status={r.status} />
                              {dados.podeResponder ? (
                                <span className="ml-auto flex items-center gap-1">
                                  {!r.daLoja ? (
                                    r.status === "oculto" ? (
                                      <button type="button" className={botao} disabled={Boolean(ocupado)} onClick={() => void mudar(r.id, "publicado")}>
                                        <Eye size={13} />
                                        Mostrar
                                      </button>
                                    ) : r.status === "pendente" ? (
                                      <button type="button" className={botao} disabled={Boolean(ocupado)} onClick={() => void mudar(r.id, "publicado")}>
                                        <Check size={13} />
                                        Aprovar
                                      </button>
                                    ) : (
                                      <button type="button" className={botao} disabled={Boolean(ocupado)} onClick={() => void mudar(r.id, "oculto")}>
                                        <EyeOff size={13} />
                                        Ocultar
                                      </button>
                                    )
                                  ) : null}
                                  <button
                                    type="button"
                                    className="flex h-8 w-8 items-center justify-center rounded-full text-[var(--ks-color-text-muted)] hover:bg-white hover:text-[#c2263f]"
                                    aria-label="Apagar resposta"
                                    disabled={Boolean(ocupado)}
                                    onClick={() => apagar(r.id, false)}
                                  >
                                    <Trash2 size={14} />
                                  </button>
                                </span>
                              ) : null}
                            </div>
                            <p className="mt-0.5 whitespace-pre-line break-words text-[13.5px] leading-6 text-[var(--ks-color-text-primary)]">{r.texto}</p>
                          </div>
                        ))}
                      </div>
                    ) : null}

                    {dados.podeResponder ? (
                      aberto ? (
                        <form
                          className="mt-3 rounded-xl border border-[var(--ks-brand-300,#c4b5fd)] bg-white p-2"
                          onSubmit={(e) => {
                            e.preventDefault();
                            void responder(c);
                          }}
                        >
                          <textarea
                            autoFocus
                            rows={3}
                            value={rascunhos[c.id] ?? ""}
                            onChange={(e) => setRascunhos((atual) => ({ ...atual, [c.id]: e.target.value.slice(0, 2000) }))}
                            placeholder="Escreva sua resposta…"
                            className="w-full resize-y rounded-lg px-2 py-1.5 text-[14px] leading-6 text-[var(--ks-color-text-primary)] outline-none"
                          />
                          <div className="flex items-center justify-between gap-2 px-1 pb-0.5">
                            <span className="text-[12px] text-[var(--ks-color-text-muted)]">Aparece para todos os clientes como {dados.nomeDaLoja}.</span>
                            <span className="flex gap-2">
                              <button type="button" className="ks-button ks-button-soft" onClick={() => setRespondendo(null)}>
                                Cancelar
                              </button>
                              <button type="submit" className="ks-button ks-button-primary" disabled={ocupado === c.id || !(rascunhos[c.id] ?? "").trim()}>
                                {ocupado === c.id ? <Loader2 size={15} className="animate-spin" /> : null}
                                Responder
                              </button>
                            </span>
                          </div>
                        </form>
                      ) : (
                        <div className="mt-3 flex flex-wrap gap-2">
                          <button
                            type="button"
                            onClick={() => setRespondendo(c.id)}
                            className="inline-flex h-8 items-center gap-1.5 rounded-full bg-[color:rgba(95,49,214,0.1)] px-3.5 text-[12.5px] font-bold text-[var(--ks-brand-600)] transition hover:bg-[color:rgba(95,49,214,0.16)]"
                          >
                            <MessageSquare size={13} />
                            Responder
                          </button>
                          {c.status === "pendente" ? (
                            <button type="button" className={botao} disabled={Boolean(ocupado)} onClick={() => void mudar(c.id, "publicado")}>
                              <Check size={13} />
                              Aprovar
                            </button>
                          ) : null}
                          {c.status === "oculto" ? (
                            <button type="button" className={botao} disabled={Boolean(ocupado)} onClick={() => void mudar(c.id, "publicado")}>
                              <Eye size={13} />
                              Mostrar de novo
                            </button>
                          ) : (
                            <button type="button" className={botao} disabled={Boolean(ocupado)} onClick={() => void mudar(c.id, "oculto")}>
                              <EyeOff size={13} />
                              Ocultar
                            </button>
                          )}
                          <button type="button" className={botao} disabled={Boolean(ocupado)} onClick={() => apagar(c.id, true)}>
                            <Trash2 size={13} />
                            Apagar
                          </button>
                          <Link href={`/dashboard/digitais/cursos/${c.curso.id}`} className="inline-flex h-8 items-center px-1 text-[12.5px] font-semibold text-[var(--ks-brand-600)] hover:underline">
                            Abrir o conteúdo
                          </Link>
                        </div>
                      )
                    ) : null}
                  </div>
                </li>
              );
            })}
          </ul>
        ) : (
          <div className="flex flex-col items-center gap-2 px-6 py-14 text-center">
            <span className="flex h-12 w-12 items-center justify-center rounded-2xl bg-[color:rgba(95,49,214,0.1)] text-[var(--ks-brand-600)]">
              <MessageSquare size={22} />
            </span>
            <p className="max-w-md text-[14px] text-[var(--ks-color-text-muted)]">{VAZIO[filtro]}</p>
          </div>
        )}
        {dados.maisAntigos ? (
          <div className="border-t border-[var(--ks-color-border-subtle)] p-3 text-center">
            <button type="button" className="ks-button ks-button-soft" onClick={() => void maisAntigos()} disabled={carregandoMais}>
              {carregandoMais ? <Loader2 size={15} className="animate-spin" /> : null}
              Ver mais antigos
            </button>
          </div>
        ) : null}
      </section>

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