/** @format */

import {
	GithubOutlined,
	GitlabOutlined,
	LockOutlined,
	MobileOutlined,
	QqOutlined,
	SafetyOutlined,
	UserOutlined,
	WechatOutlined,
	WechatWorkOutlined,
} from "@ant-design/icons";
import {
	CaptFieldRef,
	ProFormCaptcha,
	ProFormCheckbox,
	ProFormText,
} from "@ant-design/pro-components";
import {
	Alert,
	Button,
	ConfigProvider,
	Divider,
	Form,
	Image,
	message,
	Space,
	Spin,
	Tabs,
	Tooltip,
} from "antd";
import { CSSProperties, useEffect, useRef, useState } from "react";
import logo from "@/assets/images/logo.png";
import styles from "./index.module.less";
import { observer } from "mobx-react";
import useStore from "@/utils/store/useStore.tsx";
import FooterComponent from "@/components/Footer";
import RotateCaptcha, { CaptchaInstance, type TicketInfoType } from "react-rotate-captcha";
import { get, load } from "@/api/captcha/index.ts";
import {
	createClientId,
	generateQRCode,
	getClientToken,
	getSms,
	login,
	loginByPhone,
	oauthLogin,
} from "@/api/user";
import { TinyColor } from "@ctrl/tinycolor";
import { useNavigate } from "react-router-dom";
import { setStorage } from "@/utils/localStorage/config.ts";

import { TimerManager } from "timer-manager-lib";

type LoginType = "account" | "phone";

const iconStyles: CSSProperties = {
	color: "rgba(0, 0, 0, 0.2)",
	fontSize: "18px",
	verticalAlign: "middle",
	cursor: "pointer",
};

