<template>
	<cl-page background-color="#fff">
		<cl-topbar :border="false" background-color="transparent" />

		<view class="page-login">
			<!-- Logo -->
			<view class="logo">
				<image src="/static/logo.png" mode="aspectFill" />
				<text>{{ app.info.name }}</text>
			</view>

			<div class="container">
				<!-- 登录方式 -->
				<view class="mode" :class="[`is-${mode}`]">
					<!-- 手机号 -->
					<template v-if="mode == 'phone'">
						<text class="label">手机号登录</text>

						<view class="phone">
							<text>+86</text>
							<cl-input
								v-model="phone"
								type="number"
								placeholder="请填写手机号码"
								:border="false"
								:maxlength="11"
								:font-size="30"
								background-color="transparent"
							/>
						</view>

						<sms-btn
							:ref="setRefs('smsBtn')"
							:phone="phone"
							@success="phoneLogin(false)"
						>
							<template #default="{ disabled, btnText }">
								<cl-button
									fill
									type="primary"
									:height="90"
									:font-size="30"
									:disabled="disabled"
									@tap="phoneLogin"
								>
									{{ btnText }}
								</cl-button>
							</template>
						</sms-btn>
					</template>

					<!-- 微信登录 -->
					<template v-else-if="mode == 'wx'">
						<cl-button
							type="primary"
							fill
							:height="90"
							:font-size="30"
							:loading="loading"
							@tap="wxLogin"
						>
							微信一键登录
						</cl-button>
					</template>

					<!-- 协议 -->
					<view class="agree">
						<agree-btn :ref="setRefs('agreeBtn')" />
					</view>
				</view>
			</div>

			<!-- 其他登录方式 -->
			<view class="other" v-if="!isEmpty(platformsEnv)">
				<cl-divider width="400rpx" background-color="#ffffff">
					<cl-text color="#ccc" value="其他登录方式" />
				</cl-divider>

				<view class="platform">
					<view
						class="platform__item"
						v-for="(item, index) in platformsEnv"
						:key="index"
						@tap="changeMode(item)"
					>
						<image :src="item.icon" mode="aspectFit" v-if="item.icon" />
						<text>{{ item.label }}</text>
					</view>
				</view>
			</view>
		</view>
	</cl-page>
</template>

<script lang="ts" setup>
import { computed, reactive, ref } from "vue";
import { onReady } from "@dcloudio/uni-app";
import { useApp, useCool, useStore, useWx } from "/@/cool";
import { useUi } from "/$/cool-ui";
import SmsBtn from "/@/components/sms-btn.vue";
import AgreeBtn from "/@/components/agree-btn.vue";
import { config } from "/@/config";
import { ctx } from "virtual:ctx";
import { cloneDeep, isEmpty } from "lodash-es";

interface Platform {
	label: string;
	value: any;
	icon?: string;
	hidden?: boolean;
	onClick?: () => void;
}

const { service, router, refs, setRefs, storage } = useCool();
const { user } = useStore();
const app = useApp();
const ui = useUi();
const wx = useWx();

// 登录中
const loading = ref(false);

// 手机号
const phone = ref(storage.get("phone") || "");

// 登录方式
const mode = ref();

// 登录平台
const platforms = ref<Platform[]>([
	{
		label: "通过手机登录",
		value: "phone",
		icon: "/pages/user/static/icon/phone.png",
		hidden: false,
	},
	{
		label: "通过微信登录",
		value: "wx",
		icon: "/pages/user/static/icon/wx.png",
		hidden: true,
	},
]);

// 环境校验
const platformsEnv = computed(() => {
	let arr = cloneDeep(platforms.value);

	// #ifdef H5
	if (wx.isWxBrowser()) {
		arr[1].hidden = false;
	}
	// #endif

	// #ifdef MP-WEIXIN
	arr[1].hidden = false;
	// #endif

	// 过滤隐藏的
	arr = arr.filter((e) => !e.hidden);

	// 默认第一个登录方式
	if (!mode.value) {
		mode.value = arr[0]?.value;
	}

	// 过滤不是当前登录方式
	return arr.filter((e) => e.value != mode.value);
});

// 切换模式
function changeMode(item: Platform) {
	if (item.onClick) {
		item.onClick();
	} else {
		mode.value = item.value;
	}
}

// 登录请求
async function nextLogin(key: "mini" | "mp" | "uniPhone", data: any) {
	return service.user.login[key](data)
		.then(async (res) => {
			// 设置token
			user.setToken(res);

			// 获取用户信息
			await user.get();

			// 登录跳转
			router.nextLogin(key);
		})
		.catch((err) => {
			ui.showTips(err.message);
		});
}

// 短信登录
function phoneLogin(sms?: boolean) {
	if (sms) {
		check(() => {
			refs.smsBtn.open();
		});
	} else {
		storage.set("phone", phone.value);

		router.push({
			path: "/pages/user/captcha",
			query: {
				phone: phone.value,
			},
		});
	}
}

