<template>
	<div
		class="lockscreen"
		:class="lockClassName"
	>
		<el-card
			class="login-box"
			shadow="never"
		>
			<div class="avatar-container">
				<el-avatar size="large">
					<img
						src="/logo.png"
						alt="Logo"
					/>
				</el-avatar>
			</div>
			<el-form
				v-if="!isRegisterMode"
				label-position="left"
				label-width="0px"
			>
				<el-form-item>
					<el-input
						v-model="userName"
						placeholder="请输入用户名"
						autofocus
						prefix-icon="UserFilled"
					></el-input>
				</el-form-item>
				<el-form-item v-if="!sys._options.noPassword">
					<el-input
						v-model="userPassword"
						type="password"
						placeholder="请输入登录密码"
						show-password
						prefix-icon="Key"
						@keyup.enter="onLogin"
					></el-input>
				</el-form-item>
				<el-button
					type="primary"
					@click="onLogin"
					>登录</el-button
				>
				<div class="divider">
					<span>第三方登录</span>
				</div>
				<div class="third-party-login">
					<img
						v-for="platform in thirdPartyPlatforms"
						:key="platform.name"
						:src="platform.icon"
						:alt="platform.name"
						style="
							width: 25px;
							height: 25px;
							cursor: pointer;
							color: #409eff;
						"
						@click="onThirdPartyLogin(platform.name)"
					/>
				</div>
				<div
					class="actions"
					v-if="config.userType === 'member'"
				>
					<a
						href="#"
						@click.prevent="toggleRegister"
						>注册新用户</a
					>
					<a
						href="#"
						@click.prevent="toggleUserSwitch"
						>切换角色</a
					>
				</div>
			</el-form>
			<el-form
				v-else
				label-position="left"
				label-width="0px"
				:model="regForm"
				ref="regFormRef"
				:rules="rules"
			>
				<el-form-item prop="username">
					<el-input
						v-model="regForm.username"
						placeholder="请输入用户名"
						prefix-icon="UserFilled"
					></el-input>
				</el-form-item>
				<el-form-item prop="nickname">
					<el-input
						v-model="regForm.nickname"
						placeholder="请输入真实姓名"
						prefix-icon="Avatar"
					></el-input>
				</el-form-item>
				<el-form-item prop="email">
					<el-input
						v-model="regForm.email"
						placeholder="请输入邮箱"
						prefix-icon="Message"
					></el-input>
				</el-form-item>
				<el-form-item prop="phone">
					<el-input
						v-model="regForm.phone"
						placeholder="请输入手机号"
						prefix-icon="Iphone"
					></el-input>
				</el-form-item>
				<el-form-item prop="password">
					<el-input
						v-model="regForm.password"
						type="password"
						placeholder="请输入密码"
						show-password
						prefix-icon="Key"
					></el-input>
				</el-form-item>
				<el-form-item prop="confirmPassword">
					<el-input
						v-model="regForm.confirmPassword"
						type="password"
						placeholder="请再次输入密码"
						show-password
						prefix-icon="Lock"
					></el-input>
				</el-form-item>
				<el-button
					type="primary"
					@click="onRegister"
					>注册</el-button
				>
				<div class="actions">
					<a
						href="#"
						@click.prevent="toggleRegister"
						>返回登录</a
					>
				</div>
			</el-form>
		</el-card>
	</div>
</template>

