'use client';

import './style.scss';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useState, useEffect, useRef } from 'react';
import { VerificationType } from '@/constants/common';
import { VerifyEmailRequest, ResendEmailRequest } from '@/types/request/auth';
import { fetchApi } from '@/lib/utils/client';
import Loading from '@/app/component/Loading';

export default function Approval()
{
	const router = useRouter();
	const [loading, setLoading] = useState<boolean>(false);
    const [error, setError] = useState<string>('');
	const [verifyCode, setVerifyCode] = useState<string>('');
    const verifyCodeRef = useRef<HTMLInputElement>(null);

    const type: string|null = sessionStorage.getItem('type');
    const email: string = (sessionStorage.getItem('email') || '');
    const expiration: string|null = sessionStorage.getItem('expiration');
    const callbackURL: string = (sessionStorage.getItem('callbackURL') || '/');

    // 인증번호 유지 시간 조회
    const getResendApprovalSecond = (): number => {
        let remainResendApprovalSecond: string | null = sessionStorage.getItem('remainResendApprovalSecond');
        if (!remainResendApprovalSecond) {
            remainResendApprovalSecond = '120'; // 2분 후 만료
            sessionStorage.setItem('remainResendApprovalSecond', remainResendApprovalSecond);
        }
        return Number(remainResendApprovalSecond);
    };

    const [resendApprovalSecond, setResendApprovalSecond] = useState(
        getResendApprovalSecond()
    );

    // 다시 보내기 여부
    const [canResend, setCanResend] = useState(false);

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

    // 페이지 벗어날 때 세션 정리
    useEffect(() => {
		if (!email || email == '') {
			alert('잘못된 접근입니다.');
		    location.replace('/');
			return;
		}

        // 인증 시간 만료 확인
        if (type == null || type == "") {
            alert('다시 시도해주세요.');
			router.push('/');
            return;
        }

        if (!expiration || Date.now() > Number(expiration)) {
            alert('인증 시간이 만료되었습니다. 다시 시도해주세요.');
            router.push(callbackURL);
            return;
        }

        const handleUnload = (e: BeforeUnloadEvent) => {
            const isReload = (e.type === 'beforeunload' || (performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming)?.type === 'reload' || performance.navigation.type === 1);
            if (isReload) {
                e.preventDefault();
                return;
            }

            sessionStorage.clear();
        }
        window.addEventListener('beforeunload', handleUnload);

        return () => window.removeEventListener('beforeunload', handleUnload);
    }, [expiration, router]);

    // 다시 보내기 타이머 설정
    useEffect(() => {
        if (resendApprovalSecond <= 0) {
            setCanResend(true);
            sessionStorage.setItem('expiration', '0');
            sessionStorage.removeItem('remainResendApprovalSecond');
            return;
        }

        const timer = setInterval(() => {
            setResendApprovalSecond((prev) => {
                if (prev <= 1) {
                    clearInterval(timer);
                    setCanResend(true);
                    return 0;
                }
                return prev - 1;
            });
        }, 1000);

        sessionStorage.setItem('remainResendApprovalSecond', resendApprovalSecond.toString());

        return () => clearInterval(timer);
    }, [resendApprovalSecond]);

    // 인증번호 검증
    const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        setLoading(true);

        try {

            if (!verifyCode) {
                verifyCodeRef.current?.focus();
                throw new Error('인증번호를 입력하세요.');
            }

            await new Promise(resolve => setTimeout(resolve, 500));

			const res = await fetchApi('/api/auth/verify-email', {
				method: 'POST',
				body: { Email: email, Code: verifyCode, Type: Number(type) } as VerifyEmailRequest
			});

        	sessionStorage.setItem('email', email);

			switch (type) {
				// 회원가입 완료
				case VerificationType.Registration.toString():
					router.push('/welcome');
					break;

				// 비밀번호 변경 페이지 이동
				case VerificationType.ForgotPassword.toString():
					router.push('/reset-password');
					break;
			}

        } catch (err) {
            if (err instanceof Error) {
                setError(err.message);
            }
        } finally {
            setLoading(false);
        }
    };

    // 인증번호 다시 보내기
    const handleResend = async () => {
        try {

			await fetchApi('/api/auth/resend-email', {
				method: 'POST',
				body: { Email: email, Type: Number(type) } as ResendEmailRequest
			});

            setCanResend(false);
            setResendApprovalSecond(getResendApprovalSecond());
            setVerifyCode("");
        } catch (err) {
            if (err instanceof Error) {
                setError(err.message);
            }
        }
    };

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

			<div id="approvalForm" className="row-start-2 flex flex-row flex-wrap gap-2">
				<fieldset className="grow">
					<legend>인증번호 확인</legend>

					<form id="fApproval" method="post" acceptCharset="utf-8" autoComplete="off" className="grid p-4" onSubmit={handleSubmit}>
						<p>보안을 위해 인증번호를 발송했습니다. <br />수신된 인증번호를 입력해주세요.</p>
						<div>
                            <br />
                        </div>

						<label htmlFor="email">수신 이메일</label>
						<input type="email" name="email" id="email" value={email} disabled />

						<div className="flex flex-row flex-1">
							<label htmlFor="verifyCode" className="flex-auto">인증번호</label>
							<label className="text-right">
								{canResend ? (
									<button type="button" className="text-blue-600 no-underline hover:underline" onClick={handleResend}>
										다시 받기
									</button>
								) : (
									<><span className="text-green-700">유효시간：(<em>{resendApprovalSecond}</em>초)</span></>
								)}
							</label>
						</div>
						<input type="number" name="verify_code" id="verifyCode" ref={verifyCodeRef} minLength={6} maxLength={10} onChange={e => setVerifyCode(e.target.value)} autoComplete="off" />

						<div className="grid grid-cols-2 gap-2">
							<button type="submit" className="btn btn-primary" disabled={loading}>
								{loading ? "확인 중..." : "확인"}
							</button>
							<button type="button" className="btn btn-default" onClick={() => router.push(callbackURL)}>취소</button>
						</div>

						<hr />

						<dl>
							<dt>도움이 필요하신가요?</dt>
							<dd>인증번호를 받을 수 없거나 오류가 발생한 경우 <Link href="/board/qna">운영자에게 문의</Link>하세요.</dd>
						</dl>
					</form>
				</fieldset>
			</div>
		</>
    );
}