// 微信登录
function wxLogin() {
	check(async () => {
		// #ifdef APP
		if (wx.hasApp()) {
			wx.appLogin().then((code) => {
				//
			});
		} else {
			ui.showConfirm({
				title: "温馨提示",
				message: "您还未安装微信~",
				showCancelButton: false,
				confirmButtonText: "去下载",
				callback(action) {
					if (action == "confirm") {
						wx.downloadApp();
					}
				},
			});
		}
		// #endif

		// #ifdef MP-WEIXIN
		loading.value = true;

		await wx
			.miniLogin()
			.then(async (res) => {
				await nextLogin("mini", res);
			})
			.catch((err) => {
				ui.showToast(err.message);
			});

		loading.value = false;
		// #endif

		// #ifdef H5
		wx.mpAuth();
		// #endif
	});
}

// 公众号登录
function mpLogin() {
	// #ifdef H5
	wx.mpLogin().then(async (code) => {
		if (code) {
			ui.showLoading();
			await nextLogin("mp", { code });
			ui.hideLoading();
		}
	});
	// #endif
}

// 协议检测
function check(cb: () => void) {
	if (refs.agreeBtn.check()) {
		cb();
	}
}

// 手机号一键登录
const univerify = reactive({
	error: "",

	check() {
		// #ifdef APP
		uni.preLogin({
			provider: "univerify",
			success() {
				platforms.value.push({
					label: "手机号一键登录",
					value: "univerify",
					onClick() {
						univerify.login();
					},
				});
			},
			fail(err) {
				univerify.error = err.metadata?.msg || "当前环境不支持一键登录，请切换至验证码登录";
			},
		});
		// #endif
	},

	login() {
		uni.login({
			provider: "univerify",
			univerifyStyle: {
				authButton: {
					normalColor: "#6b69f8",
					highlightColor: "#6b69f8",
					disabledColor: "#73aaf5",
					textColor: "#ffffff",
					title: "一键登录",
					borderRadius: "12px",
				},
				privacyTerms: {
					defaultCheckBoxState: true, // 条款勾选框初始状态
					textColor: "#BBBBBB",
					termsColor: "#5496E3",
					prefix: "我已阅读并同意",
					suffix: "并使用本机号码登录",
					privacyItems: [
						// 自定义协议条款，最大支持2个，需要同时设置url和title. 否则不生效
						{
							url: `${config.baseUrl}/app/base/comm/html?key=userAgreement`,
							title: "用户协议",
						},
						{
							url: `${config.baseUrl}/app/base/comm/html?key=privacyPolicy`,
							title: "隐私政策",
						},
					],
				},
			},
			async success(res: { authResult: any }) {
				await nextLogin("uniPhone", {
					appId: ctx.appid,
					...res.authResult,
				});

				uni.closeAuthView();
			},
			fail() {
				if (univerify.error) {
					ui.showToast(univerify.error);
				}
			},
		});
	},
});

// 手机号一键登录环境检测
univerify.check();

onReady(() => {
	// 公众号登录授权回调
	mpLogin();
});
</script>

<style lang="scss" scoped>
.page-login {
	.logo {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		padding-top: 20%;

		image {
			display: block;
			height: 150rpx;
			width: 150rpx;
			border-radius: 24rpx;
			margin-bottom: 30rpx;
			box-shadow: 0 25rpx 30rpx -25rpx #666666;
		}

		text {
			font-size: 36rpx;
			font-weight: bold;
			letter-spacing: 1rpx;
			color: #333;
		}
	}

	.container {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		margin-top: 80rpx;

		.mode {
			width: 100%;
			padding: 0 80rpx;
			box-sizing: border-box;

			.label {
				display: block;
				font-size: 36rpx;
				font-weight: 500;
				margin-bottom: 30rpx;
			}

			&.is-phone {
				.phone {
					display: flex;
					align-items: center;
					background-color: #eeeeee;
					border-radius: 10rpx;
					height: 90rpx;
					margin-bottom: 30rpx;
					font-size: 30rpx;

					text {
						display: inline-block;
						padding: 0 40rpx;
						border-right: $cl-border-width solid $cl-border-color;
						font-weight: bold;
						color: #404040;
					}

					input {
						height: 100%;
						flex: 1;
						padding: 0 30rpx;
					}
				}
			}
		}

		.agree {
			text-align: center;
			margin: 50rpx -60rpx 0 0;
		}
	}

	.other {
		margin-top: 100rpx;

		.platform {
			display: flex;
			flex-direction: column;
			align-items: center;
			margin: 20rpx 0 60rpx 0;

			&__item {
				display: flex;
				align-items: center;
				justify-content: center;
				border: 1px solid #000000;
				height: 30px;
				width: 130px;
				margin-bottom: 28rpx;
				border-radius: 6px;
				background-color: #ffffff;

				image {
					height: 32rpx;
					width: 32rpx;
					margin-right: 10rpx;
				}

				text {
					font-size: 24rpx;
					color: #000000;
				}
			}
		}
	}
}
</style>
