"use client";
import { memo, useEffect, useRef, useState } from "react";
import { UserAvatar } from "./UserAvatar";
import Link from "next/link";
import { UserNameMenu } from "./UserNameMenu";

type CommentAuthor = {
  userId: string;
  nickname: string | null;
  profileImage: string | null;
};

type Comment = {
  id: string;
  parentId: string | null;
  depth: number;
  content: string;
  isAnonymous: boolean;
  isSecret: boolean;
  author: CommentAuthor | null;
  anonId?: string;
  createdAt: string;
  updatedAt: string;
  replies: Comment[];
};

type Props = {
  postId: string;
};

type CommentItemProps = {
  comment: Comment;
  depth?: number;
  expandedReplies: Set<string>;
  toggleReplies: (commentId: string) => void;
  replyingTo: string | null;
  setReplyingTo: (id: string | null) => void;
  replyContents: Record<string, string>;
  setReplyContents: React.Dispatch<React.SetStateAction<Record<string, string>>>;
  handleSubmitReply: (parentId: string | null) => void;
  replySecretFlags: Record<string, boolean>;
  setReplySecretFlags: React.Dispatch<React.SetStateAction<Record<string, boolean>>>;
};

function formatDate(dateString: string) {
  const date = new Date(dateString);
  const now = new Date();
  const diff = now.getTime() - date.getTime();
  const minutes = Math.floor(diff / 60000);
  const hours = Math.floor(diff / 3600000);
  const days = Math.floor(diff / 86400000);

  if (minutes < 1) return "방금 전";
  if (minutes < 60) return `${minutes}분 전`;
  if (hours < 24) return `${hours}시간 전`;
  if (days < 7) return `${days}일 전`;
  return date.toLocaleDateString();
}

// 개별 댓글 아이템: 부모 렌더 시 타입이 바뀌어 리마운트되지 않도록 파일 최상위에 선언하고 memo 처리
const CommentItem = memo(function CommentItem({
  comment,
  depth = 0,
  expandedReplies,
  toggleReplies,
  replyingTo,
  setReplyingTo,
  replyContents,
  setReplyContents,
  handleSubmitReply,
  replySecretFlags,
  setReplySecretFlags,
}: CommentItemProps) {
  const canReply = depth < 2; // 최대 3단계까지만
  const hasReplies = comment.replies && comment.replies.length > 0;
  const isExpanded = expandedReplies.has(comment.id);
  const isReplyingHere = replyingTo === comment.id;
  const replyRef = useRef<HTMLTextAreaElement | null>(null);

  // 답글 폼이 열릴 때만 포커스를 보장
  useEffect(() => {
    if (isReplyingHere) {
      replyRef.current?.focus();
    }
  }, [isReplyingHere]);

  return (
    <div className={`${depth > 0 ? "ml-8 border-l-2 border-neutral-200 pl-4" : ""}`}>
      <div className="flex gap-3 py-3">
        <UserAvatar
          src={comment.author?.profileImage}
          alt={comment.author?.nickname || "익명"}
          width={40}
          height={40}
          className="rounded-full shrink-0"
        />
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 mb-1">
            <span className="text-sm font-semibold text-neutral-900">
              {/* 닉네임 드롭다운 */}
              {/* 익명 댓글이면 드롭다운 없이 표시 */}
              {comment.isAnonymous ? (
                `익명${comment.anonId}`
              ) : (
                <UserNameMenu userId={comment.author?.userId} nickname={comment.author?.nickname} />
              )}
            </span>
            <span className="text-xs text-neutral-500">{formatDate(comment.createdAt)}</span>
            {comment.updatedAt !== comment.createdAt && (
              <span className="text-xs text-neutral-400">(수정됨)</span>
            )}
          </div>
          <div className="text-sm text-neutral-700 mb-2 whitespace-pre-wrap break-words">
            {comment.content}
          </div>
          <div className="flex items-center gap-3">
            {canReply && (
              <button
                onClick={() => {
                  setReplyingTo(comment.id);
                  setReplyContents((prev) => ({ ...prev, [comment.id]: prev[comment.id] ?? "" }));
                }}
                className="text-xs text-neutral-500 hover:text-neutral-900"
              >
                답글
              </button>
            )}
            {hasReplies && (
              <button
                onClick={() => toggleReplies(comment.id)}
                className="text-xs text-neutral-500 hover:text-neutral-900"
              >
                {isExpanded ? "답글 숨기기" : `답글 ${comment.replies.length}개`}
              </button>
            )}
          </div>
          
          {/* 답글 입력 폼 */}
          {isReplyingHere && (
            <div className="mt-3 p-3 bg-neutral-50 rounded-lg">
              <textarea
                ref={replyRef}
                value={replyContents[comment.id] ?? ""}
                onChange={(e) => setReplyContents((prev) => ({ ...prev, [comment.id]: e.target.value }))}
                placeholder="답글을 입력하세요..."
                className="w-full p-2 border border-neutral-300 rounded-md text-sm resize-none focus:outline-none focus:ring-2 focus:ring-neutral-400"
                rows={3}
              />
              <div className="flex items-center justify-between mt-2">
                <label className="flex items-center gap-2 text-xs text-neutral-600">
                  <input
                    type="checkbox"
                    checked={!!replySecretFlags[comment.id]}
                    onChange={(e) =>
                      setReplySecretFlags((prev) => ({ ...prev, [comment.id]: e.target.checked }))
                    }
                  />
                  비밀 댓글
                </label>
                <div className="flex gap-2">
                <button
                  onClick={() => {
                    setReplyingTo(null);
                    setReplyContents((prev) => {
                      const next = { ...prev };
                      delete next[comment.id];
                      return next;
                    });
                      setReplySecretFlags((prev) => {
                        const next = { ...prev };
                        delete next[comment.id];
                        return next;
                      });
                  }}
                  className="px-3 py-1 text-xs border border-neutral-300 rounded-md hover:bg-neutral-100"
                >
                  취소
                </button>
                <button
                  onClick={() => handleSubmitReply(comment.id)}
                  className="px-3 py-1 text-xs bg-neutral-900 text-white rounded-md hover:bg-neutral-800"
                >
                  등록
                </button>
                </div>
              </div>
            </div>
          )}
        </div>
      </div>

      {/* 대댓글 목록 */}
      {hasReplies && isExpanded && (
        <div className="mt-2">
          {comment.replies.map((reply) => (
            <CommentItem
              key={reply.id}
              comment={reply}
              depth={depth + 1}
              expandedReplies={expandedReplies}
              toggleReplies={toggleReplies}
              replyingTo={replyingTo}
              setReplyingTo={setReplyingTo}
              replyContents={replyContents}
              setReplyContents={setReplyContents}
              handleSubmitReply={handleSubmitReply}
              replySecretFlags={replySecretFlags}
              setReplySecretFlags={setReplySecretFlags}
            />
          ))}
        </div>
      )}
    </div>
  );
});

