'use client';

import '../style.scss';
import Image from 'next/image';
import { useState, useMemo, useCallback, useEffect, useRef, MouseEvent } from 'react';
import Loading from '@/app/component/Loading';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faThumbsUp as nThumbsUp, faThumbsDown as nThumbsDown, faFlag as nFlag, faPenToSquare, faTrashCan } from '@fortawesome/free-regular-svg-icons';
import { faThumbsUp as yThumbsUp, faThumbsDown as yThumbsDown, faFlag as yFlag, faEllipsisVertical, faLock } from '@fortawesome/free-solid-svg-icons';
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { fetchApi, formatDate } from '@/lib/utils/client';
import { isBoardAdmin } from '@/lib/utils/permission';
import useAuth from '@/hooks/useAuth';
import useErrorAlert from '@/hooks/useErrorAlert';
import { type CommentItem } from '@/types/forum/comment';
import { BoardResponse } from '@/types/response/forum/board';
import { PostResponse } from '@/types/response/forum/post';
import EditForm from './EditForm';
import Report from '@/app/(main)/(forum)/post/_component/Report';
import { Reaction } from '@/constants/forum';

type Props = {
	_board: BoardResponse; // 게시판 정보
    _post: PostResponse; // 게시글 정보
	_comment: CommentItem; // 댓글 정보
    isReplying?: boolean; // 답글 버튼 클릭 여부
	onReply: () => void;  // 답글 버튼 클릭 시
	onDelete: (commentID: number, parentID?: number) => void; // 삭제 후
    onSuccess: (comment?: CommentItem) => void; // 수정/삭제 후
	canWriteReply?: boolean; // 답글 작성 권한
	children?: React.ReactNode;
}

