"use client";

import React, {
  useCallback,
  useEffect,
  useRef,
  useState,
} from "react";
import RoundedInput from "@/components/elements/RoundedInput";
import useAxios from "@/hooks/useAxios";
import toast from "react-hot-toast";
import Rate from "rc-rate";
import "rc-rate/assets/index.css";
import "@/styles/rc-rate-custom.css";
import BoldIcon from "@/components/ui/BoldIcon";
import ProfileAvatar from "@/components/main/ProfileAvatar";
import { useRequireAuth } from "@/lib/auth/useRequireAuth";
import { useUser } from "@/hooks/useUser";
import { useTranslation } from "react-i18next";
import { cn } from "@/lib/utils";
import CaptionWithMentions from "@/components/posts/CaptionWithMentions";

export interface CourseCommentUser {
  _id: string;
  user_name: string;
  profile_image: string | null;
  is_verified: string;
  verify_badge?: string;
}

export interface CourseComment {
  _id: string;
  comment: string;
  rate: number;
  createdAt: string;
  updatedAt?: string;
  status: string;
  user_id: CourseCommentUser | string;
  course_id: string;
  likes?: number;
  isEdited?: boolean;
}

type CourseCommentsContentProps = {
  courseId: string;
  courseName?: string;
  variant?: "modal" | "sheet";
  onClose?: () => void;
  onCommentAdded?: () => void;
  className?: string;
};

function normalizeUser(
  userId: CourseCommentUser | string,
  cache: Record<string, CourseCommentUser>,
  anonymousLabel: string
): CourseCommentUser {
  if (typeof userId === "object" && userId?.user_name) {
    return userId;
  }
  const id = typeof userId === "string" ? userId : userId?._id;
  return (
    cache[id] || {
      _id: id,
      user_name: anonymousLabel,
      profile_image: null,
      is_verified: "unverified",
    }
  );
}

function CommentRow({
  item,
  anonymousLabel,
  userLabel,
}: {
  item: CourseComment & { user: CourseCommentUser };
  anonymousLabel: string;
  userLabel: string;
}) {
  return (
    <div className="mb-3 flex gap-2">
      <ProfileAvatar
        src={item.user?.profile_image}
        alt={item.user?.user_name || userLabel}
        size="chat"
        rounded="full"
        className="shrink-0"
        userId={item.user?._id}
        verifyBadge={item.user?.verify_badge}
      />
      <div className="min-w-0 flex-1 text-sm">
        <div className="flex items-center gap-2">
          <span className="font-semibold">{item.user?.user_name}</span>
          {item.rate > 0 ? (
            <span className="text-amber-500">★ {item.rate}</span>
          ) : null}
        </div>
        <p className="mt-0.5 break-words text-neutral-800 dark:text-neutral-100">
          <CaptionWithMentions text={item.comment} />
        </p>
        <div className="mt-1 flex items-center gap-4">
          <span className="text-[11px] text-neutral-400">
            {new Date(item.createdAt).toLocaleDateString("fa-IR")}
          </span>
        </div>
      </div>
    </div>
  );
}