export default observer(() => {
	const [form] = Form.useForm();
	const smsCaptcha = useRef<CaptchaInstance>(null);
	const loginCaptcha = useRef<CaptchaInstance>(null);
	const loginByPhoneCaptcha = useRef<CaptchaInstance>(null);
	const captchaRef = useRef<CaptFieldRef | null | undefined>();
	const [QRCode, setQRCode] = useState<string>("");
	const navigate = useNavigate();
	const store = useStore("user");
	const colors = ["#40e495", "#30dd8a", "#2bb673"];
	const timerManager = new TimerManager();
	const [loading, setLoading] = useState<boolean>(true);
	const getHoverColors = (colors: string[]) =>
		colors.map((color) => new TinyColor(color).lighten(5).toString());
	const getActiveColors = (colors: string[]) =>
		colors.map((color) => new TinyColor(color).darken(5).toString());

	async function smsVerify(token: string, deg: number): Promise<TicketInfoType> {
		const phone = form.getFieldValue("mobile");
		const data: any = {
			token: token,
			deg: deg,
			phone: phone,
		};
		const res: any = await getSms(data);
		if (res && res.code === 0) {
			message.open({
				content: res.data,
				type: "success",
				duration: 5,
			});
		} else {
			message.open({
				content: res.data,
				type: "warning",
				duration: 5,
			});
		}
		return res;
	}

	async function loginVerify(token: string, deg: number): Promise<TicketInfoType> {
		const userName = form.getFieldValue("username");
		const password = form.getFieldValue("password");
		const data: API.LoginRequest = {
			token: token,
			deg: deg,
			userName: userName,
			password: password,
		};
		const res: any = await login(data);
		if (res && res.success && res.code === 0) {
			store.setToken(res.data.token);
			store.setUserId(res.data.user.id);
			store.setName(res.data.user.userName);
			store.setAvatar(res.data.user.avatar);
			store.setNickName(res.data.user.nickName);
			setStorage("token", res.data.token, 24 * 60 * 30);
			setStorage("userId", res.data.user.id, 24 * 60 * 30);
			if (store.getToken() !== null || store.getUserId() !== null) {
				setTimeout(() => {
					navigate("/main/home");
				}, 3000);
			}
			message.open({
				content: "登录成功！",
				type: "success",
				duration: 5,
			});
		} else if (res.code === 0 && !res.success) {
			message.open({
				content: "登录失败！用户名或密码错误！",
				type: "error",
				duration: 5,
			});
		}
		return res;
	}

	async function loginByPhoneVerify(token: string, deg: number): Promise<TicketInfoType> {
		const mobile = form.getFieldValue("mobile");
		const captcha = form.getFieldValue("captcha");
		const data: API.LoginByPhoneRequest = {
			token: token,
			deg: deg,
			phone: mobile,
			activeCode: captcha,
		};
		const res: any = await loginByPhone(data);
		if (res && res.success && res.code === 0) {
			store.setToken(res.data.token);
			store.setUserId(res.data.user.id);
			setStorage("token", res.data.token, 24 * 60 * 30);
			setStorage("userId", res.data.user.id, 24 * 60 * 30);
			if (store.getToken() !== null || store.getUserId() !== null) {
				setTimeout(() => {
					navigate("/main");
				}, 3000);
			}
			message.open({
				content: "登录成功！",
				type: "success",
				duration: 5,
			});
		} else if (res.code === 0 && !res.success) {
			message.open({
				content: "登录失败！",
				type: "error",
				duration: 5,
			});
		}
		return res;
	}

	const items = [
		{
			label: (
				<span>
					<UserOutlined />
					账户登录
				</span>
			),
			key: "account",
		},
		{
			label: (
				<span>
					<MobileOutlined />
					短信登录
				</span>
			),
			key: "phone",
		},
	];

	async function oAuthLogin(type: string) {
		const res: any = await oauthLogin(type);
		window.open(res.data, "_self");
	}

	const [loginType, setLoginType] = useState<LoginType>("account");

	async function openSmsCaptcha() {
		smsCaptcha.current!.open();
	}

	async function openLoginCaptcha() {
		loginCaptcha.current!.open();
	}

	async function openLoginByPhoneCaptcha() {
		loginByPhoneCaptcha.current!.open();
	}

	async function wechatLogin() {
		createClientId().then((res: any) => {
			generateQRCode(res.data).then((response: any) => {
				if (res && response.success && res.data) {
					setQRCode(response.data.qrCodeUrl);
					setLoading(false);
					timerManager.add(() => {
						getClientToken(res.data).then((result: any) => {
							if (result.success) {
								timerManager.clear();
								store.setToken(result.data.tokenValue);
								store.setUserId(result.data.loginId);
								setStorage("token", result.data.tokenValue, 24 * 60 * 30);
								setStorage("userId", result.data.loginId, 24 * 60 * 30);
								message
									.open({
										content: "登录成功！",
										type: "success",
									})
									.then();
								if (store.getToken() !== null || store.getUserId() !== null) {
									setTimeout(() => {
										navigate("/main");
									}, 2000);
								}
							}
						});
					}, 3000);
				} else {
					message
						.open({
							content: response.data,
							type: "error",
						})
						.then();
				}
			});
		});
	}

	useEffect(() => {
		wechatLogin().then();
	}, []);

	return (
		<div className={styles.container}>
			<RotateCaptcha get={get} load={load} verify={smsVerify} limit={2} ref={smsCaptcha} />
			<RotateCaptcha
				get={get}
				load={load}
				verify={loginVerify}
				limit={2}
				ref={loginCaptcha}
			/>
			<RotateCaptcha
				get={get}
				load={load}
				limit={2}
				verify={loginByPhoneVerify}
				ref={loginByPhoneCaptcha}
			/>
			<div className={styles.content}>
				<Space className={styles.content_content}>
					<Space className={styles.login_content}>
						<Space align="center" className={styles.mp_code}>
							<Space direction="vertical" align="center">
								<span className={styles.mp_code_title}>微信扫码登录</span>
								<Spin tip="Loading" size="large" spinning={loading}>
									<Image
										preview={false}
										height={200}
										width={200}
										className={styles.mp_code_img}
										// src={generateMpRegCodeData.data?.qrCodeUrl}
										src={QRCode}
									/>
								</Spin>
								<Alert
									// message={(<span>微信扫码<span>关注公众号</span></span>)}
									description={
										<div>
											<span>
												微信扫码
												<span className={styles.mp_tips}>关注公众号</span>
											</span>
											<br />
											登录更快更安全
										</div>
									}
									// type="success"
									showIcon={true}
									className={styles.alert}
									icon={<WechatOutlined />}
								/>
							</Space>
						</Space>
						<Form
							form={form}
							className={styles.login_form}
							initialValues={{
								autoLogin: true,
							}}>
							<Space direction="vertical" align="center">
								<Space className={styles.logo}>
									<img
										alt="logo"
										src={logo}
										style={{ width: "44px", height: "44px" }}
									/>
									<span>五味子云存储</span>
								</Space>
								<div className={styles.subTitle}>随时随地分享你的美好瞬间</div>
							</Space>

							<Tabs
								centered={true}
								items={items}
								activeKey={loginType}
								onChange={(activeKey) =>
									setLoginType(activeKey as LoginType)
								}></Tabs>

							{loginType === "account" && (
								<>
									<ProFormText
										name="username"
										fieldProps={{
											size: "large",
											prefix: <UserOutlined className={"prefixIcon"} />,
										}}
										placeholder={"请输入邮箱或电话号码"}
										rules={[
											{
												required: true,
												message: "请输入用户名!",
											},
										]}
									/>
									<ProFormText.Password
										name="password"
										fieldProps={{
											size: "large",
											prefix: <LockOutlined className={"prefixIcon"} />,
										}}
										placeholder={"请输入密码"}
										rules={[
											{
												required: true,
												message: "请输入密码！",
											},
											{
												pattern:
													/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z\\W]{6,18}$/,
												message:
													"密码长度需在6~18位字符，且必须包含字母和数字！",
											},
										]}
									/>
								</>
							)}
							{loginType === "phone" && (
								<>
									<ProFormText
										fieldProps={{
											size: "large",
											prefix: <MobileOutlined className={"prefixIcon"} />,
											autoComplete: "off",
										}}
										name="mobile"
										placeholder={"请输入手机号"}
										rules={[
											{
												required: true,
												message: "请输入手机号！",
											},
											{
												pattern: /^1\d{10}$/,
												message: "手机号格式错误！",
											},
										]}
									/>
									<ProFormCaptcha
										fieldProps={{
											size: "large",
											prefix: <SafetyOutlined className={"prefixIcon"} />,
										}}
										captchaProps={{
											size: "large",
										}}
										placeholder={"请输入验证码"}
										captchaTextRender={(timing: boolean, count: number) => {
											if (timing) {
												return `${count} ${"获取验证码"}`;
												// return `${"获取验证码"}`;
											}
											return "获取验证码";
										}}
										name="captcha"
										phoneName={"mobile"}
										rules={[
											{
												required: true,
												message: "请输入验证码！",
											},
										]}
										fieldRef={captchaRef}
										countDown={60}
										onGetCaptcha={async () => {
											await openSmsCaptcha();
										}}
									/>
								</>
							)}
							<div style={{ marginBlockEnd: 14 }}>
								<ProFormCheckbox noStyle name="autoLogin">
									自动登录
								</ProFormCheckbox>
								<a href={"/forget"} style={{ float: "right" }}>
									忘记密码
								</a>
							</div>
							<ConfigProvider
								theme={{
									components: {
										Button: {
											colorPrimary: `linear-gradient(116deg,  ${colors.join(", ")})`,
											colorPrimaryHover: `linear-gradient(116deg, ${getHoverColors(colors).join(", ")})`,
											colorPrimaryActive: `linear-gradient(116deg, ${getActiveColors(colors).join(", ")})`,
											lineWidth: 0,
										},
									},
								}}>
								<Button
									type="primary"
									block
									size="large"
									onClick={async () => {
										let validateFields;
										if (loginType === "account") {
											validateFields = ["username", "password"];
										} else {
											validateFields = ["mobile", "captcha"];
										}

										await form
											.validateFields(validateFields)
											.then(async () => {
												if (loginType === "account") {
													await openLoginCaptcha();
												} else {
													await openLoginByPhoneCaptcha();
												}
											})
											.catch((error) => {
												console.error(error);
											});
									}}>
									登录
								</Button>
							</ConfigProvider>

							<div
								style={{
									display: "flex",
									justifyContent: "center",
									alignItems: "center",
									flexDirection: "column",
								}}>
								<Divider plain>
									<span
										style={{
											color: "#CCC",
											fontWeight: "normal",
											fontSize: 14,
										}}>
										其他登录方式
									</span>
								</Divider>
								<Space align="center" size={24}>
									<div
										style={{
											display: "flex",
											justifyContent: "center",
											alignItems: "center",
											flexDirection: "column",
											height: 40,
											width: 40,
											border: "1px solid #D4D8DD",
											borderRadius: "50%",
										}}>
										<Tooltip title="QQ登录" color={"blue"}>
											<QqOutlined
												onClick={() => {
													message
														.open({
															content: "敬请期待！",
															type: "info",
															duration: 3,
														})
														.then();
												}}
												style={{ ...iconStyles, color: "#1677FF" }}
											/>
										</Tooltip>
									</div>
									<div
										style={{
											display: "flex",
											justifyContent: "center",
											alignItems: "center",
											flexDirection: "column",
											height: 40,
											width: 40,
											border: "1px solid #D4D8DD",
											borderRadius: "50%",
										}}>
										<Tooltip title="企业微信登录" color={"green"}>
											<WechatWorkOutlined
												onClick={() => {
													oAuthLogin("wechat").then();
												}}
												style={{ ...iconStyles, color: "#08a327" }}
											/>
										</Tooltip>
									</div>
									<div
										style={{
											display: "flex",
											justifyContent: "center",
											alignItems: "center",
											flexDirection: "column",
											height: 40,
											width: 40,
											border: "1px solid #D4D8DD",
											borderRadius: "50%",
										}}>
										<Tooltip title="github登录" color={"black"}>
											<GithubOutlined
												onClick={() => {
													oAuthLogin("github").then();
												}}
												style={{ ...iconStyles, color: "#333333" }}
											/>
										</Tooltip>
									</div>
									<div
										style={{
											display: "flex",
											justifyContent: "center",
											alignItems: "center",
											flexDirection: "column",
											height: 40,
											width: 40,
											border: "1px solid #D4D8DD",
											borderRadius: "50%",
										}}>
										<Tooltip title="gitee登录" color={"orange"}>
											<GitlabOutlined
												onClick={() => {
													oAuthLogin("gitee").then();
												}}
												style={{ ...iconStyles, color: "#FF6A10" }}
											/>
										</Tooltip>
									</div>
								</Space>
							</div>
						</Form>
						<a href="/register" className={styles.go_to_register}>
							<span>注册</span>
						</a>
					</Space>
				</Space>
			</div>
			<FooterComponent></FooterComponent>
		</div>
	);
});