export default function Item({ _board, _post, _comment, isReplying, onReply, onSuccess, onDelete, canWriteReply, children } : Props)
{
	const { member, loginCheck } = useAuth();
	const { setError } = useErrorAlert();
	const [loading, setLoading] = useState<boolean>(false);
	const [isEditing, setIsEditing] = useState<boolean>(false);
	const [hasLike, setHasLike] = useState<boolean>(_comment.hasLike);
	const [hasDisLike, setHasDisLike] = useState<boolean>(_comment.hasDislike);
	const [likes, setLikes] = useState<number>(_comment.likes);
	const [dislikes, setDislikes] = useState<number>(_comment.dislikes);
	const [hasReport, setHasReport] = useState<boolean>(_comment.hasReport);
	const [report, setReport] = useState<boolean>(false);

	const isOwner = member?.id === _comment.memberID;
	const isPostOwner = member?.id === _post.memberID;
	const canManage = isOwner || isBoardAdmin(_board.boardManager, member);
	const canViewSecret = !_comment.isSecret || isOwner || isPostOwner || canManage;
	const contentRef = useRef<HTMLSpanElement>(null);
	const writerThumb = useMemo(() => _comment.writer.thumbnail ?? '/resources/thumb.gif', [_comment.writer.thumbnail]);
	const writerIcon = useMemo(() => _comment.writer.icon ?? _comment.writer.gradeImage ?? null, [_comment.writer.icon, _comment.writer.gradeImage]);
	const writerName = useMemo(() => _comment.writer.name || _comment.writer.sid, [_comment.writer.name, _comment.writer.sid]);
	const createdAt = useMemo(() => formatDate(_comment.createdAt), [_comment.createdAt]);

	// 댓글 내 파일 다운로드 클릭 핸들러
	useEffect(() => {
		const el = contentRef.current;
		if (!el) {
			return;
		}

		const handler = (e: globalThis.MouseEvent) => {
			const target = e.target as HTMLElement;
			const file = target.closest('section.file-embed') as HTMLElement;
			if (file && file.dataset.uuid) {
				window.location.href = `/api/forum/comment/file/${file.dataset.uuid}`;
			}
		};

		el.addEventListener('click', handler);
		return () => {
			el.removeEventListener('click', handler);
		};
	}, []);

	const handleStartEdit = useCallback(() => {
		if (!loginCheck()) {
			return;
		}
		if (!canManage) {
			alert('본인의 댓글만 수정할 수 있습니다.');
			return;
		}
        setIsEditing(true);
    }, [loginCheck, canManage]);

	const handleCancelEdit = useCallback(() => {
        setIsEditing(false);
    }, []);

	const handleEditSuccess = useCallback((comment?: CommentItem) => {
        setIsEditing(false);
        onSuccess(comment);
    }, [onSuccess]);

	// 좋아요/싫어요 (로딩 없이 즉시 반영)
	const handleReaction = useCallback(async (e: MouseEvent<HTMLButtonElement>) => {
		const reaction = Number(e.currentTarget.value);

		if (!loginCheck()) {
			return;
		}

		try {
			const res = await fetchApi('/api/forum/comments/' + _comment.id + '/reaction', { method: 'POST', body: { reaction } });
			if (res.success) {
				switch (reaction) {
					case Reaction.Like:
						setHasLike(prev => {
							setLikes(c => prev ? c - 1 : c + 1);
							return !prev;
						});
						setHasDisLike(prev => {
							if (prev) setDislikes(c => c - 1);
							return false;
						});
						break;
					case Reaction.Dislike:
						setHasDisLike(prev => {
							setDislikes(c => prev ? c - 1 : c + 1);
							return !prev;
						});
						setHasLike(prev => {
							if (prev) setLikes(c => c - 1);
							return false;
						});
						break;
				}
			}
		} catch (err) {
			if (err instanceof Error) {
				setError(err.message);
			}
		}
	}, [_comment.id, loginCheck, setError]);

	// 신고하기
	const handleReport = useCallback(() => {
		if (hasReport) {
			alert('이미 신고하셨습니다.');
			return;
		}

		if (!loginCheck()) {
			return;
		}

		setReport(prev => !prev);
	}, [loginCheck, hasReport]);

	// 댓글 삭제
	const handleDelete = useCallback(() => {
		if (!loginCheck()) {
			return;
		}
		if (!canManage) {
			alert('본인의 댓글만 삭제할 수 있습니다.');
			return;
		}

		setIsEditing(false);

		if (confirm("댓글을 삭제하시겠습니까?")) {
			setLoading(true);

			// 댓글 삭제 호출
			fetchApi('/api/forum/comments/' + _comment.id, { method: 'DELETE' }).then(() => {
				// 삭제 성공 시 해당 댓글 영역 삭제
				onDelete(_comment.id, _comment.parentID);
			}).catch(err => {
				setError(err.message);
			}).finally(() => {
				setLoading(false);
			});
		}
	}, [_comment.id, _comment.parentID, loginCheck, canManage, onDelete, setError]);

	return (
		 <>
			{loading ? (
				<Loading type={2} />
			) : (
				<li className={_comment.isSecret ? 'is-secret' : ''}>
					<Report isEnable={true} open={report} onChange={setReport} onComplete={setHasReport} postID={_post.id} commentID={_comment.id} memberID={member?.id} />
					{_board.boardMeta.comment.showMemberThumb && (
					<div>
						<Image src={writerThumb} alt={writerName} width={72} height={0} />
					</div>
					)}
					<div>
						<div>
							<ul>
								<li>
									{_board.boardMeta.comment.showMemberIcon && writerIcon && (
										<Image src={writerIcon} alt="" width={16} height={16} className="inline-block mr-1 align-middle" />
									)}
									<span>{writerName}</span>
								</li>
								<li><small>{createdAt}</small></li>
							</ul>
						</div>
						<div>
							<DropdownMenu>
								<DropdownMenuTrigger>
									<FontAwesomeIcon icon={faEllipsisVertical}/>
								</DropdownMenuTrigger>
								<DropdownMenuContent align='end'>
									{!canManage && (
									<DropdownMenuItem onClick={handleReport}>
										<FontAwesomeIcon icon={!hasReport ? nFlag : yFlag} className="mr-2"/> 신고
									</DropdownMenuItem>
									)}
									{canManage && (
									<>
										<DropdownMenuItem onClick={handleStartEdit}>
											<FontAwesomeIcon icon={faPenToSquare} className="mr-2"/> 수정
										</DropdownMenuItem>
										<DropdownMenuItem onClick={handleDelete}>
											<FontAwesomeIcon icon={faTrashCan} className="mr-2"/> 삭제
										</DropdownMenuItem>
									</>
									)}
								</DropdownMenuContent>
							</DropdownMenu>
						</div>
						<div>
							{!canViewSecret ? (
								<span className='text-[#999]'>
									<FontAwesomeIcon icon={faLock} className='pe-1'/>
									비밀글입니다.
								</span>
							) : isEditing ? (
								<EditForm
									_board={_board}
									_post={_post}
									_comment={_comment}
									onSuccess={handleEditSuccess}
									onCancel={handleCancelEdit}
								/>
							) : (
								<>
									{_comment.mention && (
										<span className="mention">{_comment.mention.rawHandle} </span>
									)}
									{_comment.isSecret && (
										<FontAwesomeIcon icon={faLock} className='pe-1 text-[#999]'/>
									)}
									<span ref={contentRef} dangerouslySetInnerHTML={{ __html: _comment.content }} />
								</>
							)}
						</div>
						<div>
							{!isEditing && canViewSecret && (
								<>
								{canWriteReply !== false && (
								<div>
									<button type="button" title="답글" onClick={onReply}>
										{isReplying ? '답글 접기' : '답글'}
									</button>
								</div>
								)}
								{_board.boardMeta.comment.allowLike && (
									<>
									<div>
										<button type="button" value={Reaction.Like} onClick={handleReaction} title='좋아요'>
											<FontAwesomeIcon icon={!hasLike ? nThumbsUp : yThumbsUp } />
										</button>
									</div>
									<div>
										<em>{likes}</em>
									</div>
									</>
								)}
								{_board.boardMeta.comment.allowDisLike && (
									<>
									<div>
										<button type="button" value={Reaction.Dislike} onClick={handleReaction} title='싫어요'>
											<FontAwesomeIcon icon={!hasDisLike ? nThumbsDown : yThumbsDown } />
										</button>
									</div>
									<div>
										<em>{dislikes}</em>
									</div>
									</>
								)}
								</>
							)}
						</div>

						{children}
					</div>
				</li>
			)}
		</>
	);
}