export function CommentSection({ postId }: Props) {
  const [comments, setComments] = useState<Comment[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [replyingTo, setReplyingTo] = useState<string | null>(null);
  const [newContent, setNewContent] = useState("");
  const [replyContents, setReplyContents] = useState<Record<string, string>>({});
  const [expandedReplies, setExpandedReplies] = useState<Set<string>>(new Set());
  const [newIsSecret, setNewIsSecret] = useState(false);
  const [replySecretFlags, setReplySecretFlags] = useState<Record<string, boolean>>({});

  useEffect(() => {
    loadComments();
  }, [postId]);

  async function loadComments() {
    try {
      const res = await fetch(`/api/posts/${postId}/comments`);
      if (!res.ok) return;
      const data = await res.json();
      setComments(data.comments || []);
    } catch (e) {
      console.error(e);
    } finally {
      setIsLoading(false);
    }
  }

  async function handleSubmitReply(parentId: string | null) {
    const content = parentId ? (replyContents[parentId] ?? "") : newContent;
    if (!content.trim()) return;
    
    try {
      const res = await fetch("/api/comments", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          postId,
          parentId,
          content,
          isSecret: parentId ? !!replySecretFlags[parentId] : newIsSecret,
        }),
      });
      
      if (!res.ok) {
        const error = await res.json();
        alert(error.error || "댓글 작성 실패");
        return;
      }
      
      if (parentId) {
        setReplyContents((prev) => {
          const next = { ...prev };
          delete next[parentId!];
          return next;
        });
        setReplySecretFlags((prev) => {
          const next = { ...prev };
          delete next[parentId!];
          return next;
        });
      } else {
        setNewContent("");
        setNewIsSecret(false);
      }
      setReplyingTo(null);
      loadComments();
    } catch (e) {
      console.error(e);
      alert("댓글 작성 실패");
    }
  }

  function toggleReplies(commentId: string) {
    const newExpanded = new Set(expandedReplies);
    if (newExpanded.has(commentId)) {
      newExpanded.delete(commentId);
    } else {
      newExpanded.add(commentId);
    }
    setExpandedReplies(newExpanded);
  }

  if (isLoading) {
    return (
      <section className="rounded-xl overflow-hidden bg-white p-4">
        <div className="text-center text-neutral-500 py-8">댓글을 불러오는 중...</div>
      </section>
    );
  }

  return (
    <section 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">댓글 {comments.length}</h2>
      </header>
      
      <div className="p-4">
        {/* 댓글 입력 폼 */}
        <div className="mb-6 pb-6 border-b border-neutral-200">
          <textarea
            value={newContent}
            onChange={(e) => setNewContent(e.target.value)}
            placeholder="댓글을 입력하세요..."
            className="w-full p-3 border border-neutral-300 rounded-lg text-sm resize-none focus:outline-none focus:ring-2 focus:ring-neutral-400"
            rows={4}
          />
          <div className="flex items-center justify-between mt-2">
            <label className="flex items-center gap-2 text-sm text-neutral-700">
              <input
                type="checkbox"
                checked={newIsSecret}
                onChange={(e) => setNewIsSecret(e.target.checked)}
              />
              비밀 댓글
            </label>
            <button
              onClick={() => handleSubmitReply(null)}
              disabled={!newContent.trim()}
              className="px-4 py-2 text-sm bg-neutral-900 text-white rounded-md hover:bg-neutral-800 disabled:opacity-50 disabled:cursor-not-allowed"
            >
              등록
            </button>
          </div>
        </div>

        {/* 댓글 목록 */}
        {comments.length === 0 ? (
          <div className="text-center text-neutral-500 py-8">댓글이 없습니다.</div>
        ) : (
          <div className="space-y-0">
            {comments.map((comment) => (
              <CommentItem
                key={comment.id}
                comment={comment}
                expandedReplies={expandedReplies}
                toggleReplies={toggleReplies}
                replyingTo={replyingTo}
                setReplyingTo={setReplyingTo}
                replyContents={replyContents}
                setReplyContents={setReplyContents}
                handleSubmitReply={handleSubmitReply}
                replySecretFlags={replySecretFlags}
                setReplySecretFlags={setReplySecretFlags}
              />
            ))}
          </div>
        )}
      </div>
    </section>
  );
}

