import LogoIcon from '@/assets/images/gpustack-logo.png';
import { initialPasswordAtom, userAtom } from '@/atoms/user';
import LangSelect from '@/components/lang-select';
import SealInput from '@/components/seal-form/seal-input';
import ThemeDropActions from '@/components/theme-toggle/theme-drop-actions';
import externalLinks from '@/constants/external-links';
import {
  CRYPT_TEXT,
  REMEMBER_ME_KEY,
  getRememberMe,
  rememberMe,
  removeRememberMe
} from '@/utils/localstore/index';
import { LockOutlined, UserOutlined } from '@ant-design/icons';
import { useIntl, useModel } from '@umijs/max';
import { Button, Checkbox, Form } from 'antd';
import { createStyles } from 'antd-style';
import CryptoJS from 'crypto-js';
import { useAtom } from 'jotai';
import { useEffect, useMemo } from 'react';
import { flushSync } from 'react-dom';
import { login } from '../apis';
import { checkDefaultPage } from '../utils';

const authConfig = await fetchAuthConfig('/get_config'); // get authentication configuration
const useStyles = createStyles(({ token, css }) => ({
  header: css`
    display: flex;
    align-items: center;
    gap: 8px;
    position: fixed;
    right: 0;
    top: 0;
    height: 60px;
    padding: 20px;
    .anticon-global {
      color: ${token.colorText};
    }
    .anticon:hover {
      color: ${token.colorTextTertiary};
    }
  `
}));
// function authentication configuration method
async function fetchAuthConfig(url) {
  try {
    const response = await fetch(url);
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
  } catch (error) {
    console.error('OIDC config error:', error);
    throw error;
  }
};

