import { useEffect, useState } from "react";
import { dict, type Lang } from "@/lib/i18n";
import { relativeTime } from "@/lib/format";
import {
  listComments,
  postComment,
  getSessionNickname,
  rerollSessionNickname,
  getDeviceId,
  ApiError,
} from "@/lib/api";
import type { Comment } from "@/lib/types";

const FIRST = 3; // 처음 보여줄 최신 댓글 수
const PAGE = 10; // "더보기" 한 번에 더 불러올 수

// 한 댓글을 식별하는 합성 키 (id 비노출이라 시각+내용으로 dedup/렌더)
const keyOf = (c: Comment) => `${c.createdAt}|${c.nickname}|${c.body}`;

// 경기별 한마디(댓글) — 완전 익명. 최신 3개 + 더보기/접기.
export default function Comments({
  matchId,
  lang,
}: {
  matchId: string;
  lang: Lang;
}) {
  const t = dict(lang);
  const [items, setItems] = useState<Comment[]>([]);
  const [total, setTotal] = useState(0);
  const [cursor, setCursor] = useState(0); // 서버에서 페이징으로 받은 개수
  const [loadingMore, setLoadingMore] = useState(false);
  const [expanded, setExpanded] = useState(false);

  const [body, setBody] = useState("");
  const [nickname, setNickname] = useState(""); // 세션 닉(캐싱)
  const [posting, setPosting] = useState(false);
  const [error, setError] = useState("");

  useEffect(() => {
    let alive = true;
    listComments(matchId, FIRST, 0)
      .then((res) => {
        if (!alive) return;
        setItems(res.items);
        setTotal(res.total);
        setCursor(res.items.length);
      })
      .catch(() => {});
    getSessionNickname(matchId)
      .then((n) => alive && setNickname(n))
      .catch(() => {});
    return () => {
      alive = false;
    };
  }, [matchId]);

  const visible = expanded ? items : items.slice(0, FIRST);
  const unloaded = Math.max(0, total - items.length);
  const hiddenWhenCollapsed = Math.max(0, total - FIRST);

  async function showMore() {
    setExpanded(true);
    if (items.length <= FIRST && unloaded > 0) await loadMore();
  }

  async function loadMore() {
    if (loadingMore) return;
    setLoadingMore(true);
    try {
      const res = await listComments(matchId, PAGE, cursor);
      setItems((prev) => {
        const seen = new Set(prev.map(keyOf));
        return [...prev, ...res.items.filter((c) => !seen.has(keyOf(c)))];
      });
      setTotal(res.total);
      setCursor((c) => c + res.items.length);
    } catch {
      /* 조용히 무시 — 다시 누르면 재시도 */
    } finally {
      setLoadingMore(false);
    }
  }

  async function reroll() {
    try {
      const n = await rerollSessionNickname(matchId);
      setNickname(n);
    } catch {
      /* 무시 */
    }
  }

  async function submit() {
    const text = body.trim();
    if (posting || !text) return;
    setError("");
    setPosting(true);
    try {
      const created = await postComment(matchId, {
        deviceId: getDeviceId(),
        nickname,
        body: text,
      });
      setItems((prev) => [created, ...prev]); // 낙관적: 맨 위에 즉시 표시
      setTotal((n) => n + 1);
      setBody("");
    } catch (e) {
      if (e instanceof ApiError && e.status === 429) setError(t.commentCooldown);
      else setError(t.commentError);
    } finally {
      setPosting(false);
    }
  }

  return (
    <section className="mt-7 rounded-2xl border border-[var(--line-d)] bg-[var(--bg2)] p-4">
      {/* 헤더 */}
      <div className="flex items-baseline gap-2">
        <h2 className="text-[17px] font-extrabold text-white">
          💬 {t.commentsTitle}
        </h2>
        <span className="text-[13px] font-bold text-white/45">
          {t.commentsCount(total)}
        </span>
      </div>

      {/* 입력 */}
      <div className="mt-3 space-y-2">
        {nickname && (
          <p className="flex items-center gap-1.5 text-[12px] font-bold text-white/45">
            ⚽ {t.commentAs}{" "}
            <span className="text-[var(--green)]">{nickname}</span>
            <button
              type="button"
              onClick={reroll}
              title={t.commentReroll}
              aria-label={t.commentReroll}
              className="grid h-5 w-5 place-items-center rounded-full text-[13px] leading-none text-white/45 transition hover:text-white active:rotate-180"
            >
              ↻
            </button>
          </p>
        )}
        <div className="flex items-end gap-2">
          <textarea
            value={body}
            onChange={(e) => setBody(e.target.value.slice(0, 200))}
            placeholder={t.commentPh}
            rows={2}
            maxLength={200}
            className="min-h-[44px] flex-1 resize-none rounded-lg border border-[var(--line-d)] bg-[#0f1217] px-3 py-2.5 text-[15px] text-white outline-none focus:border-[var(--green)]"
          />
          <button
            type="button"
            onClick={submit}
            disabled={posting || !body.trim()}
            className="shrink-0 rounded-lg bg-[var(--green)] px-4 py-2.5 text-[15px] font-extrabold text-black transition active:scale-[0.98] disabled:opacity-40"
          >
            {t.commentSubmit}
          </button>
        </div>
        <div className="flex items-center justify-between">
          {error ? (
            <span className="text-[12px] font-bold text-red-400">{error}</span>
          ) : (
            <span />
          )}
          <span className="text-[11px] tabular-nums text-white/35">
            {body.length}/200
          </span>
        </div>
      </div>

      {/* 목록 */}
      {items.length === 0 ? (
        <p className="mt-4 py-3 text-center text-[13px] text-white/40">
          {t.commentEmpty}
        </p>
      ) : (
        <ul
          className={`mt-4 divide-y divide-[var(--line-d)] ${
            expanded ? "max-h-[360px] overflow-y-auto pr-1 scroll-dark" : ""
          }`}
        >
          {visible.map((c, i) => (
            <li key={`${keyOf(c)}-${i}`} className="py-3 first:pt-0">
              <div className="flex items-baseline gap-2">
                <span className="text-[13px] font-extrabold text-[var(--green)]">
                  {c.nickname}
                </span>
                <span className="text-[11px] text-white/35">
                  {relativeTime(c.createdAt, lang)}
                </span>
              </div>
              <p className="mt-1 whitespace-pre-wrap break-words text-[14px] leading-snug text-white/90">
                {c.body}
              </p>
            </li>
          ))}
        </ul>
      )}

      {/* 더보기 / 접기 */}
      {!expanded && hiddenWhenCollapsed > 0 && (
        <button
          type="button"
          onClick={showMore}
          disabled={loadingMore}
          className="mt-2 w-full rounded-lg border border-[var(--line-d)] py-2.5 text-[13px] font-bold text-white/70 transition hover:text-white disabled:opacity-50"
        >
          {t.commentMore} ▾
        </button>
      )}
      {expanded && (
        <div className="mt-2 flex gap-2">
          {unloaded > 0 && (
            <button
              type="button"
              onClick={loadMore}
              disabled={loadingMore}
              className="flex-1 rounded-lg border border-[var(--line-d)] py-2.5 text-[13px] font-bold text-white/70 transition hover:text-white disabled:opacity-50"
            >
              {t.commentMore} ▾
            </button>
          )}
          {items.length > FIRST && (
            <button
              type="button"
              onClick={() => setExpanded(false)}
              className="flex-1 rounded-lg border border-[var(--line-d)] py-2.5 text-[13px] font-bold text-white/70 transition hover:text-white"
            >
              {t.commentCollapse} ▴
            </button>
          )}
        </div>
      )}
    </section>
  );
}
