"use client";
import { useTranslations } from "next-intl";
import Link from "next/link";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";

import { FormItem, FormWrapper } from "@/components/ui/form";
import { Fragment, useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { useAppDispatch, useAppSelector } from "@/lib/redux/hooks";
import { clearToken, doGetAuthInfo, doLogin, getAuthInfo, getAuthIsLoading, getShowGakkenMyPage, getShowGakkenTermsAllow, setCallstartAppWithCustomAuth } from "@/lib/redux/features/auth";
import { getUserTrace, hashMD5 } from "@/lib/utils";
import { DefaultLoginRequest, GakkenLoginRequest, GoogleLoginRequest, IpLoginRequest, MicrosoftLoginRequest, SignInResponse } from "@/types/auth";
import { ResponseStatus, STORAGE_KEYS } from "@/types/common";
import { getCompanyDomain, getGakkenTermsAndCondition, getServicePath, getViewSettings, loadGakkenTerms } from "@/lib/redux/features/serviceAdmin";
import { ServiceViewSettings } from "@/types/serviceAdmin";
import { AUTHEN_TYPES, DOMAIN_TYPE, GOOGLE_OPTION, LAYOUT_SETTING, MICROSOFT_LOGIN_OPTION, OPTION_LOGIN, USER_CONFIG } from "@/lib/appConstant";
import StorageHelper from "@/lib/storeHelper";
import { useSearchParams } from "next/navigation";
import { useMounted } from "@/hooks/useMounted";
import { makeStyles } from "tss-react/mui";
import Box from "@mui/material/Box";
import AppCheckbox from "../../ui/checkbox";
import MicrosoftLoginButton from "../../ui/button/microsoft-login-button";
import GoogleLoginButton from "../../ui/button/google-login-button";
import InputField from "../../ui/input/input-field";
import AppButton from "../../ui/button/app-button";
import AppLoading from "../../ui/loading";



const useStyle = makeStyles()(() => {
  return (
    {
      fieldEmail: {
        marginBottom: '5px !important',
      },
      cardBody: {
        display: 'flex',
        flexDirection: 'column'
      },
      termsCondition: {
        overflowY: 'auto',
        height: '100%',
        marginBottom: '16px'
      },
    }
  );
});
type PropsType = {
  notChangeRouter?: boolean;
  handleSuccess?: () => void;
  handleBeforeSubmit?: () => void;
}
export default function LoginForm(props: PropsType) {
const { notChangeRouter, handleSuccess, handleBeforeSubmit } = props;

  const router = useRouter();
  
  const dispatch = useAppDispatch();
  const t = useTranslations("");
  const searchParams = useSearchParams();
  const mounted = useMounted();

  const viewSettings = useAppSelector(getViewSettings) as ServiceViewSettings;
  const domain = useAppSelector(getCompanyDomain) as string;
  const servicePath = useAppSelector(getServicePath) as string;
  const authInfo = useAppSelector(getAuthInfo);
  const showGakkenTermsAllow = useAppSelector(getShowGakkenTermsAllow);
  const showGakkenMypage = useAppSelector(getShowGakkenMyPage);
  const gakkenTermsAndCondition = useAppSelector(getGakkenTermsAndCondition);  
  const authLoading = useAppSelector(getAuthIsLoading);  
  
  const clientId = viewSettings.googleId;
  const googleOption = viewSettings.googleOption;
  const microsoftOption = viewSettings.microsoftLoginOption;
  const isActiveForgotPassword = viewSettings.activeForgotPassword;

  const gakkenCode = searchParams.get('code');
  const stateSearchParams = searchParams.get('state');
  const gidRegistered = searchParams.get('gid_registered');
  const is_login_mobile_app = searchParams.get('is_login_mobile_app');
  
  
  const [isLoading, setIsLoading] = useState(false);
  const [showSendConfirmation, setShowSendConfirmation] = useState(false);
  
  const titleOfEmailField = viewSettings.titleOfEmailField;
  const { accountType, domainType, isAutoRegisterGakkenAccountAtLogin, layoutSettingResponse, microsoftLoginOption } = viewSettings;

  const isFullDomain = domainType === DOMAIN_TYPE.FULL_DOMAIN;
  const listDomainSystemAdmin = process.env.NEXT_PUBLIC_DOMAIN_SYSTEM_ADMIN?.split(',') || [];
  const hideForgotPassword = !isActiveForgotPassword || accountType === OPTION_LOGIN.USERNAME || accountType === OPTION_LOGIN.GAKKEN_ID;

  const formSchema = z.object({
    email: z
      .string()
      .trim()
      .min(1, { message: t("validate.required") }),
    password: z.string().min(1, {
      message: t("validate.required"),
    }),
    keepSignIn: z.boolean().default(false),
    isAcceptTermsAndCondition: z.any()
  });

  type LoginFormSchema = z.infer<typeof formSchema>;

  const signInForm = useForm<LoginFormSchema>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      email: "",
      password: "",
      keepSignIn: false,
    },
  });
  
  const doIpLogin = async () => {
    handleBeforeSubmit && handleBeforeSubmit();
    const userTrace = await getUserTrace();
    const ip = userTrace.ip;
    const param: IpLoginRequest = {
      clientIpAddress: ip,
      loginType: AUTHEN_TYPES.IP,
      companyDomain: domain,
      path: servicePath
    }
    const result = await dispatch(doLogin({ data: param, loginType: AUTHEN_TYPES.IP, domain: domain, servicePath: servicePath }));
    handleLoginSuccess(result);
  };
  const doGoogleLogin = async (data: GoogleLoginRequest) => {
    handleBeforeSubmit && handleBeforeSubmit();
    const result = await dispatch(doLogin({ data: data, loginType: AUTHEN_TYPES.GOOGLE_LOGIN, domain: domain, servicePath: servicePath }));
    handleLoginSuccess(result);
  };
  const doMicrosoftLogin = async (data: MicrosoftLoginRequest, loginType?: string) => {
    handleBeforeSubmit && handleBeforeSubmit();
    const result = await dispatch(doLogin({ data: data, loginType: AUTHEN_TYPES.MICROSOFT_LOGIN, domain: domain, servicePath: servicePath }));
    handleLoginSuccess(result);
  };
  const redirectGakkenLogin = async (isMobileApp?: boolean) => {
    if (typeof window !== 'undefined' && mounted) {
      const redirectUrl = (isFullDomain ? `${window.location.origin}/login` : `${window.location.origin}/${servicePath}/login`);
      const gakkenUrl = `${process.env.NEXT_PUBLIC_GAKKEN_LINK}/common-login?response_type=code&client_id=${viewSettings.gakkenServiceCode}&redirect_uri=${redirectUrl}${isMobileApp ? '&state=mobile_app' : ''}`;
      window.location.replace(gakkenUrl);
    }
  };
  const onGakkenLogin = async (data: any) => {
    const redirectUrl = mounted && window ? (isFullDomain ? `${window.location.origin}/login` : `${window.location.origin}/${servicePath}/login`) : '';
    const loginRequest: GakkenLoginRequest = {
      authorizeCode: decodeURIComponent(gakkenCode as string),
      loginType: AUTHEN_TYPES.GAKKEN_ID,
      redirectUrl: redirectUrl,
      isAcceptTermsAndCondition: data.isAcceptTermsAndCondition,
      isSubscribeMail: data.isSubscribeMail,
      isAuto: isAutoRegisterGakkenAccountAtLogin,
      isMobileApp: !!data.isMobileApp,
      domain: domain,
      path: servicePath
    };
    const result = await dispatch(doLogin({ data: loginRequest, loginType: AUTHEN_TYPES.GAKKEN_ID, domain: domain, servicePath: servicePath }));
    handleLoginSuccess(result);
  };

  const onSubmit = async (values: LoginFormSchema) => {
    handleBeforeSubmit && handleBeforeSubmit();
    try {
      setIsLoading(true);
      const request: DefaultLoginRequest = {
        email: values.email,
        passwordHash: hashMD5(values.password),
        // keepLogin: values.keepSignIn,
        // isAcceptTermsAndCondition: values.isAcceptTermsAndCondition,
        // isSubscribeMail: values.isSubscribeMail,
        loginType: USER_CONFIG.USER.loginType,
        // loginRole: USER_CONFIG.USER.loginType,
        domain: domain,
        path: servicePath
      };
      const result = await dispatch(doLogin({ data: request, loginType: AUTHEN_TYPES.EMAIL, domain: domain, servicePath: servicePath }));
      handleLoginSuccess(result);
      // const payload = result?.payload as SignInResponse;

      // if (payload && payload.status === ResponseStatus.SUCCESS) {
      //   await dispatch(doGetAuthInfo());
      //   if (!notChangeRouter) {
      //     router.push(`/${servicePath}/`);
      //   }
      //   handleSuccess && handleSuccess();
      // }
      //  else {
      //   const errorMessage = typeof payload === "string" ? payload : payload?.errorMsg || "Login failed, please try again.";
      //   toast.error(errorMessage);
      // }
    } catch (error) {
      console.error("Login error:", error);
    } finally {
      setIsLoading(false);
    }
  }

  const handleLoginSuccess = async (result: any) => {
    const payload = result?.payload as SignInResponse;

    if (payload && payload.status === ResponseStatus.SUCCESS) {
      await dispatch(doGetAuthInfo());
      if (!notChangeRouter) {
        router.push(`${servicePath ? '/'+servicePath : ''}/`);
      }
      handleSuccess && handleSuccess();
    }
  }

  const isSuperAdmin = listDomainSystemAdmin.indexOf(domain) > -1;
  useEffect(() => {
    // Handle keydown enter to submit form
    const keyDownHandler = (event) => {
      if (event.key === "Enter") {
        event.preventDefault();
        signInForm.handleSubmit(onSubmit)();
      }
    };

    document.addEventListener("keydown", keyDownHandler);

    return () => {
      document.removeEventListener("keydown", keyDownHandler);
    };
  }, [signInForm]);


  useEffect(() => {
    const userStore = !servicePath || servicePath === '' ? domain : servicePath;
    const token = StorageHelper.getCookie(userStore);
    const appMobileAuthToken = StorageHelper.getLocalItem(STORAGE_KEYS.appMobileAuthToken);
    // Check login
    console.log(' >>> gakkenCode: ', gakkenCode);
    if (gakkenCode && accountType === OPTION_LOGIN.GAKKEN_ID) {
      console.log(' >>> gidRegistered: ', gidRegistered);
      if (gidRegistered === '1') {
        dispatch(loadGakkenTerms());
      } else {
        mounted && onGakkenLogin({ isMobileApp: viewSettings.isEnableWebMobile && stateSearchParams === 'mobile_app' });
      }
    } else if (mounted && viewSettings && accountType && accountType === OPTION_LOGIN.GAKKEN_ID && !gakkenCode) {
      // Check login with mobile app
      console.log(' >>>>> is_login_mobile_app: ', is_login_mobile_app);
      
      if (viewSettings.isEnableWebMobile && is_login_mobile_app) {
        if (token && appMobileAuthToken) {
          // Go to home page then call startAppWithCustomAuth
          setCallstartAppWithCustomAuth(true);
          const path = layoutSettingResponse?.viewPage === LAYOUT_SETTING.SEARCH_LAYOUT.id ? '/search' : '';
          router.push(`${servicePath ? '/'+servicePath : ''}/${path}/?UserID=${token}`);
        } else {
          // Redirect Gakken login
          token && clearToken();
          redirectGakkenLogin(true);
        }
        return;
      }
      // login gakken default
      if (!authInfo?.id && (!is_login_mobile_app || viewSettings.isEnableWebMobile === false)) {
        setTimeout(() => {
          redirectGakkenLogin(false);
        }, 2000);
      }
    }
    
  }, [gakkenCode, accountType, gidRegistered, mounted]);

  useEffect(() => {
    if (mounted && accountType === OPTION_LOGIN.EMAIL || accountType === OPTION_LOGIN.ALL) {
      // check microsoftOption = NONE
      if (typeof window !== 'undefined') {
        if (window.location.hash && window.location.hash.includes('#code=') && microsoftLoginOption === MICROSOFT_LOGIN_OPTION.NONE) {
          StorageHelper.setSessionItem(STORAGE_KEYS.loginType, '');
          StorageHelper.setSessionItem(STORAGE_KEYS.microsoftVerifier, '');
          
          router.push(`${servicePath ? '/'+servicePath : ''}/login`);
        }
      }
    }
  }, [mounted, window]);

  useEffect(() => {
    const userStore = !servicePath || servicePath === '' ? domain : servicePath;
    const isToken = StorageHelper.getCookie(userStore);
    if (isToken && isToken !== '' && !notChangeRouter) {
      router.push(`${servicePath ? '/'+servicePath : ''}/`);
    }
  }, [servicePath, domain]);

  const { classes } = useStyle();

  return (
    <FormWrapper<LoginFormSchema>
      form={signInForm}
      onSubmit={onSubmit}
      layout="vertical"
      className="position-relative"
      // onKeyDown={handleKeyDown}
    >
      {
        authLoading && <AppLoading bgColor="#fff"/>
      }
      <div style={{ opacity: authLoading ? 0 : 1}}>
        {
          accountType === OPTION_LOGIN.GAKKEN_ID
          ? <div >
              {
                showGakkenTermsAllow || gidRegistered
                  ? <Fragment>
                    {
                      showGakkenMypage
                        ? <Fragment>
                          <Box display="flex" alignItems="center" justifyContent="center" mt={3}>{t('label.gakkenMissingEmail')}</Box>
                          <Box display="flex" alignItems="center" justifyContent="center">
                            <AppButton
                              // type="primary"
                              disabled={isLoading || authLoading}
                              onClick={() => window.location.replace(`${process.env.NEXT_PUBLIC_GAKKEN_LINK}/my-page`)}
                              className='mt-3'
                            >
                              {t('label.gakkenMyPage')}
                            </AppButton>
                          </Box>
                        </Fragment>
                        : <Fragment>
                          <div className={classes.termsCondition} dangerouslySetInnerHTML={{ __html: gakkenTermsAndCondition }}/>
                            <FormItem name="isAcceptTermsAndCondition">
                              {({ value, ref, ...field }) => (
                                <>
                                  <AppCheckbox
                                    {...field}
                                    className="w-[32px]"
                                    disabled={showGakkenMypage}
                                    checked={value}
                                    onChange={(checked) => {
                                      field.onChange(checked);
                                      setShowSendConfirmation(!!checked);
                                    }}
                                  >
                                    {value}
                                  </AppCheckbox>
                                  <span className="ml-1">{t("label.agreeTermLabel")}</span>
                                </>
                              )}
                            </FormItem>
                            
                            <FormItem name="isSubscribeMail">
                              {({ value, ref, ...field }) => (
                                <>
                                  <AppCheckbox
                                    {...field}
                                    className="w-[32px]"
                                    checked={value}
                                    disabled={showGakkenMypage}
                                    onChange={(checked) => {
                                      field.onChange(checked);
                                    }}
                                  >
                                    {value}
                                  </AppCheckbox>
                                  <span className="ml-1">{t("label.subscribeMailing")}</span>
                                </>
                              )}
                            </FormItem>
                          <Box display="flex" alignItems="center" justifyContent="center">
                            <AppButton
                              // variant="contained"
                              // color="primary"
                              disabled={!showSendConfirmation}
                              onClick={() => onGakkenLogin(signInForm.getValues())}
                              className='mt-3'
                            >
                              {t('label.sendConfirmation')}
                            </AppButton>
                          </Box>
                        </Fragment>
                    }
                  </Fragment>
                  : <AppButton
                      // type="primary"
                      disabled={isLoading || authLoading}
                      className="w-full"
                      onClick={() => redirectGakkenLogin(false)}
                  >
                    {t('label.gakkenId')}
                  </AppButton>
              }
          </div>
          : <div>
            <FormItem
              name="email"
              className={classes.fieldEmail}
              label={
                titleOfEmailField && titleOfEmailField !== ''
                ? titleOfEmailField
                : t(accountType === OPTION_LOGIN.ALL ? 'label.emailOrUser' : accountType === OPTION_LOGIN.EMAIL ? 'label.email' : 'label.username')
              }
            >
              {({ value, ref, ...field }) => (
                <InputField
                  name="email"
                  // type='email'
                  placeholder={
                    titleOfEmailField && titleOfEmailField !== ''
                    ? titleOfEmailField
                    : t(accountType === OPTION_LOGIN.ALL ? 'label.emailOrUser' : accountType === OPTION_LOGIN.EMAIL ? 'label.email' : 'label.username')
                  }
                  {...field}
                />
                // <AppInput ref={ref} {...field} placeholder={t("label.email")} />
              )}
            </FormItem>


            <FormItem name="password" label={t("label.password")}>
              {({ value, ref, ...field }) => (
                <InputField
                  name="password"
                  type='password'
                  placeholder={t("label.password")}
                  {...field}
                />
              )}
            </FormItem>

            <div className="mb-[1rem]">
              <AppButton
                // type="primary"
                type="submit"
                loading={isLoading || authLoading}
                className="w-full"
              >
                {t("menu.login")}
              </AppButton>
              <hr data-content="OR" style={{
                  boxSizing: 'content-box',
                  overflow: 'visible',
                }} className="hr-text"/>
              
              <AppButton
                loading={isLoading || authLoading}
                color="black"
                className="w-full"
                onClick={doIpLogin}
              >
                {t("menu.loginIp")}
              </AppButton>
            </div>
            {
              (accountType === OPTION_LOGIN.EMAIL ||
              accountType === OPTION_LOGIN.ALL) &&
              googleOption !== GOOGLE_OPTION.NONE
                ? <div className="mb-[1rem]">
                    <GoogleLoginButton
                      clientId={clientId}
                      onSubmit={doGoogleLogin}
                    />
                </div>
                : null
            }
            {
              (accountType === OPTION_LOGIN.EMAIL ||
              accountType === OPTION_LOGIN.ALL) &&
              microsoftOption !== MICROSOFT_LOGIN_OPTION.NONE
              ? <div className="mb-[1rem]">
                  <MicrosoftLoginButton
                    clientId={viewSettings.clientIdMicrosoftSso}
                    onSubmit={doMicrosoftLogin}
                  />
              </div>
              : null
            }
            
            {
              !hideForgotPassword && !isSuperAdmin &&
                <div className="text-center mb-3">
                  <Link href={`${servicePath ? '/'+servicePath : ''}/forget-password`}>
                    {t("label.forgotPassword")}
                  </Link>
                </div>
            }
            {
              !isSuperAdmin && viewSettings.isShowLinkRegisterUser &&
              <div className="text-center mb-3">
                {t("text.dontHaveAnAccount")}
                <Link href={`${servicePath ? '/'+servicePath : ''}/register`} className="ml-1">
                  {t("menu.signup")}
                </Link>
              </div>
            }
          </div>
        }
      </div>
    </FormWrapper>
  );
}
