'use client';

import './style.scss';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useState, useEffect, useRef } from 'react';
import { Checkbox } from '@/components/ui/checkbox';
import { Field, FieldGroup, FieldLabel } from '@/components/ui/field';
import { Dialog, DialogTrigger } from '@/components/ui/dialog';
import TermsDialog from '@/app/component/TermsDialog';
import { VerificationType } from '@/constants/common';
import { fetchApi } from '@/lib/utils/client';
import { RegisterRequest } from '@/types/request/auth';
import { RegisterResponse } from '@/types/response/auth';

export default function Page()
{
    const router = useRouter();
    const [error, setError] = useState<string>('');
	const [loading, setLoading] = useState<boolean>(false);
    const [email, setEmail] = useState<string>('');
    const [password, setPassword] = useState<string>('');
    const [rePassword, setRePassword] = useState<string>('');
    const [agree1, setAgree1] = useState<boolean>(false);
    const [agree2, setAgree2] = useState<boolean>(false);
	const emailRef = useRef<HTMLInputElement>(null);
	const passwordRef = useRef<HTMLInputElement>(null);
	const rePasswordRef = useRef<HTMLInputElement>(null);

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

    const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();

        try {

            if (email.length < 1) {
				emailRef.current?.focus();
                throw new Error('이메일을 입력해주세요.');
            }

			if (password.length < 1) {
				passwordRef.current?.focus();
                throw new Error('비밀번호를 입력해주세요.');
            }

			if (rePassword.length < 1) {
				rePasswordRef.current?.focus();
                throw new Error('비밀번호 확인을 입력해주세요.');
            }

			if (password !== rePassword) {
                throw new Error('비밀번호가 서로 일치하지 않습니다.');
            }

            if (!agree1 || !agree2) {
                throw new Error('모든 필수 약관에 동의해주세요.');
            }

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

            const res = await fetchApi<RegisterResponse>('/api/auth/register', {
                method: 'POST',
                body: {
                    Email: email,
                    Password: password,
                    IsPolicyAgree: agree1,
                    IsPrivacyAgree: agree2
                } as RegisterRequest
            });


			// 시간 제한 생성
			const expiration: string = (Date.now() + 10 * 60 * 1000).toString();
			const callbackURL: string = location.pathname;

			sessionStorage.setItem('type', VerificationType.Registration.toString());
			sessionStorage.setItem('expiration', expiration);
			sessionStorage.setItem('callbackURL', callbackURL);
			sessionStorage.setItem('email', email);

			if (res.data!.isRegisterEmailAuth) {
				// 이메일 인증 필요
				router.push('/approval');
			} else {
				// 회원가입 완료
				router.push('/welcome');
			}

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

    return (
		<>
			<div id="registForm" className="row-start-2">
				<fieldset>
					<legend>회원가입</legend>
					<form method="post" acceptCharset="utf-8" autoComplete="off" onSubmit={handleSubmit}>
						<div className="flex flex-row flex-wrap">
							<section className="sm:pt-4 sm:pb-4">
								<dl>
									<dt hidden>&nbsp;</dt>
									<dd>{ process.env.NEXT_PUBLIC_SITE_NAME } 에 오신 것을 환영합니다.</dd>
									<dd>빠르고 간단하게 회원가입을 진행하세요.</dd>
								</dl>
								<br/>
								<dl>
									<dt hidden>&nbsp;</dt>
									<dd>가입 확인을 위해 유효한 이메일을 입력해주세요.</dd>
									<dd>비밀번호는 최소 8자 이상 입력해주세요.</dd>
								</dl>
							</section>
							<section className="sm:pt-4">
								<article className="grid">
									<label htmlFor="email">이메일</label>
									<input type="email" name="email" id="email" ref={emailRef} maxLength={30} onChange={e => setEmail(e.target.value)} autoComplete="off" />

									<label htmlFor="password">비밀번호</label>
									<input type="password" name="password" id="password" ref={passwordRef} maxLength={20} onChange={e => setPassword(e.target.value)} />

									<label htmlFor="rePassword">비밀번호 확인</label>
									<input type="password" name="re_password" id="rePassword" ref={rePasswordRef} maxLength={20} onChange={e => setRePassword(e.target.value)} />
								</article>
							</section>
						</div>

						<hr />

						<div className="flex flex-row flex-wrap">
							<section>
								<dl>
									<dt>회원가입 약관</dt>
									<dd>원활한 서비스 이용을 위해 약관 동의가 필요합니다.</dd>
									<dd>약관 내용을 자세히 확인하신 후 동의해주세요.</dd>
								</dl>
							</section>
							<section className="pt-4 sm:pt-0">
								<FieldGroup>
									<Field orientation="horizontal" className='items-start'>
										<Checkbox name="agree_1" id="agree_1" onCheckedChange={(checked) => setAgree1(Boolean(checked))} />
										<FieldLabel htmlFor="agree_1">
											<Dialog>
												<DialogTrigger>이용약관</DialogTrigger>
												<TermsDialog subject="이용약관" code="terms" />
											</Dialog>
											에 동의합니다.
										</FieldLabel>
									</Field>
								</FieldGroup>
								<FieldGroup>
									<Field orientation="horizontal" className='items-start'>
										<Checkbox name="agree_2" id="agree_2" onCheckedChange={(checked) => setAgree2(Boolean(checked))} />
										<FieldLabel htmlFor="agree_2">
											<Dialog>
												<DialogTrigger>개인정보처리방침</DialogTrigger>
												<TermsDialog subject="개인정보처리방침" code="privacy" />
											</Dialog>
											에 동의합니다.
										</FieldLabel>
									</Field>
								</FieldGroup>
								<div className="grid grid-cols-2 gap-2 mt-3">
									<button type="submit" className="btn btn-primary" disabled={loading}>
										{loading ? "회원가입 중..." : "회원가입"}
									</button>
									<Link href="/login" className="btn btn-default">취소</Link>
								</div>
							</section>
						</div>
					</form>
				</fieldset>
			</div>
		</>
    );
}