"use client";
import { useEffect, useState, useRef } from "react";
import Link from "next/link";
import { UserNameMenu } from "@/app/components/UserNameMenu";
import { useSearchParams, useRouter } from "next/navigation";

function stripHtml(html: string | null | undefined): string {
  if (!html) return "";
  return html.replace(/<[^>]*>/g, "").trim();
}

type RelatedPost = {
  id: string;
  title: string;
  createdAt: string;
  author: { nickname: string | null } | null;
  stat: { views: number; recommendCount: number; commentsCount: number } | null;
};

type Props = {
  boardId: string;
  boardName: string;
  currentPostId: string;
  pageSize?: number;
};

export function RelatedPosts({ boardId, boardName, currentPostId, pageSize = 10 }: Props) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const [page, setPage] = useState(1);
  const [posts, setPosts] = useState<RelatedPost[]>([]);
  const [stablePosts, setStablePosts] = useState<RelatedPost[]>([]);
  const [total, setTotal] = useState(0);
  const [stableTotal, setStableTotal] = useState(0);
  const [isLoading, setIsLoading] = useState(true);
  const [currentPageSize, setCurrentPageSize] = useState(pageSize);
  const [lockedMinHeight, setLockedMinHeight] = useState<number | null>(null);
  const listContainerRef = useRef<HTMLDivElement>(null);

  // URL에서 page 파라미터 읽기
  useEffect(() => {
    const pageParam = searchParams.get("relatedPage");
    if (pageParam) {
      const parsed = parseInt(pageParam, 10);
      if (!isNaN(parsed) && parsed > 0) {
        setPage(parsed);
      }
    }
  }, [searchParams]);

  // pageSize 파라미터 읽기
  useEffect(() => {
    const sizeParam = searchParams.get("relatedPageSize");
    if (sizeParam) {
      const parsed = parseInt(sizeParam, 10);
      if (!isNaN(parsed) && parsed > 0 && parsed <= 100) {
        setCurrentPageSize(parsed);
      }
    }
  }, [searchParams]);

  // 게시글 목록 가져오기
  useEffect(() => {
    let isMounted = true;
    setIsLoading(true);
    (async () => {
      try {
        const params = new URLSearchParams({
          boardId,
          page: String(page),
          pageSize: String(currentPageSize),
          sort: "recent",
        });
        const res = await fetch(`/api/posts?${params.toString()}`);
        if (!res.ok) return;
        const data = await res.json();
        if (!isMounted) return;
        // 현재 게시글 제외
        const filtered = data.items.filter((p: RelatedPost) => p.id !== currentPostId);
        const filteredTotal = Math.max(0, data.total - 1);
        setPosts(filtered);
        setTotal(filteredTotal);
        // 로딩이 끝나면 안정적인 데이터로 업데이트
        if (filtered.length > 0 || filteredTotal === 0) {
          setStablePosts(filtered);
          setStableTotal(filteredTotal);
        }
      } catch (e) {
        console.error(e);
      } finally {
        if (isMounted) {
          setIsLoading(false);
        }
      }
    })();
    return () => {
      isMounted = false;
    };
  }, [boardId, currentPostId, page, currentPageSize]);

  // 로딩이 끝나면 높이 고정 해제
  useEffect(() => {
    if (!isLoading) {
      setLockedMinHeight(null);
    }
  }, [isLoading]);

  // 이전 데이터 유지 (깜빡임 방지)
  useEffect(() => {
    if (posts.length > 0 || total > 0) {
      setStablePosts(posts);
      setStableTotal(total);
    }
  }, [posts, total]);

  const displayPosts = stablePosts.length > 0 ? stablePosts : posts;
  const displayTotal = stableTotal > 0 ? stableTotal : total;
  const totalPages = Math.max(1, Math.ceil(displayTotal / currentPageSize));

  // 높이 고정 함수
  const lockHeight = () => {
    const el = listContainerRef.current;
    if (!el) return;
    const h = el.offsetHeight;
    if (h > 0) setLockedMinHeight(h);
  };

  const handlePageChange = (newPage: number) => {
    lockHeight();
    setPage(newPage);
    const newSp = new URLSearchParams(searchParams.toString());
    newSp.set("relatedPage", String(newPage));
    router.push(`?${newSp.toString()}`, { scroll: false });
  };

  const handlePageSizeChange = (newSize: number) => {
    lockHeight();
    setCurrentPageSize(newSize);
    setPage(1);
    const newSp = new URLSearchParams(searchParams.toString());
    newSp.set("relatedPageSize", String(newSize));
    newSp.set("relatedPage", "1");
    router.push(`?${newSp.toString()}`, { scroll: false });
  };

  const isEmpty = !isLoading && displayPosts.length === 0 && stablePosts.length === 0;

  return (
    <section id="related-posts" className="rounded-xl overflow-hidden bg-white">
      <header className="px-4 py-3 border-b border-neutral-200">
        <h2 className="text-lg font-bold text-neutral-900">{boardName}</h2>
      </header>
      
      {/* 빈 상태 */}
      {isEmpty && (
        <div className="px-4 py-8 text-center text-sm text-neutral-500">게시글이 없습니다.</div>
      )}

      {/* 리스트 컨테이너 (높이 고정) */}
      <div ref={listContainerRef} style={{ minHeight: lockedMinHeight ? `${lockedMinHeight}px` : undefined }}>
        <ul className="divide-y divide-[#ececec]">
          {displayPosts.map((p) => {
            const postDate = new Date(p.createdAt);
            return (
              <li key={p.id} className="px-4 py-2.5 hover:bg-neutral-50 transition-colors">
                <Link href={`/posts/${p.id}`} className="block">
                  <div className="grid grid-cols-1 md:grid-cols-[1fr_120px_120px_80px] items-center gap-2">
                    <div className="min-w-0">
                      <div className="truncate text-[15px] md:text-base text-neutral-900">
                        {stripHtml(p.title)}
                      </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="truncate max-w-[84px]">
                        <UserNameMenu userId={(p as any).author?.userId} nickname={p.author?.nickname} />
                      </span>
                    </div>
                    <div className="md:w-[120px] text-[11px] text-[#8c8c8c] text-center flex items-center justify-center gap-3">
                      <span>조회 {p.stat?.views ?? 0}</span>
                      <span>추천 {p.stat?.recommendCount ?? 0}</span>
                      <span>댓글 {p.stat?.commentsCount ?? 0}</span>
                    </div>
                    <div className="md:w-[80px] text-[11px] text-neutral-500 text-right hidden md:block">
                      {postDate.toLocaleDateString()}
                    </div>
                  </div>
                </Link>
              </li>
            );
          })}
        </ul>
      </div>

      {/* 페이지네이션 */}
      <div className="mt-4 flex items-center justify-between px-4 pb-4">
        <div className="flex items-center gap-2">
          {/* Previous */}
          <button
            onClick={() => handlePageChange(Math.max(1, page - 1))}
            disabled={page <= 1}
            className="h-9 px-3 rounded-md border border-neutral-300 bg-white text-sm disabled:opacity-50 cursor-pointer hover:bg-neutral-100"
          >
            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={() => handlePageChange(n)}
                    aria-current={n === page ? "page" : undefined}
                    className={`h-9 w-9 rounded-md border cursor-pointer ${n === page ? "border-neutral-300 text-[#f94b37] font-semibold hover:bg-neutral-100" : "border-neutral-300 text-neutral-900 hover:bg-neutral-100"}`}
                  >
                    {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={() => handlePageChange(Math.min(totalPages, page + 1))}
            disabled={page >= totalPages}
            className="h-9 px-3 rounded-md border border-neutral-300 bg-white text-sm disabled:opacity-50 cursor-pointer hover:bg-neutral-100"
          >
            Next
          </button>
        </div>
        <div className="flex items-center gap-2">
          <span className="text-xs text-neutral-600">표시 개수</span>
          <select
            value={currentPageSize}
            onChange={(e) => handlePageSizeChange(parseInt(e.target.value, 10))}
            className="h-[36px] px-[12px] rounded-[6px] border border-[#d5d5d5] bg-white text-[14px] text-[#161616] cursor-pointer hover:bg-neutral-100"
          >
            <option value="10">10</option>
            <option value="20">20</option>
            <option value="30">30</option>
            <option value="50">50</option>
          </select>
        </div>
      </div>
    </section>
  );
}

