import Footer from '@/components/Footer';
import LangSwitches from '@/components/Lang/LanguageSwitcherAuth';
import ThemeSwitcherAuth from '@/components/Theme/ThemeSwitcherAuth';
import { THEME_KEY } from '@/constants';
import { ROUTER_HOME } from '@/constants/routes';
import {
  apiForgotPassword,
  apiLogin,
  apiLogin2FA,
  apiQueryProfile,
} from '@/services/master/AuthController';
import { checkRefreshTokenExpired } from '@/utils/jwt';
import { getDomainTitle, getLogoImage } from '@/utils/logo';
import {
  getBrowserId,
  getRefreshToken,
  removeAccessToken,
  removeRefreshToken,
  setAccessToken,
  setRefreshToken,
} from '@/utils/storage';
import { LoginFormPage } from '@ant-design/pro-components';
import { FormattedMessage, history, useIntl, useModel } from '@umijs/max';
import { Button, ConfigProvider, Flex, Image, message, theme } from 'antd';
import { CSSProperties, useEffect, useState } from 'react';
import { flushSync } from 'react-dom';
import mobifontLogo from '../../../public/mobifont-logo.png';
import ForgotPasswordForm from './components/ForgotPasswordForm';
import LoginForm from './components/LoginForm';
import OtpForm from './components/OtpForm';

type LoginType = 'login' | 'forgot' | 'otp';

// Form wrapper with animation
const FormWrapper = ({
  children,
  animationKey,
}: {
  children: React.ReactNode;
  animationKey: string;
}) => {
  const style: CSSProperties = {
    animation: 'fadeInSlide 0.4s ease-out forwards',
  };

  return (
    <div key={animationKey} style={style}>
      <style>{`
        @keyframes fadeInSlide {
          from {
            opacity: 0;
            transform: translateX(-20px);
          }
          to {
            opacity: 1;
            transform: translateX(0);
          }
        }
      `}</style>
      {children}
    </div>
  );
};

