"use client";

import React, { useEffect, useState, useCallback } from "react";
import useInfiniteScroll from "@/hooks/useInfiniteScroll";
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 { cn } from "@/lib/utils";
import CaptionWithMentions from "@/components/posts/CaptionWithMentions";
import { useTranslation } from "react-i18next";

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

export interface PostComment {
  _id: string;
  comment: string;
  rating: number | null;
  createdAt: string;
  status: string;
  user: CommentUser;
  project: string | null;
  post_id?: string;
  postId?: string;
  parent_id?: string | null;
  likesCount?: number;
  is_liked?: boolean;
  replies?: PostComment[];
}

type PostCommentsContentProps = {
  userId: string;
  postId?: string;
  variant?: "modal" | "sheet";
  onClose?: () => void;
  className?: string;
};

function CommentLikeButton({
  comment,
  onUpdate,
}: {
  comment: PostComment;
  onUpdate: (id: string, patch: Partial<PostComment>) => void;
}) {
  const { t } = useTranslation("common");
  const { request } = useAxios();
  const requireAuth = useRequireAuth();
  const [busy, setBusy] = useState(false);

  const toggle = async () => {
    if (!requireAuth() || busy) return;
    setBusy(true);
    const optimistic = !comment.is_liked;
    const nextCount = (comment.likesCount || 0) + (optimistic ? 1 : -1);
    onUpdate(comment._id, { is_liked: optimistic, likesCount: Math.max(0, nextCount) });
    try {
      const res = await request<{ is_liked?: boolean; likesCount?: number }>(
        "POST",
        "/users/comments/like",
        { commentId: comment._id },
        { noToast: true }
      );
      onUpdate(comment._id, {
        is_liked: res?.is_liked ?? optimistic,
        likesCount: res?.likesCount ?? nextCount,
      });
    } catch {
      onUpdate(comment._id, {
        is_liked: comment.is_liked,
        likesCount: comment.likesCount,
      });
    } finally {
      setBusy(false);
    }
  };

  return (
    <button
      type="button"
      onClick={toggle}
      disabled={busy}
      className={cn(
        "flex items-center gap-1 text-xs transition active:scale-95",
        comment.is_liked ? "text-red-500" : "text-neutral-400"
      )}
      aria-label={t("posts.likeComment")}
    >
      <BoldIcon
        name={comment.is_liked ? "heart" : "heart"}
        size={14}
        tinted
        className={comment.is_liked ? "text-red-500" : "text-neutral-400"}
      />
      {(comment.likesCount ?? 0) > 0 ? (
        <span className="tabular-nums">{comment.likesCount}</span>
      ) : null}
    </button>
  );
}

function CommentRow({
  item,
  onReply,
  onLikeUpdate,
  nested = false,
}: {
  item: PostComment;
  onReply: (c: PostComment) => void;
  onLikeUpdate: (id: string, patch: Partial<PostComment>) => void;
  nested?: boolean;
}) {
  const { t } = useTranslation("common");
  return (
    <div className={cn("mb-3 flex gap-2", nested && "mr-8 mt-2")}>
      <ProfileAvatar
        src={item.user?.profile_image}
        alt={item.user?.user_name || t("common.user")}
        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.rating != null && item.rating > 0 ? (
            <span className="text-amber-500">★ {item.rating}</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">{item.createdAt}</span>
          <button
            type="button"
            onClick={() => onReply(item)}
            className="text-xs font-semibold text-neutral-500 active:text-neutral-800 dark:active:text-white"
          >
            {t("posts.reply")}
          </button>
          <CommentLikeButton comment={item} onUpdate={onLikeUpdate} />
        </div>
        {item.replies?.map((reply) => (
          <CommentRow
            key={reply._id}
            item={reply}
            onReply={onReply}
            onLikeUpdate={onLikeUpdate}
            nested
          />
        ))}
      </div>
    </div>
  );
}

export default function PostCommentsContent({
  userId,
  postId,
  variant = "modal",
  onClose,
  className,
}: PostCommentsContentProps) {
  const { t } = useTranslation("common");
  const [hasRatedProfile, setHasRatedProfile] = useState(false);
  const [newMessage, setNewMessage] = useState("");
  const [rating, setRating] = useState(0);
  const [replyTo, setReplyTo] = useState<PostComment | null>(null);
  const [localComments, setLocalComments] = useState<PostComment[]>([]);
  const { request } = useAxios();
  const requireAuth = useRequireAuth();

  const { data, containerRef, isFetchingNextPage, refetch } = useInfiniteScroll({
    endpoint: "/users/comments",
    queryKey: ["comments", userId, postId || "profile"],
    params: postId
      ? { user_id: userId, post_id: postId }
      : { user_id: userId },
  });

  useEffect(() => {
    const hasRated = data?.pages?.[0]?.has_rated;
    if (typeof hasRated === "boolean") setHasRatedProfile(hasRated);
  }, [data]);

  useEffect(() => {
    const all =
      data?.pages?.flatMap((page) => page?.comments || []) || [];
    const filtered = postId
      ? all.filter(
          (c: PostComment) => c.post_id === postId || c.postId === postId
        )
      : all;
    setLocalComments(filtered);
  }, [data, postId]);

  const patchComment = useCallback((id: string, patch: Partial<PostComment>) => {
    const apply = (list: PostComment[]): PostComment[] =>
      list.map((c) => {
        if (c._id === id) return { ...c, ...patch };
        if (c.replies?.length) {
          return { ...c, replies: apply(c.replies) };
        }
        return c;
      });
    setLocalComments((prev) => apply(prev));
  }, []);

  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 body: Record<string, unknown> = {
        comment: newMessage,
        user_id: userId,
      };
      if (!replyTo && !hasRatedProfile && rating) body.rate = rating;
      if (postId) body.post_id = postId;
      if (replyTo) body.parent_id = replyTo._id;

      await request("POST", "/users/comments", body);
      if (!replyTo && !hasRatedProfile && rating) setHasRatedProfile(true);
      setNewMessage("");
      setRating(0);
      setReplyTo(null);
      refetch?.();
    } catch (error) {
      console.error(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">
        {localComments.length === 0 && !isFetchingNextPage ? (
          <p className="py-8 text-center text-gray-500">{t("posts.noComments")}</p>
        ) : (
          localComments.map((item) => (
            <div
              key={item._id}
              className="border-b border-neutral-100 pb-2 dark:border-neutral-800"
            >
              <CommentRow
                item={item}
                onReply={setReplyTo}
                onLikeUpdate={patchComment}
              />
            </div>
          ))
        )}
      </div>

      <div
        className={cn(
          "shrink-0 border-t border-neutral-200/60 px-4 pt-3 dark:border-neutral-700",
          composerPad
        )}
      >
        {replyTo ? (
          <div className="mb-2 flex items-center justify-between rounded-lg bg-neutral-100 px-3 py-1.5 text-xs dark:bg-neutral-900">
            <span>
              {t("posts.replyTo", { name: replyTo.user?.user_name ?? "" })}
            </span>
            <button type="button" onClick={() => setReplyTo(null)}>
              ✕
            </button>
          </div>
        ) : null}
        {!hasRatedProfile && !replyTo && (
          <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={replyTo ? t("posts.writeReply") : t("posts.writeComment")}
            onChange={(e) => {
              if (e.target.value.length <= 500) setNewMessage(e.target.value);
            }}
            className="flex-1"
          />
        </div>
      </div>
    </div>
  );
}
