import { useCallback, useEffect, useState } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { 
  Card,
  CardContent,
  CardHeader,
  CardFooter
} from '@/components/ui/card';
import { Field, FieldError, FieldGroup, FieldLabel } from '@/components/ui/field';
import { SignUpSchema } from '@/data/form';
import { Controller, useForm } from 'react-hook-form';
import * as z from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import EmailVerificationModal from '@/ui/component/modal/EmailVerificationModal';
import { CheckDuplicationRequest, SignupRequest } from '@/data/request';
import { AccountNetwork } from '@/network/AccountNetwork';
import { toast } from 'sonner';
import { useNavigate } from 'react-router-dom';
import { PageRouting } from '@/const/PageRouting';
import { useIsMobile } from '@/hooks/use-mobile';
import { ScrollArea } from '@/components/ui/scroll-area';
import { SchedulerDTO as DTO } from '@baekyangdan/core-utils';

export default function SignUpPage() {
  const [emailVerificationModalOpen, setEmailVerificationModalOpen] = useState<boolean>(false);
  const [isCheckedEmailDuplication, setIsCheckedEmailDuplication] = useState<boolean>(false);
  const [isCheckedAccountIdDuplication, setIsCheckedAccountIdDuplication] = useState<boolean>(false);
  const [duplicationCheckedEmail, setDuplicationCheckedEmail] = useState<string>("");
  const [duplicationCheckedAccountId, setDuplicationCheckedAccountId] = useState<string>("");

  const accountNetwork = new AccountNetwork();
  const navigate = useNavigate();
  const isMobile = useIsMobile();

  const signUpForm = useForm<z.infer<typeof SignUpSchema>>({
    resolver: zodResolver(SignUpSchema),
    defaultValues: {
      accountId: "",
      email: "",
      password: "",
      passwordConfirm: "",
      name: "",
      nickname: "",
    }
  });

  const goToLogin = useCallback(() => {
    navigate(PageRouting["LOGIN"].path);
  }, [navigate]);

  const checkDuplication = async (type: 'email' | 'accountId', value: string) => {
    const data = {
      type,
      value
    } as DTO.CheckDuplicationRequest;
    return await accountNetwork.checkDuplication(data);
  }

  const signup = async () => {
    const { email, accountId, name, nickname, password } = signUpForm.getValues();
    const data = {
      email,
      accountId,
      name,
      nickname,
      password
    } as DTO.SignupRequest;

    const signupPromise = accountNetwork.signup(data);

    toast.promise(
      signupPromise,
      {
        loading: "회원가입 진행 중입니다.",
        success: (res) => {
          if (!res.success) return "회원가입에 실패하였습니다.\n잠시 후 다시 시도해주십시오.";
          
          return <SuccessToast onClose={goToLogin} />
        },
        error: "회원가입에 실패하였습니다.\n잠시 후 다시 시도해주십시오.",
      }
    );
  }

  const handleOnChangeAccountId = (e: React.ChangeEvent<HTMLInputElement>) => {
    setIsCheckedAccountIdDuplication(
      e.currentTarget.value === duplicationCheckedAccountId
    );
  }

  const handleOnChangeEmail = (e: React.ChangeEvent<HTMLInputElement>) => {
    setIsCheckedEmailDuplication(
      e.currentTarget.value === duplicationCheckedEmail
    );
  }

  const handleDuplicationCheckButtonClick = async (type: 'email' | 'accountId') => {
    const value = signUpForm.getValues(type);
    const duplicatedMessage = type === 'email' ? '사용할 수 없는 이메일입니다.' : '사용할 수 없는 아이디입니다.';

    if (!value) return;

    try {

      const result = await checkDuplication(type, value);
      let isDuplicated = false;

      if (result.success) {
        isDuplicated = result.data.isDuplicated;
      } else {
        throw new Error(result.error);
      }

      if (isDuplicated) {
        signUpForm.setError(type, { message: duplicatedMessage });
      } else {
        signUpForm.clearErrors(type);
        if (type === 'email') {
          setIsCheckedEmailDuplication(true);
          setDuplicationCheckedEmail(value);
        } else {
          setIsCheckedAccountIdDuplication(true);
          setDuplicationCheckedAccountId(value);
        }
      }
    } catch (e) {
      if (type === 'email') {
        setIsCheckedEmailDuplication(false);
        setDuplicationCheckedEmail('');
      } else {
        setIsCheckedAccountIdDuplication(false);
        setDuplicationCheckedAccountId('');
      }
    }
  }

  const handleOnSignUpButtonClick = () => {
    if (!isCheckedAccountIdDuplication) {
      signUpForm.setError("accountId", { message: "아이디 중복 확인이 필요합니다."});
      return;
    }

    if (!isCheckedEmailDuplication) {
      signUpForm.setError("email", { message: "이메일 중복 확인이 필요합니다." });
      return;
    }

    setEmailVerificationModalOpen(true);
  }

  return (
    <div className={"w-full h-full flex flex-col justify-center items-center"}>

        <Card className={isMobile ? "w-full pl-2 pr-2" : "w-md pl-2 pr-2"}>
          <CardHeader>회원가입</CardHeader>
          <ScrollArea className="h-72 [&>div>div:last-child]:hidden">
          <CardContent>
            <form id="form-signup">
              <FieldGroup>
                <Controller
                  name="accountId"
                  control={signUpForm.control}
                  render={({ field, fieldState  }) => (
                    <Field data-invalid={fieldState.invalid}>
                      <FieldLabel htmlFor="form-signup-account-id">아이디</FieldLabel>
                      <div id="accountId-group" className="w-full flex flex-row justify-between gap-2.5">
                        <Input
                          {...field}
                          id="form-signup-account-id"
                          aria-invalid={fieldState.invalid}
                          onInput={handleOnChangeAccountId}
                        />
                        <Button
                          type="button"
                          onClick={() => handleDuplicationCheckButtonClick('accountId')}
                          className="bg-indigo-500 hover:bg-indigo-400"
                        >
                          중복 확인
                        </Button>
                      </div>
                      { isCheckedAccountIdDuplication && <p className="text-green-500 text-sm font-normal">사용할 수 있는 아이디입니다</p> }
                      <FieldError errors={[fieldState.error]}/>
                    </Field>
                  )} 
                />
                <Controller
                  name="name"
                  control={signUpForm.control}
                  render={({ field, fieldState }) => (
                    <Field data-invalid={fieldState.invalid}>
                      <FieldLabel htmlFor="form-signup-name">이름</FieldLabel>
                      <Input
                        {...field}
                        id="form-signup-name"
                        aria-invalid={fieldState.invalid}
                      />
                      <FieldError errors={[fieldState.error]} />
                    </Field>
                  )}
                />
                <Controller
                  name="nickname"
                  control={signUpForm.control}
                  render={({ field, fieldState }) => (
                    <Field data-invalid={fieldState.invalid}>
                      <FieldLabel htmlFor="form-signup-nickname">닉네임</FieldLabel>
                      <Input
                        {...field}
                        id="form-signup-nickname"
                        aria-invalid={fieldState.invalid}
                      />
                      <FieldError errors={[fieldState.error]} />
                    </Field>
                  )}
                />
                <Controller
                  name="email"
                  control={signUpForm.control}
                  render={({ field, fieldState  }) => (
                    <Field data-invalid={fieldState.invalid}>
                      <FieldLabel htmlFor="form-signup-email">이메일</FieldLabel>
                      <div id="email-group" className="w-full flex flex-row justify-between gap-2.5">
                        <Input
                          {...field}
                          id="form-signup-email"
                          aria-invalid={fieldState.invalid}
                          placeholder="example@domain.com"
                          type="email"
                          onInput={handleOnChangeEmail}
                        />
                        <Button
                          type="button"
                          onClick={() => handleDuplicationCheckButtonClick('email')}
                          className="bg-indigo-500 hover:bg-indigo-400"
                        >
                          중복 확인
                        </Button>
                      </div>
                      { isCheckedEmailDuplication && <p className="text-green-500 text-sm font-normal">사용할 수 있는 이메일입니다</p> }
                      <FieldError errors={[fieldState.error]}/>
                    </Field>
                  )} 
                />
                <Controller
                  name="password"
                  control={signUpForm.control}
                  render={({ field, fieldState }) => (
                    <Field data-invalid={fieldState.invalid}>
                      <FieldLabel htmlFor="form-signup-password">비밀번호</FieldLabel>
                      <Input
                        {...field}
                        id="form-signup-password"
                        aria-invalid={fieldState.invalid}
                        type="password"
                      />
                      <FieldError errors={[fieldState.error]} />
                    </Field>
                  )}
                />
                <Controller
                  name="passwordConfirm"
                  control={signUpForm.control}
                  render={({ field, fieldState }) => (
                    <Field data-invalid={fieldState.invalid}>
                      <FieldLabel htmlFor="form-signup-password-confirm">비밀번호 확인</FieldLabel>
                      <Input
                        {...field}
                        id="form-signup-password-confirm"
                        aria-invalid={fieldState.invalid}
                        type="password"
                      />
                      <FieldError errors={[fieldState.error]} />
                    </Field>
                  )}
                />
              </FieldGroup>
            </form>
          </CardContent>
          </ScrollArea>
          <CardFooter>
            <EmailVerificationModal 
              trigger={
                <Button type="button" onClick={handleOnSignUpButtonClick} className="0">
                  회원가입
                </Button>
              }
              email={duplicationCheckedEmail}
              open={emailVerificationModalOpen}          // ✅ 부모 상태 연결
              setOpen={setEmailVerificationModalOpen}    // ✅ 부모 상태 변경 함수 전달
              onVerifySuccess={signup}                   // ✅ 인증 성공 시 signup 호출
            />
          </CardFooter>
          
        </Card>

    </div>
  );
}

function SuccessToast({ onClose }: { onClose: () => void }) {
  useEffect(() => {
    const timer = setTimeout(() => onClose(), 3000); // 3초 후 이동
    return () => clearTimeout(timer);
  }, [onClose]);

  return (
    <div className="w-full flex flex-row justify-between items-center">
      회원가입 성공!
      <button onClick={onClose}>로그인 페이지로 이동</button>
    </div>
  );
}