import { ThemeMode } from '@/common/cache';
import { encrptRsa, validatePasswordComplexity, validatePasswordComplexityInititalValue, ValidatePasswordComplexityType } from '@/common/helper';
import { Footer, PasswordComplexityValidation, ThemeSwitch } from '@/components';
import { isDarkTheme } from '@/layouts/RootLayout';
import { loginByAccount } from '@/services/account';
import SysAuthController from '@/services/apis/SysAuthController';
import { LoadingOutlined, LockOutlined, UserOutlined } from '@ant-design/icons';
import type { ProFormInstance } from '@ant-design/pro-components';
import { ProForm, ProFormCheckbox, ProFormText } from '@ant-design/pro-components';
import { useEmotionCss } from '@ant-design/use-emotion-css';
import { useModel } from '@umijs/max';
import { Alert, App, ConfigProvider, theme, Tooltip, Typography } from 'antd';
import { useCallback, useEffect, useRef, useState } from 'react';
import defaultSettings from '../../../../config/defaultSettings';
import packageInfo from '../../../../package.json';

const version = packageInfo.version;

const REMEMBER_ME = 'ytwms_account';
type LoginType = {
    status: string;
    type: 'scan' | 'account';
    errorMessage?: string;
    isActivated: boolean;
    orgName?: string;
};

type LoginFormValueType = Omit<API.LoginInput, 'captcha'> & {
    rememberMe: boolean;
    captchaCode?: string;
};

