"use client";
import useSWRInfinite from "swr/infinite";
import useSWR from "swr";
import { useEffect, useMemo, useRef, useState } from "react";
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import ViewsIcon from "@/app/svgs/ViewsIcon";
import LikeIcon from "@/app/svgs/LikeIcon";
import CommentIcon from "@/app/svgs/CommentIcon";

type Item = {
  id: string;
  title: string;
  createdAt: string;
  isPinned: boolean;
  status: string;
  stat?: { recommendCount: number; views: number; commentsCount: number } | null;
  postTags?: { tag: { name: string; slug: string } }[];
  author?: { nickname: string } | null;
};

type Resp = {
  total: number;
  page: number;
  pageSize: number;
  items: Item[];
  sort: "recent" | "popular";
};

const fetcher = (url: string) => fetch(url).then((r) => r.json());

export function PostList({ boardId, sort = "recent", q, tag, author, start, end, variant = "default", newPostHref }: { boardId?: string; sort?: "recent" | "popular"; q?: string; tag?: string; author?: string; start?: string; end?: string; variant?: "default" | "board"; newPostHref?: string }) {
  const pageSize = 10;
  const sp = useSearchParams();
  const listContainerRef = useRef<HTMLDivElement | null>(null);
  const [lockedMinHeight, setLockedMinHeight] = useState<number | null>(null);

  const getKey = (index: number, prev: Resp | null) => {
    if (prev && prev.items.length === 0) return null;
    const page = index + 1;
    const sp = new URLSearchParams({ page: String(page), pageSize: String(pageSize), sort });
    if (boardId) sp.set("boardId", boardId);
    if (q) sp.set("q", q);
    if (tag) sp.set("tag", tag);
    if (author) sp.set("author", author);
    if (start) sp.set("start", start);
    if (end) sp.set("end", end);
    return `/api/posts?${sp.toString()}`;
  };
  // default(무한 스크롤 형태)
  const { data, size, setSize, isLoading } = useSWRInfinite<Resp>(getKey, fetcher, { revalidateFirstPage: false });
  const itemsInfinite = data?.flatMap((d) => d.items) ?? [];
  const canLoadMore = (data?.at(-1)?.items.length ?? 0) === pageSize;
  const isEmptyInfinite = !isLoading && itemsInfinite.length === 0;

  // board 변형: 번호 페이지네이션
  const initialPage = useMemo(() => Math.max(1, parseInt(sp.get("page") || "1", 10)), [sp]);
  const [page, setPage] = useState(initialPage);
  useEffect(() => { setPage(initialPage); }, [initialPage]);
  const singleKey = useMemo(() => {
    if (variant !== "board") return null;
    const usp = new URLSearchParams({ page: String(page), pageSize: String(pageSize), sort });
    if (boardId) usp.set("boardId", boardId);
    if (q) usp.set("q", q);
    if (tag) usp.set("tag", tag);
    if (author) usp.set("author", author);
    if (start) usp.set("start", start);
    if (end) usp.set("end", end);
    return `/api/posts?${usp.toString()}`;
  }, [variant, page, pageSize, sort, boardId, q, tag, author, start, end]);
  const { data: singlePageResp, isLoading: isLoadingSingle } = useSWR<Resp>(singleKey, fetcher);
  const itemsSingle = singlePageResp?.items ?? [];
  const totalSingle = singlePageResp?.total ?? 0;
  const totalPages = Math.max(1, Math.ceil(totalSingle / pageSize));
  const isEmptySingle = !isLoadingSingle && itemsSingle.length === 0;

  const items = variant === "board" ? itemsSingle : itemsInfinite;
  const isEmpty = variant === "board" ? isEmptySingle : isEmptyInfinite;

  // 잠깐 높이 고정: 페이지 변경으로 재로딩될 때 현재 높이를 min-height로 유지
  const lockHeight = () => {
    const el = listContainerRef.current;
    if (!el) return;
    const h = el.offsetHeight;
    if (h > 0) setLockedMinHeight(h);
  };

  // 로딩이 끝나면 해제
  useEffect(() => {
    if (variant === "board" && !isLoadingSingle) {
      setLockedMinHeight(null);
    }
  }, [variant, isLoadingSingle]);

  const initials = (name?: string | null) => (name ? name.trim().slice(0, 1) : "익");

  return (
    <div className="w-full">
      {/* 정렬 스위치 (board 변형에서는 상단 툴바를 숨김) */}
      {variant !== "board" && (
        <div className="px-4 py-2 border-b border-neutral-200 mb-2 flex items-center gap-2">
          <span className="text-xs text-neutral-500 mr-1">정렬</span>
          <a
            className={`text-xs px-3 py-1 rounded-full border transition-colors ${
              sort === "recent" ? "bg-neutral-900 text-white border-neutral-900" : "bg-white text-neutral-700 border-neutral-300 hover:bg-neutral-100"
            }`}
            href={`${q ? "/search" : "/"}?${(() => { const p = new URLSearchParams(); if (q) p.set("q", q); if (boardId) p.set("boardId", boardId); p.set("sort", "recent"); return p.toString(); })()}`}
          >
            최신
          </a>
          <a
            className={`text-xs px-3 py-1 rounded-full border transition-colors ${
              sort === "popular" ? "bg-neutral-900 text-white border-neutral-900" : "bg-white text-neutral-700 border-neutral-300 hover:bg-neutral-100"
            }`}
            href={`${q ? "/search" : "/"}?${(() => { const p = new URLSearchParams(); if (q) p.set("q", q); if (boardId) p.set("boardId", boardId); p.set("sort", "popular"); return p.toString(); })()}`}
          >
            인기
          </a>
        </div>
      )}

      {/* 리스트 테이블 헤더 (board 변형에서는 숨김) */}
      {variant !== "board" && (
        <div className="hidden md:grid grid-cols-[20px_1fr_120px_120px_80px] items-center px-4 py-2 text-[12px] text-[#8c8c8c] bg-[#f6f4f4] border-b border-[#e6e6e6] rounded-t-xl">
          <div />
          <div>제목</div>
          <div className="text-center">작성자</div>
          <div className="text-center">지표</div>
          <div className="text-right">작성일</div>
        </div>
      )}

      {/* 빈 상태 */}
      {isEmpty && (
        <div className="h-[400px] flex items-center justify-center border-t border-b border-[#8c8c8c]">
          <p className="text-[20px] leading-[20px] text-[#161616]">글이 없습니다.</p>
        </div>
      )}

      {/* 아이템들 */}
      <div ref={listContainerRef} style={{ minHeight: lockedMinHeight ? `${lockedMinHeight}px` : undefined }}>
        <ul className="divide-y divide-[#ececec]">
          {items.map((p) => (
            <li key={p.id} className={`px-4 ${variant === "board" ? "py-2.5" : "py-3 md:py-3"} hover:bg-neutral-50 transition-colors`}>
              <div className="grid grid-cols-1 md:grid-cols-[20px_1fr_120px_120px_80px] items-center gap-2">
              {/* bullet/공지 아이콘 자리 */}
              <div className="hidden md:flex items-center justify-center text-[#f94b37]">{p.isPinned ? "★" : "•"}</div>

              <div className="min-w-0">
                <Link href={`/posts/${p.id}`} className="block truncate text-[15px] md:text-base text-neutral-900">
                  {p.isPinned && <span className="mr-2 inline-flex items-center rounded bg-orange-100 text-orange-700 px-1.5 py-0.5 text-[11px]">공지</span>}
                  {p.title}
                </Link>
                {!!p.postTags?.length && (
                  <div className="mt-1 hidden md:flex flex-wrap gap-1 text-[11px] text-neutral-500">
                    {p.postTags?.map((pt) => (
                      <Link key={pt.tag.slug} href={`/search?tag=${pt.tag.slug}`} className="hover:underline">#{pt.tag.name}</Link>
                    ))}
                  </div>
                )}
              </div>
              <div className="md:w-[120px] text-xs text-neutral-600 text-center hidden md:flex items-center justify-center gap-2">
                <span className="inline-flex items-center justify-center w-6 h-6 rounded-full bg-neutral-200 text-[11px] text-neutral-700">{initials(p.author?.nickname)}</span>
                <span className="truncate max-w-[84px]">{p.author?.nickname ?? "익명"}</span>
              </div>
              <div className="md:w-[120px] text-[11px] text-[#8c8c8c] text-center flex items-center justify-center gap-3">
                <span className="inline-flex items-center gap-1"><ViewsIcon width={16} height={16} />{p.stat?.views ?? 0}</span>
                <span className="inline-flex items-center gap-1"><LikeIcon width={16} height={16} />{p.stat?.recommendCount ?? 0}</span>
                <span className="inline-flex items-center gap-1"><CommentIcon width={16} height={16} />{p.stat?.commentsCount ?? 0}</span>
              </div>
              <div className="md:w-[80px] text-xs text-neutral-500 text-right">{new Date(p.createdAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}</div>
            </div>
            </li>
          ))}
        </ul>
      </div>

      {/* 페이지네이션 */}
      {!isEmpty && (
        variant === "board" ? (
          <div className="mt-4 flex items-center justify-between px-4">
            <div className="flex items-center gap-2">
              {/* Previous */}
              <button
              onClick={() => {
                lockHeight();
                const next = Math.max(1, page - 1);
                setPage(next);
                const nextSp = new URLSearchParams(Array.from(sp.entries()));
                nextSp.set("page", String(next));
                if (typeof window !== "undefined") {
                  window.history.replaceState(null, "", `?${nextSp.toString()}`);
                }
              }}
              disabled={page <= 1}
              className="h-9 px-3 rounded-md border border-neutral-300 bg-white text-sm disabled:opacity-50"
            >
              Previous
            </button>
            {/* Numbers with ellipsis */}
              <div className="flex items-center gap-1">
              {(() => {
                const nodes: (number | string)[] = [];
                if (totalPages <= 7) {
                  for (let i = 1; i <= totalPages; i++) nodes.push(i);
                } else {
                  nodes.push(1);
                  const start = Math.max(2, page - 1);
                  const end = Math.min(totalPages - 1, page + 1);
                  if (start > 2) nodes.push("...");
                  for (let i = start; i <= end; i++) nodes.push(i);
                  if (end < totalPages - 1) nodes.push("...");
                  nodes.push(totalPages);
                }
                return nodes.map((n, idx) =>
                  typeof n === "number" ? (
                    <button
                      key={`p-${n}-${idx}`}
                      onClick={() => {
                        lockHeight();
                        setPage(n);
                        const nextSp = new URLSearchParams(Array.from(sp.entries()));
                        nextSp.set("page", String(n));
                        if (typeof window !== "undefined") {
                          window.history.replaceState(null, "", `?${nextSp.toString()}`);
                        }
                      }}
                      aria-current={n === page ? "page" : undefined}
                      className={`h-9 w-9 rounded-md border ${n === page ? "border-neutral-300 text-[#f94b37] font-semibold" : "border-neutral-300 text-neutral-900"}`}
                    >
                      {n}
                    </button>
                  ) : (
                    <span key={`e-${idx}`} className="h-9 w-9 inline-flex items-center justify-center text-neutral-900">…</span>
                  )
                );
              })()}
              </div>
              {/* Next */}
              <button
              onClick={() => {
                lockHeight();
                const next = Math.min(totalPages, page + 1);
                setPage(next);
                const nextSp = new URLSearchParams(Array.from(sp.entries()));
                nextSp.set("page", String(next));
                if (typeof window !== "undefined") {
                  window.history.replaceState(null, "", `?${nextSp.toString()}`);
                }
              }}
              disabled={page >= totalPages}
              className="h-9 px-3 rounded-md border border-neutral-300 bg-white text-sm disabled:opacity-50"
            >
              Next
              </button>
            </div>
            {newPostHref && (
              <Link href={newPostHref} className="shrink-0">
                <button className="h-9 px-4 rounded-[10px] bg-[#f94b37] text-white text-sm border border-[#d73b29] hover:opacity-95">글쓰기</button>
              </Link>
            )}
          </div>
        ) : (
          <div className="mt-3 flex justify-center">
            <button
              className="h-9 px-4 rounded-md border border-neutral-300 bg-white text-sm hover:bg-neutral-100 disabled:opacity-50"
              disabled={!canLoadMore || isLoading}
              onClick={() => setSize(size + 1)}
            >
              {isLoading ? "로딩 중..." : canLoadMore ? "더 보기" : "끝"}
            </button>
          </div>
        )
      )}
    </div>
  );
}


