'use client';

import './style.scss';
import { useEffect, useState, useCallback, useRef } from 'react';
import Loading from '@/app/component/Loading';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { fetchReport } from '@/lib/api/forum/post';
import { throwError } from '@/lib/utils/client';
import { ReportType } from '@/constants/forum';
import PostReportRequest from '@/dtos/request/forum/post/postReportRequest';

type Props = {
	isEnable: boolean;
	open: boolean;
	onChange: (_: boolean) => void;
	onComplete: (_: boolean) => void;
	postID: number;
	memberID?: number;
}

export default function Report({ isEnable, open, onChange, onComplete, postID, memberID }: Props)
{
	const [error, setError] = useState<string>('');
	const [loading, setLoading] = useState<boolean>(false);
	const [form, setForm] = useState<{
		type: string;
		reason: string;
	}>({
		type: '',
		reason: ''
	});
	const typeRef = useRef<HTMLSelectElement>(null);
	const reasonRef = useRef<HTMLTextAreaElement>(null);

	const reportTypeLabels: Record<ReportType, string> = {
		[ReportType.None]: '신고 유형을 선택하세요.',
		[ReportType.Abuse]: '욕설',
		[ReportType.Obscene]: '음란',
		[ReportType.Illegal]: '불법',
		[ReportType.Impersonation]: '신분 사칭',
		[ReportType.CashTrade]: '현금거래 유도',
		[ReportType.SpamAd]: '스팸/광고',
		[ReportType.Flood]: '도배',
		[ReportType.PersonalLeak]: '개인정보 노출',
		[ReportType.Other]: '기타'
	};

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

	const handleChange = (e: React.ChangeEvent<HTMLSelectElement|HTMLTextAreaElement>) => {
        const { name, value } = e.target;

        setForm((prev) => ({
            ...prev,
            [name]: value
        }));
    };

	const handleSubmit = useCallback(async () => {
		if (!form.type) {
			alert('신고 유형을 선택하세요.');
			typeRef.current?.focus();
			return;
		}

		if (!form.reason) {
			alert('신고 내용을 입력해주세요.');
			reasonRef.current?.focus();
			return;
		}

        if (!memberID) {
            alert('로그인 후 이용해주세요.');
            return;
        }

		setLoading(true);
		onChange(false);

		try {

            const res = await fetchReport({
				postID,
				type: Number(form.type) as ReportType,
				reason: form.reason
			} as PostReportRequest);

			if (res.success) {
				alert('신고가 접수되었습니다.');
				setForm({ type: '', reason: '' });
				onComplete(true);
			} else {
				throwError(res);
			}

        } catch (err: any) {
            alert(err.message);
        } finally {
            setLoading(false);
        }
    }, [form, postID, memberID, onChange]);

	if (!isEnable) {
		return null;
	}

	return (
		<>
			{loading && <Loading />}

			<Dialog open={open} onOpenChange={onChange}>
				<DialogContent className='w-3xs sm:max-w-md'>
					<DialogHeader>
						<DialogTitle>게시글 신고</DialogTitle>
					</DialogHeader>
					<div id='report' className='flex flex-col items-center gap-4'>
						<select ref={typeRef} name='type' value={form.type} title='신고 유형' onChange={handleChange}>
							{Object.entries(reportTypeLabels).map(([key, label]) => (
								<option key={key} value={key}>
									{label}
								</option>
							))}
						</select>
						<textarea ref={reasonRef} name='reason' rows={4} value={form.reason} title='신고 내용' onChange={handleChange} maxLength={500} placeholder='신고 내용을 구체적으로 입력해주세요.(500자 이하)'></textarea>
						<Button type='button' variant='outline' className='hover:bg-blue-500 hover:text-white sm:w-24' onClick={handleSubmit}>
							신고하기
						</Button>
					</div>
				</DialogContent>
			</Dialog>
		</>
	);
}