const Login: React.FC = () => {
    const styles = {
        theme: useEmotionCss(({ token }) => {
            return {
                position: 'fixed',
                top: token.marginLG,
                right: token.marginLG,
            };
        }),
        container: useEmotionCss(({ token }) => {
            return {
                display: 'flex',
                flexDirection: 'column',
                alignItems: 'center',
                justifyContent: 'center',
                width: '100vw',
                height: '100vh',
                boxShadow: '0 0 80px rgba(0, 0, 0, 0.4) inset',
                backgroundImage: `url('https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr')`,
                backgroundSize: '100% 100%',
                backgroundColor: token.colorBgContainer,
            };
        }),
        body: useEmotionCss(({ token }) => {
            const mbSize = token.paddingMD * 2;
            return {
                display: 'flex',
                flexDirection: 'row',
                alignItems: 'stretch',
                width: 840,
                minHeight: 528,
                padding: mbSize,
                backgroundColor: token.colorBgElevated,
                border: `1px solid ${token.colorBgElevated}`,
                borderRadius: token.borderRadiusLG,
                boxShadow: `0 0 ${mbSize}px rgba(0, 0, 0, 0.1)`,
                '.left': {
                    display: 'flex',
                    flex: 1,
                    flexDirection: 'column',
                    alignItems: 'stretch',
                    paddingRight: mbSize,
                    borderRight: `1px solid ${token.colorBorder}`,
                    '.logo': {
                        display: 'flex',
                        flexDirection: 'row',
                        alignItems: 'center',
                        '> img': {
                            width: 32,
                        },
                        '> div': {
                            marginLeft: token.paddingSM,
                            color: token.colorTextSecondary,
                            fontSize: token.fontSizeHeading3,
                            lineHeight: 1,
                            paddingBottom: 4,
                        },
                    },
                    '.avatar': {
                        display: 'flex',
                        flex: 1,
                        flexDirection: 'column',
                        alignItems: 'center',
                        marginTop: mbSize,
                        '> img': {
                            width: 320,
                        },
                    },

                    '.contacts': {
                        marginTop: mbSize,
                        color: token.colorTextDescription,
                        fontSize: token.fontSizeSM,
                    },
                },
                '.right': {
                    display: 'flex',
                    flex: 1,
                    flexDirection: 'column',
                    alignItems: 'stretch',
                    paddingLeft: mbSize,
                    '.form-title': {
                        paddingBottom: token.padding,
                        marginBottom: token.marginLG * 2,
                        color: token.colorTextSecondary,
                        fontSize: token.fontSizeHeading3,
                        lineHeight: '32px',
                        textAlign: 'center',
                        letterSpacing: 2,
                        borderBottom: `1px solid ${token.colorBorder}`,
                    },
                    '.ant-form': {
                        input: {
                            ':-internal-autofill-selected': {
                                boxShadow: `inset 0 0 0 1000px ${token.colorBgContainer} !important`,
                                backgroundColor: `${token.colorBgContainer} !important`,
                                WebkitTextFillColor: token.colorText,
                            },
                        },
                    },
                    '.tab-label': {
                        fontSize: token.fontSizeHeading5,
                    },
                },
            };
        }),
        footer: useEmotionCss(({ token }) => {
            return {
                display: 'flex',
                flexDirection: 'column',
                alignItems: 'center',
                justifyContent: 'center',
                // height: 64,
                '.tip': {
                    paddingTop: token.paddingSM,
                    paddingBottom: token.paddingSM,
                    color: token.colorTextSecondary,
                    fontSize: token.fontSize,
                    textAlign: 'center',
                    '> p': {
                        margin: 0,
                        padding: 0,
                    }
                },
            };
        }),
        captcha: useEmotionCss(({ token }) => {
            return {
                display: 'flex',
                flexDirection: 'row',
                alignItems: 'center',
                '> .captcha-img': {
                    height: 28,
                    marginLeft: 4,
                    marginTop: -2,
                    marginBottom: -2,
                },
                '> .refresh-code': {
                    fontSize: token.fontSize,
                },
            };
        }),
        ding: useEmotionCss(({ token }) => {
            return {
                display: 'flex',
                flexDirection: 'column',
                alignItems: 'center',
                '.qr-code': {
                    minHeight: 304,
                    minWidth: 240,
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                },
                '.qr-code-error': {
                    color: token.colorError,
                },
                '.tip': {
                    marginTop: token.margin,
                    color: token.colorTextSecondary,
                    display: 'flex',
                    flexDirection: 'row',
                    alignItems: 'center',
                },
                '.ding-icon': {
                    color: token.colorPrimary,
                    fontSize: 16,
                    marginRight: token.marginXS,
                },
            };
        }),
    };

    const [submitting, setSubmitting] = useState(false);
    const [userLoginState, setUserLoginState] = useState<LoginType>({
        status: '',
        type: 'account',
        isActivated: true,
    });

    const [captchaLoading, setCaptchaLoading] = useState<boolean>(false);
    const [captcha, setCaptcha] = useState<API.GeneralCaptchaOutput>();

    const { initialState, setInitialState } = useModel('@@initialState');
    const { message } = App.useApp();

    const formRef = useRef<ProFormInstance>();

    const { minLen, maxLen, special } = validatePasswordComplexityInititalValue;
    const [passwordValid, setPasswordValid] = useState<ValidatePasswordComplexityType>({ minLen, maxLen, special });

    // 获取验证码
    const fetchCaptcha = useCallback(async () => {
        setCaptchaLoading(true);
        const captcha = await SysAuthController.getCaptcha();
        setCaptchaLoading(false);
        if (captcha) {
            setCaptcha(captcha);
        }
    }, []);
    useEffect(() => {
        fetchCaptcha();
    }, [fetchCaptcha]);

    useEffect(() => {
        const rme = localStorage.getItem(REMEMBER_ME);
        if (rme) {
            const maccount = JSON.parse(rme) as LoginFormValueType;
            formRef.current?.setFieldsValue(maccount ?? {});
        }
    }, []);

    const fetchUserInfo = async () => {
        const userInfo = await initialState?.fetchUserInfo?.();
        if (userInfo) {
            await setInitialState((s) => ({
                ...s,
                currentUser: userInfo,
            }));
        }
    };

    const handleSubmit = async (values: LoginFormValueType) => {
        setSubmitting(true);
        try {
            const { rememberMe, password, account, captchaCode, newPassword } = values;
            const pwd = encrptRsa(password) || '';
            const auth = await loginByAccount({
                account,
                password: pwd,
                newPassword: newPassword ? encrptRsa(newPassword) || '' : '',
                captcha: {
                    captchaCode: captchaCode ?? '',
                    token: captcha?.token,
                },
            });
            if (!auth) {
                throw '登录失败' as any;
            }
            message.success('登录成功');

            if (auth.isActivated) {
                if (rememberMe) {
                    localStorage.setItem(REMEMBER_ME, JSON.stringify({ account, password, rememberMe }));
                } else {
                    localStorage.removeItem(REMEMBER_ME);
                }
                await fetchUserInfo();
                location.replace('/');
            }
            else {
                setUserLoginState((v) => ({
                    ...v,
                    isActivated: false,
                    orgName: auth.orgName,
                    status: '',
                    errorMessage: '',
                }));
                formRef.current?.setFieldsValue({ captchaCode: '' });
                await fetchCaptcha();
            }
        } catch (error: any) {
            await fetchCaptcha();
            formRef.current?.setFieldsValue({ captchaCode: '' });

            let errMsg = '';
            if ((typeof error).toLowerCase() === 'string') {
                errMsg = error;
            } else {
                errMsg = error?.info?.errorMessage ?? error?.message ?? '登录错误';
            }
            setUserLoginState((v) => ({ ...v, status: 'error', errorMessage: errMsg }));
        } finally {
            setSubmitting(false);
        }
    };

    const { status, errorMessage, isActivated, orgName } = userLoginState;

    const custTheme = ThemeMode.get();
    let algorithm: any[] = [theme.defaultAlgorithm];
    if (custTheme?.themeMode === 'auto' && isDarkTheme || custTheme?.themeMode === 'dark') {
        algorithm = [theme.darkAlgorithm];
    }

    return (
        <ConfigProvider theme={{
            algorithm,
            token: {
                colorPrimary: defaultSettings.colorPrimary,
            }
        }} >
            <div className={styles.container}>
                <div className={styles.theme}>
                    <ThemeSwitch />
                </div>
                <div className={styles.body}>
                    <div className="left">
                        <div className="logo">
                            <img src="/images/logo.svg" alt="logo" />
                            <div>{AppConfig.systemName}</div>
                        </div>
                        <div className="avatar">
                            <img src="/images/login-avatar-320.png" alt="login caption" />
                        </div>
                        {!isActivated && <Alert
                            // message={`当前用户暂未激活，属于【${orgName}】，暂未激活，若学校有误请勿激活，首次登录请输入新密码更换登录密码！`}
                            message={
                                <>
                                    <Typography.Text>当前用户</Typography.Text>
                                    <Typography.Text type="danger">未激活</Typography.Text>
                                    <Typography.Text>，属于</Typography.Text>
                                    <Typography.Text mark> {orgName} </Typography.Text>
                                    <Typography.Text>，设置新密码后以激活用户。若用户和学校有误请联系管理员处理，请勿激活！</Typography.Text>
                                </>
                            }
                            type="warning"
                            showIcon
                            style={{ marginBottom: 24 }}
                        />}
                        <div className="contacts">
                            <Tooltip
                                trigger="click"
                                title={
                                    <ul style={{ margin: 0, padding: 0, listStyleType: 'none' }}>
                                        <li>
                                            v{version}.{AppConfig.edition}
                                        </li>
                                        {AppConfig.edition === 'debug' && (
                                            <li>{AppConfig.apiRoot}</li>
                                        )}
                                    </ul>
                                }
                            >
                                {version}
                            </Tooltip>
                        </div>
                    </div>
                    <div className="right">
                        {isActivated && <h1 className="form-title">用户登录</h1>}
                        {status === 'error' && (
                            <Alert
                                message={errorMessage ?? '错误的用户名和密码！'}
                                type="error"
                                showIcon
                                style={{ marginBottom: 24, marginTop: -24 }}
                            />
                        )}
                        <ProForm<LoginFormValueType>
                            formRef={formRef}
                            size="large"
                            isKeyPressSubmit={true}
                            layout="horizontal"
                            labelAlign="left"
                            labelCol={{ span: isActivated ? 6 : 7 }}
                            submitter={{
                                searchConfig: {
                                    submitText: '登录',
                                },
                                render: (_, dom) => dom.pop(),
                                submitButtonProps: {
                                    loading: submitting,
                                    style: { marginTop: 24, width: '100%' },
                                },
                            }}
                            onFinish={async (values) =>
                                await handleSubmit(values)
                            }
                        >
                            <ProFormText
                                label="用户名"
                                name="account"
                                fieldProps={{
                                    prefix: <UserOutlined />,
                                }}
                                placeholder="用户名"
                                rules={[
                                    {
                                        required: true,
                                        message: '请输入账户!',
                                    },
                                ]}
                            />
                            <ProFormText.Password
                                label={isActivated ? '密码' : "初始密码"}
                                name="password"
                                fieldProps={{
                                    prefix: <LockOutlined />,
                                }}
                                placeholder="登录密码"
                                rules={[
                                    {
                                        required: true,
                                        message: '请输入登录密码！',
                                    },
                                ]}
                            />
                            {!isActivated && <>
                                <ProFormText.Password
                                    label="新密码"
                                    name="newPassword"
                                    fieldProps={{
                                        prefix: <LockOutlined />,
                                        minLength: 6,
                                        maxLength: 32,
                                        showCount: true,
                                    }}
                                    placeholder="新密码"
                                    required
                                    rules={[
                                        // { required: true, min: 6, max: 32 },
                                        ({ getFieldValue }) => ({
                                            validator: (_, value) => {
                                                const op = getFieldValue("password");
                                                if (value === op) {
                                                    return Promise.reject("新密码不能与初始密码一致");
                                                }
                                                // const np2 = getFieldValue('newPasswordConfirm');
                                                // if (!np2 || np2 === '' || np2 === value) {
                                                //     return Promise.resolve();
                                                // }
                                                // return Promise.reject('两次输入新密码不一致！');

                                                const r = validatePasswordComplexity(value);
                                                setPasswordValid(r);
                                                if (!r.isValid) {
                                                    return Promise.reject('新密码不符合密码规则要求');
                                                }
                                                return Promise.resolve();
                                            },
                                        }),
                                    ]}
                                />
                                <PasswordComplexityValidation result={passwordValid} />
                                <ProFormText.Password
                                    label="确认新密码"
                                    name="newPasswordConfirm"
                                    fieldProps={{
                                        prefix: <LockOutlined />,
                                        minLength: 6,
                                        maxLength: 32,
                                        showCount: true,
                                    }}
                                    rules={[
                                        { required: true },
                                        ({ getFieldValue }) => ({
                                            validator: (_, value) => {
                                                const np = getFieldValue('newPassword');
                                                if (np === value) {
                                                    return Promise.resolve();
                                                }
                                                return Promise.reject('两次输入新密码不一致！');
                                            },
                                        }),
                                    ]}
                                />
                            </>}
                            <ProFormText
                                label="验证码"
                                name="captchaCode"
                                fieldProps={{
                                    // size: 'large',
                                    minLength: 4,
                                    maxLength: 4,
                                    suffix: (
                                        <div className={styles.captcha}>
                                            {captcha?.imageBase64 && (
                                                <img
                                                    className="captcha-img"
                                                    src={`data:image/png;base64,${captcha.imageBase64}`}
                                                    onClick={fetchCaptcha}
                                                />
                                            )}
                                            {captchaLoading ? (
                                                <LoadingOutlined />
                                            ) : (
                                                <Tooltip title="点击获取新的验证码">
                                                    <a className="refresh-code" onClick={fetchCaptcha}>换一个</a>
                                                </Tooltip>
                                            )}
                                        </div>
                                    ),
                                }}
                                placeholder="验证码"
                                rules={[
                                    {
                                        required: true,
                                        min: 4,
                                        max: 4,
                                        message: '请输入4位验证码!',
                                    },
                                ]}
                            />

                            <ProFormCheckbox noStyle name="rememberMe">
                                记住账户和密码
                            </ProFormCheckbox>
                        </ProForm>
                    </div>
                </div>
                <div className={styles.footer}>
                    <div className="tip">
                        <p>本系统不支持IE浏览器，推荐使用谷歌、Microsoft Edge浏览器，或360、QQ等浏览器极速模式</p>
                        <p>为了更好的使用体验，推荐使用 1920 * 1080 及以上分辨率显示器</p>
                    </div>
                    <Footer />
                </div>
            </div>
        </ConfigProvider>
    );
};

export default Login;