<script lang="ts" setup>
	import { useLoginStore } from "@/stores/login";
	import { useSystem } from "@/system";
	import { getSystemConfig, setSystemConfig } from "@/system/config";
	import router from "@/system/router";
	import { RestartApp } from "@/util/goutil";
	import { notifyError } from "@/util/msg";
	import { onMounted, ref } from "vue";
	const store = useLoginStore();
	const sys = useSystem();
	const loginCallback = sys._options.loginCallback;
	const config = getSystemConfig();
	const lockClassName = ref("screen-show");
	const isRegisterMode = ref(false);

	const thirdPartyPlatforms = [
		{
			name: "wechat",
			icon: new URL("@/assets/login/wechat.png", import.meta.url).href,
		},
		{
			name: "qq",
			icon: new URL("@/assets/login/qq.png", import.meta.url).href,
		},
		{
			name: "sina",
			icon: new URL("@/assets/login/sina.png", import.meta.url).href,
		},
		{
			name: "github",
			icon: new URL("@/assets/login/github.png", import.meta.url).href,
		},
		{
			name: "gitee",
			icon: new URL("@/assets/login/gitee.png", import.meta.url).href,
		},
	];

	function loginSuccess() {
		lockClassName.value = "screen-hidean";
		setTimeout(() => {
			lockClassName.value = "screen-hide";
		}, 500);
	}

	const userName = ref("");
	const userPassword = ref("");

	onMounted(() => {
		if (config.userType === "person") {
			userName.value = sys._options.login?.username || "admin";
			userPassword.value = sys._options.login?.password || "";
		} else {
			userName.value = config.userInfo.username;
			userPassword.value = config.userInfo.password;
		}
	});

	// 监听code参数
	watch(
		() => router.currentRoute.value.query.code,
		() => {
			onLogin();
		}
	);

	const onLogin = async () => {
		localStorage.removeItem("godoosClientId");
		if (loginCallback) {
			const platform = store.ThirdPartyPlatform;
			const code = router.currentRoute.value.query.code as string;

			// 使用映射对象，将平台名称映射到相应的参数名称
			const platformCodeMap: Record<string, string> = {
				github: "github_code",
				gitee: "gitee_code",
				wechat: "wechat_code",
				qq: "qq_code",
			};

			// 获取对应的参数名称
			const codeParam = platform ? platformCodeMap[platform] : null;

			let res;
			if (codeParam) {
				// 第三方登录统一调用
				const returnedState = router.currentRoute.value.query
					.state as string;

				console.log(returnedState, "---", store.State);

				if (returnedState !== store.State) {
					notifyError("登录失败，请重试");
					return;
				}

				res = await loginCallback(userName.value, userPassword.value, {
					[codeParam]: code,
				});
			} else {
				// 普通登录
				res = await loginCallback(userName.value, userPassword.value);
			}

			if (res) {
				store.ThirdPartyPlatform = null;
				loginSuccess();
			} else {
				notifyError("登录失败，请重试");
			}
		}
	};

	const toggleRegister = () => {
		isRegisterMode.value = !isRegisterMode.value;
	};

	const toggleUserSwitch = () => {
		config.userType = "person";
		setSystemConfig(config);
		RestartApp();
	};

	const regForm = ref({
		username: "",
		password: "",
		confirmPassword: "",
		email: "",
		phone: "",
		nickname: "",
	});
	const regFormRef: any = ref(null);

	const rules = {
		username: [
			{ required: true, message: "用户名不能为空", trigger: "blur" },
			{
				min: 3,
				max: 20,
				message: "用户名长度应在3到20个字符之间",
				trigger: "blur",
			},
		],
		password: [
			{ required: true, message: "密码不能为空", trigger: "blur" },
			{ min: 6, message: "密码长度不能小于6位", trigger: "blur" },
		],
		confirmPassword: [
			{ required: true, message: "请再次输入密码", trigger: "blur" },
			{
				validator: (rule: any, value: any, callback: any) => {
					console.log(rule);
					if (value === "") {
						callback(new Error("请再次输入密码"));
					} else if (value !== regForm.value.password) {
						callback(new Error("两次输入的密码不一致"));
					} else {
						callback();
					}
				},
				trigger: "blur",
			},
		],
		email: [
			{ required: true, message: "邮箱不能为空", trigger: "blur" },
			{
				type: "email",
				message: "请输入有效的邮箱地址",
				trigger: ["blur", "change"],
			},
		],
		phone: [
			{ required: true, message: "手机号不能为空", trigger: "blur" },
			{
				pattern: /^1[3-9]\d{9}$/,
				message: "请输入有效的手机号",
				trigger: "blur",
			},
		],
		nickname: [
			{ required: true, message: "昵称不能为空", trigger: "blur" },
			{
				min: 2,
				max: 20,
				message: "昵称长度应在2到20个字符之间",
				trigger: "blur",
			},
		],
	};

	const onRegister = async () => {
		try {
			await regFormRef.value.validate();
			const save = toRaw(regForm.value);
			const userInfo = config.userInfo;
			const comp = await fetch(userInfo.url + "/member/register", {
				method: "POST",
				body: JSON.stringify(save),
			});
			if (!comp.ok) {
				notifyError("网络错误，注册失败");
				return;
			}
			const res = await comp.json();
			if (res.success) {
				notifyError("注册成功");
				toggleRegister();
			} else {
				notifyError(res.message);
				return;
			}
		} catch (error) {
			console.error(error);
		}
	};

	const onThirdPartyLogin = async (platform: string) => {
		let loginFunction: (() => Promise<boolean>) | undefined;
		// 当前选择的第三方登录方式
		store.ThirdPartyPlatform = platform;
		switch (platform) {
			case "github":
				// 跳转到 GitHub 授权页面
				loginFunction = async function () {
					return await authWithGithub();
				};
				break;
			case "wechat":
				loginFunction = async function () {
					return await authWithWechat();
				};
				break;
			case "qq":
				loginFunction = async function () {
					return await authWithQQ();
				};
				break;
			case "sina":
				loginFunction = async function () {
					return await authWithSina();
				};
				break;
			case "gitee":
				loginFunction = async function () {
					return await authWithGitee();
				};
				break;
			default:
				notifyError("不支持的第三方登录平台");
				return;
		}

		if (loginFunction) {
			const success = await loginFunction();
			if (success) {
				loginSuccess();
			} else {
				notifyError("登录失败");
			}
		}
	};

	const authWithGithub = async (): Promise<boolean> => {
		// 传递state用于防止CSRF攻击,使用时间戳加随机字符串
		const state = Date.now() + Math.random().toString(36).substring(2, 15);
		store.State = state;
		const url = config.userInfo.url + "/github/authorize?state=" + state;
		const res: any = await fetch(url, {
			method: "POST",
			body: JSON.stringify({
				state: state,
			}),
		});
		if (!res.ok) {
			return false;
		}
		const data = await res.json();
		console.log(data.data.url);
		window.location.href = data.data.url;
		return true;
	};

	const authWithWechat = (): boolean | PromiseLike<boolean> => {
		throw new Error("Function not implemented.");
	};

	const authWithQQ = (): boolean | PromiseLike<boolean> => {
		throw new Error("Function not implemented.");
	};

	const authWithSina = (): boolean | PromiseLike<boolean> => {
		throw new Error("Function not implemented.");
	};

	const authWithGitee = async (): Promise<boolean> => {
		// 传递state用于防止CSRF攻击,使用时间戳加随机字符串
		const state = Date.now() + Math.random().toString(36).substring(2, 15);
		store.State = state;
		const url = config.userInfo.url + "/gitee/authorize?state=" + state;
		const res: any = await fetch(url, {
			method: "POST",
			body: JSON.stringify({
				state: state,
			}),
		});
		if (!res.ok) {
			return false;
		}
		const data = await res.json();
		// 跳转到Gitee授权页面
		window.location.href = data.data.url;
		return true;
	};
