"use client";

import { useState } from "react";
import { useAppSelector } from "@/redux/hooks";
import {
  useCreateCommentMutation,
  useLazyGetCommentsQuery,
} from "@/api/blog.api";
import type { IBlogCommentsBlock } from "@/api/types/blog";
import { mapBlogComment } from "@/utils/mapBlogComment";
import { Comments, type CommentData } from "@/components/common/Comments";

interface BlogCommentsProps {
  postId: number;
  postCode: string;
  commentsCount: number;
  comments: CommentData[];
  canPost?: boolean;
  onSubscribeClick?: () => void;
}

const PER_PAGE = 20;

const BlogComments: React.FC<BlogCommentsProps> = ({
  postId,
  postCode,
  commentsCount,
  comments,
  canPost = true,
  onSubscribeClick,
}) => {
  const user = useAppSelector((state) => state.auth.user);
  const isAuthenticated = useAppSelector((state) => state.auth.isAuthenticated);
  const [createComment, { isLoading: isSubmitting }] = useCreateCommentMutation();
  const [fetchComments, { isFetching }] = useLazyGetCommentsQuery();

  const [loadedComments, setLoadedComments] = useState<CommentData[]>([]);
  const [currentPage, setCurrentPage] = useState(0);
  const [totalPages, setTotalPages] = useState(0);
  const [totalRecords, setTotalRecords] = useState(commentsCount);
  const [hasLoaded, setHasLoaded] = useState(false);

  const userAvatar =
    typeof user?.profileImage === "string" && user.profileImage.trim() !== ""
      ? user.profileImage
      : undefined;
  const userName = user?.name || "User";

  const visibleComments = hasLoaded ? loadedComments : comments;
  const headerCount = hasLoaded ? totalRecords : commentsCount;

  const applyPage = (result: IBlogCommentsBlock, reset = false) => {
    const mapped = (result.data ?? []).map(mapBlogComment);
    setLoadedComments((prev) => (reset || result.page === 1 ? mapped : [...prev, ...mapped]));
    setCurrentPage(result.page ?? 1);
    setTotalPages(result.totalPages ?? 0);
    setTotalRecords(result.totalRecords ?? 0);
    setHasLoaded(true);
  };

  const refreshComments = async () => {
    const pageToRefresh = hasLoaded ? Math.max(currentPage, 1) : 1;
    const refreshed: CommentData[] = [];
    let lastPage = pageToRefresh;
    let lastTotalPages = totalPages;
    let lastTotalRecords = totalRecords;
    for (let page = 1; page <= pageToRefresh; page++) {
      const result = await fetchComments({ postId, page, perPage: PER_PAGE }).unwrap();
      refreshed.push(...(result.data ?? []).map(mapBlogComment));
      lastPage = result.page ?? page;
      lastTotalPages = result.totalPages ?? 0;
      lastTotalRecords = result.totalRecords ?? 0;
    }
    setLoadedComments(refreshed);
    setCurrentPage(lastPage);
    setTotalPages(lastTotalPages);
    setTotalRecords(lastTotalRecords);
    setHasLoaded(true);
  };

  const handlePost = async (text: string) => {
    await createComment({ postId, postCode, content: text }).unwrap();
    await refreshComments();
  };

  const handleReply = async (text: string, parentId: number) => {
    await createComment({ postId, postCode, content: text, parentId }).unwrap();
    await refreshComments();
  };

  const handleLoadMore = async () => {
    const nextPage = hasLoaded ? currentPage + 1 : 1;
    const result = await fetchComments({ postId, page: nextPage, perPage: PER_PAGE }).unwrap();
    applyPage(result);
  };

  return (
    <Comments
      comments={visibleComments}
      totalCount={headerCount}
      hasMore={hasLoaded ? currentPage < totalPages : commentsCount > 0}
      isFetching={isFetching}
      isSubmitting={isSubmitting}
      canPost={canPost}
      userAvatar={userAvatar}
      userName={userName}
      isAuthenticated={isAuthenticated}
      onPost={handlePost}
      onReply={handleReply}
      onLoadMore={handleLoadMore}
      onSubscribeClick={onSubscribeClick}
    />
  );
};

export default BlogComments;
