'use client';

import '../style.scss';
import Image from 'next/image';
import { useState, useRef, useEffect } from 'react';
import { useMemberContext } from '@/contexts/memberProvider';
import { fetchCommentCreate } from '@/lib/api/forum/comment';
import BoardResponse from '@/dtos/response/forum/board/boardResponse';
import PostResponse from '@/dtos/response/forum/post/postResponse';
import CommentCreateRequest from '@/dtos/request/forum/comment/commentCreateRequest';
import EmojiPicker from '@/app/component/EmojiPicker';
import Loading from '@/app/component/Loading';
import { BoardLayout, CommentConst } from '@/constants/forum';
import { throwError } from '@/lib/utils/server';
import { CommentItem } from '@/types/forum/comment';

type Props = {
	board: BoardResponse,
	post: PostResponse,
	comment?: CommentItem; // null이면 새 댓글, 값이 있으면 답글
	onSuccess: () => void;
	onCancel?: () => void;
};

export default function WriteForm({ board, post, comment, onSuccess, onCancel }: Props)
{
	const { member } = useMemberContext();
	const boardMeta = board.boardMeta;

	const [error, setError] = useState<string|null>(null);
	const [loading, setLoading] = useState<boolean>(false);

	const [form, setForm] = useState<CommentCreateRequest>({
		postID: post.id,
		parentID: comment?.parentID ?? undefined,
		mention: '',
		content: '',
		isSecret: false
	});

	const textareaRef = useRef<HTMLTextAreaElement>(null);
	const contentRef = useRef<HTMLTextAreaElement>(null);
	const editorRef = useRef<any>(null);

	const initialContent = () => {
		if (comment && comment.parentID && member?.id != comment.writer.id) {
			const rawHandle = comment.mention?.rawHandle ?? `@${comment.writer.name ?? comment.writer.sid}`;
            const mentionText = rawHandle ? (rawHandle.endsWith(' ') ? rawHandle : `${rawHandle} `) : '';
            setForm(prev => ({ ...prev, parentID: comment.id ?? undefined, mention: mentionText, content: mentionText + ' ' }));
            setTimeout(() => textareaRef.current?.focus(), 0);
		} else {
            // 새 글일 때는 mention 초기화
            setForm(prev => ({ ...prev, parentID: undefined, mention: '' }));
        }
	};

	useEffect(() => {
		initialContent();
	}, [comment]);

	// 입력 창 높이 조절
	const resizeTextarea = () => {
		const textarea = textareaRef.current;
		if (textarea) {
			textarea.style.height = 'auto'; // 초기화
			textarea.style.height = `${textarea.scrollHeight}px`; // 높이 조정
		}
	};

	useEffect(() => {
		if (error) {
			alert(error);
			setError(null);
		}
	}, [error]);

	useEffect(() => {
		resizeTextarea();
	}, [form.content]);

	// 입력 내용 저장
	const handleChange = (key: keyof CommentCreateRequest, value: any) => {
		setForm(prev => ({ ...prev, [key]: value }));
	};

	// 이모지 선택
	const handleEmoji = (emoji: string) => {
		handleChange("content", (form.content + emoji));
	};

	// Ctrl + Enter 최종 제출
	const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
		if (e.ctrlKey && e.key === 'Enter') {
			e.preventDefault();
			handleSubmit();
		}
	};

	// 댓글+답글 등록
	const handleSubmit = async () => {
		if (!form.content.trim()) {
			return;
		}

		try {

			if (!form.content) {
				if (boardMeta.list.layout === BoardLayout.QnA) {
					editorRef.current!.editorInstance?.editing.view.focus();
				} else {
					contentRef.current!.focus();
				}

				throw new Error('내용을 입력해주세요.');
			} else if (!boardMeta.comment.enableEditor && !contentRef.current) {
				// 기본 textarea 사용 시 글자 수 검사
				if (form.content.length > CommentConst.MaxAllowedContentLength) {
					contentRef.current!.focus();
					throw new Error(`내용은 ${CommentConst.MaxAllowedContentLength}자 이내로 작성해주세요.`);
				}
			}

			const formData = new FormData();
			formData.append('postID', String(form.postID));
			formData.append('isSecret', String(form.isSecret));

			if (form.parentID) {
				formData.append('parentID', String(form.parentID));
			}

			// content에서 자동으로 붙은 @회원을 제거한다.
			const escapeRegExp = (s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
			if (form.mention) {
				form.content = form.content.replace(
					new RegExp('^\\s*' + escapeRegExp(form.mention) + '\\s*', 'i')
				, '');
			}

			// 이미지 정보
			if (boardMeta.list.layout === BoardLayout.QnA) {
				if (form.content) {
					const doc = new DOMParser().parseFromString(form.content, 'text/html');
					doc.querySelectorAll('img[src]').forEach(img => {
						img.setAttribute('src', 'data:image/');
					});

					form.content = doc.body.innerHTML;
				}

				editorRef.current?.getImageStore().forEach((i: any) => {
					if (i.image?.size > 0 && i.name) {
						formData.append('images', i.image, i.name);
					}
				});

				// 미디어 정보
				editorRef.current!.getMediaStore().forEach((m: any) => {
					if (m.url) {
						formData.append('medias', m.url);
					}
				});

				// 첨부 파일
				editorRef.current!.getFileStore().forEach((f: any) => {
					if (f?.size > 0 && f.name) {
						formData.append('files', f.file, f.name);
					}
				});
			}

			formData.append('content', form.content);

			const res = await fetchCommentCreate(formData);
			await throwError(res);
			onSuccess();

		} catch (err: any) {
			setError(err.message);
		} finally {
			setLoading(false);
			resetForm();
		}
	};

	// 입력 내용 초기화
	const resetForm = () => {
		initialContent();

		if (contentRef.current) {
			contentRef.current.value = '';
		}

		if (textareaRef.current) {
			textareaRef.current.value = '';
		}

		resizeTextarea();
	};

	// 취소
	const handleCancel = () => {
		if (typeof onCancel === 'function') {
			onCancel();
		} else {
			resetForm();
		}
	};

	return (
		<>
			{loading ? (
				<Loading type={2} />
			) : (

				<article className='write-form'>
					<div>
						<Image src={member?.thumb ?? '/resources/thumb.gif'} alt={member?.name ?? member?.sid ?? ''} width={72} height={0} />
					</div>
					<div>
						<textarea
							name='comment'
							rows={1}
							value={form.content}
							title='댓글 입력 창'
							placeholder=''
							ref={textareaRef}
							onChange={(e) => handleChange("content", e.target.value)}
							onKeyDown={handleKeyDown}
							disabled={loading}
						/>
					</div>
					<div>
						{/* 비밀글, 이모지 */}
						<EmojiPicker onEmojiSelect={handleEmoji} />
					</div>
					<div>
						<button type='button' className='btn btn-default' onClick={handleCancel}>취소</button>
						<button type='button' className='btn btn-submit' onClick={handleSubmit}>확인</button>
					</div>
				</article>

			)}
		</>
	)
};