</script>

<style scoped lang="scss">
	.lockscreen {
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		z-index: 201;
		display: flex;
		justify-content: center;
		align-items: center;
		overflow: hidden;
		color: #fff;
		background-color: rgba(25, 28, 34, 0.78);
		backdrop-filter: blur(7px);

		.login-box {
			width: 300px;
			padding: 20px;
			text-align: center;
			background: #ffffff;
			border-radius: 10px;
			box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
			border: 1px solid #e0e0e0;

			.avatar-container {
				margin-bottom: 20px;
			}

			.el-input {
				width: 100%;
				margin-bottom: 10px;
				background: #f9f9f9;
				border-radius: 4px;
			}

			.el-button {
				width: 100%;
				margin-top: 10px;
				background: #409eff;
				color: #ffffff;
				border: none;
				border-radius: 4px;
				transition: background 0.3s ease;
			}

			.el-button:hover {
				background: #66b1ff;
			}

			.tip {
				padding: 4px 0;
				font-size: 12px;
				color: red;
				height: 30px;
			}

			.actions {
				margin-top: 10px;
				display: flex;
				justify-content: space-between;

				a {
					color: #409eff;
					text-decoration: none;
					cursor: pointer;

					&:hover {
						text-decoration: underline;
					}
				}
			}
		}

		.screen-hidean {
			animation: outan 0.5s forwards;
		}

		.screen-hide {
			display: none;
		}

		.third-party-login {
			margin-top: 10px;
			display: flex;
			justify-content: center;
			gap: 15px;

			el-icon {
				font-size: 24px;
				cursor: pointer;
				transition: color 0.3s ease;

				&:hover {
					color: #409eff;
				}
			}
		}

		.divider {
			display: flex;
			align-items: center;
			text-align: center;
			margin: 20px 0;
			color: #999;
			font-size: 14px;

			&::before,
			&::after {
				content: "";
				flex: 1;
				border-bottom: 1px solid #ddd;
			}

			&::before {
				margin-right: 0.25em;
			}

			&::after {
				margin-left: 0.25em;
			}
		}
	}

	@keyframes outan {
		0% {
			opacity: 1;
		}

		30% {
			opacity: 0;
		}

		100% {
			transform: translateY(-100%);
			opacity: 0;
		}
	}
</style>