export default function CourseCommentsContent({
  courseId,
  courseName,
  variant = "modal",
  onClose,
  onCommentAdded,
  className,
}: CourseCommentsContentProps) {
  const { t } = useTranslation("common");
  const [newMessage, setNewMessage] = useState("");
  const [rating, setRating] = useState(0);
  const [comments, setComments] = useState<
    Array<CourseComment & { user: CourseCommentUser }>
  >([]);
  const [loading, setLoading] = useState(false);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);
  const [hasRatedCourse, setHasRatedCourse] = useState(false);
  const [usersCache, setUsersCache] = useState<Record<string, CourseCommentUser>>(
    {}
  );
  const usersCacheRef = useRef(usersCache);
  usersCacheRef.current = usersCache;

  const { request } = useAxios();
  const requireAuth = useRequireAuth();
  const currentUser = useUser();
  const containerRef = useRef<HTMLDivElement>(null);
  const observer = useRef<IntersectionObserver | null>(null);

  const fetchUserInfo = async (userId: string) => {
    if (usersCacheRef.current[userId]) return usersCacheRef.current[userId];
    try {
      const response = await request("GET", `/profile/${userId}`);
      if (response?.user) {
        const userData: CourseCommentUser = {
          _id: response.user._id,
          user_name: response.user.user_name,
          profile_image: response.user.profile_image,
          is_verified: response.user.is_verified,
        };
        setUsersCache((prev) => ({ ...prev, [userId]: userData }));
        return userData;
      }
    } catch (error) {
      console.error(`Error fetching user ${userId}:`, error);
    }
    return null;
  };

  const fetchComments = useCallback(
    async (pageNum: number, append = false) => {
      if (!courseId) return;

      setLoading(true);
      try {
        const response = await request(
          "GET",
          `/academy/course/${courseId}/comments?page=${pageNum}&limit=20&status=accepted&sortBy=createdAt&sortOrder=desc`
        );

        if (response?.success) {
          const newComments: CourseComment[] = response.data.comments || [];
          const pagination = response.data.pagination;

          const enriched = await Promise.all(
            newComments.map(async (comment) => {
              let user: CourseCommentUser;
              if (
                typeof comment.user_id === "object" &&
                comment.user_id?.user_name
              ) {
                user = comment.user_id;
              } else {
                const uid =
                  typeof comment.user_id === "string"
                    ? comment.user_id
                    : comment.user_id?._id;
                const fetched = await fetchUserInfo(uid);
                user =
                  fetched ||
                  normalizeUser(comment.user_id, usersCacheRef.current, t("common.user"));
              }
              return { ...comment, user };
            })
          );

          setComments((prev) => (append ? [...prev, ...enriched] : enriched));
          setHasMore(pagination?.hasNextPage || false);
        }
      } catch (error) {
        console.error("Error fetching comments:", error);
        toast.error(t("academy.commentsError"));
      } finally {
        setLoading(false);
      }
    },
    [courseId, request]
  );

  useEffect(() => {
    setPage(1);
    setComments([]);
    void fetchComments(1, false);
  }, [courseId, fetchComments]);

  useEffect(() => {
    if (page > 1) {
      void fetchComments(page, true);
    }
  }, [page, fetchComments]);

  useEffect(() => {
    if (!currentUser?._id) return;
    const alreadyRated = comments.some(
      (item) =>
        String(item.user?._id) === String(currentUser._id) &&
        Number(item.rate) > 0
    );
    setHasRatedCourse(alreadyRated);
  }, [comments, currentUser?._id]);

  const lastCommentRef = useCallback(
    (node: HTMLDivElement | null) => {
      if (loading) return;
      if (observer.current) observer.current.disconnect();
      observer.current = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting && hasMore) {
          setPage((prev) => prev + 1);
        }
      });
      if (node) observer.current.observe(node);
    },
    [loading, hasMore]
  );

  const sendMessageHandler = async () => {
    if (!requireAuth()) return;
    if (!newMessage.trim()) {
      toast.error(t("posts.commentRequired"));
      return;
    }
    if (newMessage.length > 500) {
      toast.error(t("posts.commentTooLong"));
      return;
    }

    try {
      const payload: Record<string, unknown> = {
        course_id: courseId,
        comment: newMessage,
      };
      if (!hasRatedCourse && rating > 0) {
        payload.rate = rating;
      }

      const response = await request("POST", "/academy/comment/create", payload);

      if (response?.success) {
        setNewMessage("");
        setRating(0);
        if (!hasRatedCourse && rating > 0) {
          setHasRatedCourse(true);
        }
        setPage(1);
        setComments([]);
        await fetchComments(1, false);
        onCommentAdded?.();
      }
    } catch (error: unknown) {
      console.error("Error sending comment:", error);
      toast.error(t("posts.commentError"));
    }
  };

  const composerPad =
    variant === "sheet"
      ? "pb-[calc(0.75rem+env(safe-area-inset-bottom))]"
      : "pb-[calc(5.5rem+env(safe-area-inset-bottom))]";

  return (
    <div className={cn("flex h-full min-h-0 flex-col", className)}>
      <div className="relative flex shrink-0 items-center justify-between border-b border-neutral-200/60 px-4 py-3 dark:border-neutral-700">
        <h3 className="flex-1 text-center font-bold">{t("posts.comments")}</h3>
        {variant === "sheet" && onClose ? (
          <button
            type="button"
            onClick={onClose}
            className="absolute left-4 flex h-8 w-8 items-center justify-center rounded-full text-neutral-500"
            aria-label={t("posts.close")}
          >
            <BoldIcon name="close-circle" size={20} tinted />
          </button>
        ) : null}
      </div>

      <div ref={containerRef} className="min-h-0 flex-1 overflow-y-auto px-4 py-3">
        {comments.length === 0 && !loading ? (
          <p className="py-8 text-center text-gray-500">{t("posts.noComments")}</p>
        ) : (
          comments.map((item, index) => (
            <div
              key={item._id}
              ref={index === comments.length - 1 ? lastCommentRef : null}
              className="border-b border-neutral-100 pb-2 dark:border-neutral-800"
            >
              <CommentRow
                item={item}
                anonymousLabel={t("common.user")}
                userLabel={t("common.user")}
              />
            </div>
          ))
        )}
        {loading ? (
          <p className="py-4 text-center text-sm text-neutral-400">
            {t("common.loading")}
          </p>
        ) : null}
      </div>

      <div
        className={cn(
          "shrink-0 border-t border-neutral-200/60 px-4 pt-3 dark:border-neutral-700",
          composerPad
        )}
      >
        {!hasRatedCourse && (
          <div className="mb-3 flex flex-col items-center gap-1">
            <span className="text-[11px] text-neutral-500">{t("posts.ratingOptional")}</span>
            <Rate
              value={rating}
              onChange={(v) => setRating(v)}
              count={5}
              style={{ fontSize: 28, color: "#f59e0b" }}
            />
          </div>
        )}
        <div className="flex items-center gap-2">
          <button
            type="button"
            onClick={sendMessageHandler}
            className="ig-dm-send-btn gentle-transition flex h-10 w-10 shrink-0 items-center justify-center rounded-full text-white active:scale-90"
          >
            <BoldIcon name="send-2" size={18} tinted className="text-current" />
          </button>
          <RoundedInput
            value={newMessage}
            placeholder={t("posts.writeComment")}
            onChange={(e) => {
              if (e.target.value.length <= 500) setNewMessage(e.target.value);
            }}
            className="flex-1"
          />
        </div>
      </div>
    </div>
  );
}