const LoginForm = () => {
  const { styles } = useStyles();
  const [userInfo, setUserInfo] = useAtom(userAtom);
  const [initialPassword, setInitialPassword] = useAtom(initialPasswordAtom);
  const { initialState, setInitialState } = useModel('@@initialState') || {};
  const intl = useIntl();
  const [form] = Form.useForm();

  const renderWelCome = useMemo(() => {
    return (
      <div
        style={{
          display: 'flex',
          marginBottom: 32,
          fontSize: 20,
          justifyContent: 'center',
          alignItems: 'center'
        }}
      >
        <div className="flex-center">
          <span>{intl?.formatMessage({ id: 'users.login.title' })}</span>
          <img
            src={LogoIcon}
            alt="logo"
            style={{ height: '24px', marginLeft: 10 }}
          />
        </div>
      </div>
    );
  }, [intl]);

  const gotoDefaultPage = async (userInfo: any) => {
    checkDefaultPage(userInfo, true);
  };

  const fetchUserInfo = async () => {
    const userInfo = await initialState?.fetchUserInfo?.();

    if (userInfo) {
      flushSync(() => {
        setInitialState((s: any) => ({
          ...s,
          currentUser: userInfo
        }));
      });
    }
    return userInfo;
  };

  const encryptPassword = (password: string) => {
    const psw = CryptoJS.AES?.encrypt?.(password, CRYPT_TEXT).toString();
    return psw;
  };
  const decryptPassword = (password: string) => {
    const bytes = CryptoJS.AES?.decrypt?.(password, CRYPT_TEXT);
    const res = bytes.toString(CryptoJS.enc.Utf8);
    return res;
  };

  const callRememberMe = async (values: any) => {
    const { autoLogin } = values;
    if (autoLogin) {
      await rememberMe(REMEMBER_ME_KEY, {
        um: encryptPassword(values.username),
        pw: encryptPassword(values.password),
        f: true
      });
    } else {
      await removeRememberMe(REMEMBER_ME_KEY);
    }
  };

  const callGetRememberMe = async () => {
    const rememberMe = await getRememberMe(REMEMBER_ME_KEY);

    if (rememberMe?.f) {
      const username = decryptPassword(rememberMe?.um);
      const password = decryptPassword(rememberMe?.pw);
      form.setFieldsValue({ username, password, autoLogin: true });
    }
  };
  // OIDC certification
  const handleOidcLogin = async () => {
    const authUrl = `${authConfig.base_entrypoint}auth?response_type=code&client_id=${authConfig.CLIENT_ID}&redirect_uri=${authConfig.redirect_uri}&scope=openid profile email&state=random_state_string`;
    window.location.href = authUrl;};
  // SAML certification
  const handleSamlLogin = async () => {
      window.location.href = "/auth/saml/login";}
  // Handling certification callbacks
  useEffect(()  => {
    const params = new URLSearchParams(window.location.search);
    const code = params.get('code'); // OIDC callback information
    console.log(code)
    const samlResponse = params.get('SAMLResponse'); // SAML callback information
    const allParams = Object.fromEntries(params.entries());
    history.replaceState({}, '', window.location.pathname);
    if (code) { login({
        code: code
      }).then(async () => {
      const userInfo = await fetchUserInfo();
      await setUserInfo(userInfo);
      gotoDefaultPage(userInfo);
    });
    };
    if (samlResponse) { login({
        SAMLResponse: decodeURIComponent(samlResponse)
      }).then(async () => {
      const userInfo = await fetchUserInfo();
      await setUserInfo(userInfo);
      gotoDefaultPage(userInfo);
    })};
  }, []);
  const handleLogin = async (values: any) => {
    try {
      await login({
        username: values.username,
        password: values.password
      });

      const userInfo = await fetchUserInfo();
      setUserInfo(userInfo);
      if (values.autoLogin) {
        await callRememberMe(values);
      } else {
        await removeRememberMe(REMEMBER_ME_KEY);
      }
      if (!userInfo?.require_password_change) {
        gotoDefaultPage(userInfo);
      } else {
        setInitialPassword(encryptPassword(values.password));
      }
    } catch (error) {
      // to do something
    }
  };

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

  return (
    <div>
      <div className={styles.header}>
        <ThemeDropActions></ThemeDropActions>
        <LangSelect />
      </div>
      <div>
        <Form
          form={form}
          style={{ width: '360px', margin: '0 auto' }}
          onFinish={handleLogin}
        >
          {renderWelCome}
          <Form.Item
            name="username"
            rules={[
              {
                required: true,
                message: intl.formatMessage(
                  { id: 'common.form.rule.input' },
                  { name: intl.formatMessage({ id: 'common.form.username' }) }
                )
              }
            ]}
          >
            <SealInput.Input
              label={intl.formatMessage({ id: 'common.form.username' })}
              prefix={<UserOutlined />}
            />
          </Form.Item>

          <Form.Item
            name="password"
            rules={[
              {
                required: true,
                message: intl.formatMessage(
                  { id: 'common.form.rule.input' },
                  { name: intl.formatMessage({ id: 'common.form.password' }) }
                )
              }
            ]}
          >
            <SealInput.Password
              prefix={<LockOutlined />}
              label={intl.formatMessage({ id: 'common.form.password' })}
            />
          </Form.Item>
          <div
            className="flex-center flex-between"
            style={{
              marginBottom: 24
            }}
          >
            <Form.Item noStyle name="autoLogin" valuePropName="checked">
              <Checkbox style={{ marginLeft: 5 }}>
                <span style={{ color: 'var(--ant-color-text-secondary)' }}>
                  {intl.formatMessage({ id: 'common.login.rember' })}
                </span>
              </Checkbox>
            </Form.Item>
            <Button
              type="link"
              size="small"
              href={externalLinks.resetPassword}
              target="_blank"
              style={{ padding: 0 }}
            >
              {intl.formatMessage({ id: 'common.button.forgotpassword' })}
            </Button>
          </div>
          <Button onClick={handleOidcLogin}
                type="primary"
                block
                style={{ height: '48px', fontSize: '14px', display: authConfig?.is_oidc ? 'block': 'none'}}
                >
                  {intl.formatMessage({ id: 'common.button.oidclogin' })}
                </Button>
          <Button onClick={handleSamlLogin}
                type="primary"
                block
                style={{ height: '48px', fontSize: '14px', display: authConfig?.is_saml ? 'block': 'none'}}
                >
                  {intl.formatMessage({ id: 'common.button.samllogin' })}
                </Button>
          <Button
                htmlType="submit"
                type="link"
                block
                style={{ height: '48px', fontSize: '14px' }}
              >
                {intl.formatMessage({ id: 'common.button.login' })}
              </Button>
        </Form>
      </div>
    </div>
  );
};

export default LoginForm;