const LoginPage = () => {
  const [isDark, setIsDark] = useState(
    (localStorage.getItem(THEME_KEY) as 'light' | 'dark') === 'dark',
  );
  const { token } = theme.useToken();
  const [messageApi, contextHolder] = message.useMessage();
  const urlParams = new URL(window.location.href).searchParams;
  const redirect = urlParams.get('redirect');
  const intl = useIntl();
  const { setInitialState } = useModel('@@initialState');
  const [loginType, setLoginType] = useState<LoginType>('login');
  const [pending2faToken, setPending2faToken] = useState<string>('');

  // Listen for theme changes from ThemeSwitcherAuth
  useEffect(() => {
    const handleThemeChange = (e: Event) => {
      const customEvent = e as CustomEvent<{ theme: 'light' | 'dark' }>;
      setIsDark(customEvent.detail.theme === 'dark');
    };

    window.addEventListener('theme-change', handleThemeChange as EventListener);
    return () => {
      window.removeEventListener(
        'theme-change',
        handleThemeChange as EventListener,
      );
    };
  }, []);

  const checkLogin = async () => {
    const refreshToken = getRefreshToken();
    if (!refreshToken) {
      return;
    }
    const isRefreshTokenExpired = checkRefreshTokenExpired(refreshToken);
    if (isRefreshTokenExpired) {
      removeAccessToken();
      removeRefreshToken();
      return;
    } else {
      const userInfo = await apiQueryProfile();
      if (userInfo) {
        flushSync(() => {
          setInitialState((s: any) => ({
            ...s,
            currentUserProfile: userInfo,
          }));
        });
      }
      if (redirect) {
        history.push(redirect);
      } else {
        history.push(ROUTER_HOME);
      }
    }
  };

  useEffect(() => {
    checkLogin();
  }, []);

  const handleLogin = async (values: any) => {
    const { email, password } = values;
    if (loginType === 'login') {
      try {
        const resp = await apiLogin({
          guid: getBrowserId(),
          email,
          password,
        });
        // Check if 2FA is enabled
        if (resp?.enabled2fa && resp?.token) {
          // Save pending 2FA token and switch to OTP form
          setPending2faToken(resp.token);
          setLoginType('otp');
          return;
        }
        if (resp?.token) {
          setAccessToken(resp.token);
          setRefreshToken(resp.refresh_token || '');
          const userInfo = await apiQueryProfile();
          if (userInfo) {
            flushSync(() => {
              setInitialState((s: any) => ({
                ...s,
                currentUserProfile: userInfo,
              }));
            });
          }
          if (redirect) {
            history.push(redirect);
          } else {
            history.push(ROUTER_HOME);
          }
        }
      } catch (error) {
        console.error('Login error:', error);
      }
    } else if (loginType === 'otp') {
      // Handle OTP verification
      try {
        const resp = await apiLogin2FA(pending2faToken, {
          otp: values.otp || '',
        });
        if (resp?.token) {
          setAccessToken(resp.token);
          setRefreshToken(resp.refresh_token || '');
          const userInfo = await apiQueryProfile();
          if (userInfo) {
            flushSync(() => {
              setInitialState((s: any) => ({
                ...s,
                currentUserProfile: userInfo,
              }));
            });
          }
          if (redirect) {
            history.push(redirect);
          } else {
            history.push(ROUTER_HOME);
          }
        }
      } catch (error) {
        console.error('2FA verification error:', error);
        messageApi.error(
          intl.formatMessage({
            id: 'master.auth.otp.error',
            defaultMessage: 'Invalid OTP code. Please try again.',
          }),
        );
      }
    } else {
      try {
        const host = window.location.origin;
        const body: MasterModel.ForgotPasswordRequestBody = {
          email: email,
          host: host,
        };
        const resp = await apiForgotPassword(body);
        if (!resp.error) {
          messageApi.success(
            intl.formatMessage({
              id: 'master.auth.forgot.message.success',
              defaultMessage:
                'Request sent successfully, please check your email!',
            }),
          );
        }
      } catch (error) {
        console.error('Error when send reset password: ', error);
        messageApi.error(
          intl.formatMessage({
            id: 'master.auth.forgot.message.fail',
            defaultMessage: 'Request failed, please try again later!',
          }),
        );
      }
    }
  };

  const getSubmitText = () => {
    if (loginType === 'login') {
      return intl.formatMessage({
        id: 'master.auth.login.title',
        defaultMessage: 'Đăng nhập',
      });
    }
    if (loginType === 'otp') {
      return intl.formatMessage({
        id: 'master.auth.otp.button.title',
        defaultMessage: 'Verify OTP',
      });
    }
    return intl.formatMessage({
      id: 'master.auth.forgot.button.title',
      defaultMessage: 'Send Reset Link',
    });
  };

  const handleBackToLogin = () => {
    setPending2faToken('');
    setLoginType('login');
  };

  return (
    <ConfigProvider
      theme={{
        algorithm: isDark ? theme.darkAlgorithm : theme.defaultAlgorithm,
      }}
    >
      <div
        style={{
          backgroundColor: isDark ? '#000' : 'white',
          height: '100vh',
        }}
      >
        {contextHolder}
        <LoginFormPage
          backgroundImageUrl="https://mdn.alipayobjects.com/huamei_gcee1x/afts/img/A*y0ZTS6WLwvgAAAAAAAAAAAAADml6AQ/fmt.webp"
          logo={getLogoImage()}
          backgroundVideoUrl="https://gw.alipayobjects.com/v/huamei_gcee1x/afts/video/jXRBRK_VAwoAAAAAAAAAAAAAK4eUAQBr"
          title={
            <span style={{ color: token.colorBgContainer }}>
              {intl.formatMessage({
                id: getDomainTitle(),
                defaultMessage: 'Smatec',
              })}
            </span>
          }
          containerStyle={{
            backgroundColor: 'rgba(0, 0, 0,0.65)',
            backdropFilter: 'blur(4px)',
          }}
          subTitle={<Image preview={false} src={mobifontLogo} />}
          submitter={{
            searchConfig: {
              submitText: getSubmitText(),
            },
          }}
          onFinish={async (values: any) => handleLogin(values)}
        >
          <FormWrapper animationKey={loginType}>
            {loginType === 'login' && <LoginForm />}
            {loginType === 'forgot' && <ForgotPasswordForm />}
            {loginType === 'otp' && <OtpForm />}
          </FormWrapper>
          <Flex
            justify="flex-end"
            align="flex-start"
            style={{ marginBlockEnd: 16 }}
          >
            <Button
              type="link"
              size="small"
              onClick={() => {
                if (loginType === 'login') {
                  setLoginType('forgot');
                } else {
                  handleBackToLogin();
                }
              }}
            >
              {loginType === 'login' ? (
                <FormattedMessage
                  id="master.auth.forgot.title"
                  defaultMessage="Quên mật khẩu?"
                />
              ) : (
                <FormattedMessage
                  id="master.auth.backToLogin.title"
                  defaultMessage="Back to Login"
                />
              )}
            </Button>
          </Flex>
        </LoginFormPage>
        <div className="absolute top-5 right-5 z-50 flex gap-4">
          <ThemeSwitcherAuth />
          <LangSwitches />
        </div>
        <div
          style={{
            backgroundColor: 'transparent',
            position: 'absolute',
            bottom: 0,
            zIndex: 99,
            width: '100%',
          }}
        >
          <Footer />
        </div>
      </div>
    </ConfigProvider>
  );
};

export default LoginPage;
