<template>
	<div class="flex h-screen overflow-hidden sm:bg-gray-50">
		<div class="w-full overflow-auto">
			<LoginBox
				:title="title"
				:class="{ 'pointer-events-none': $resources.signup.loading }"
			>
				<template v-slot:default>
					<div v-if="!(resetPasswordEmailSent || otpRequested)">
						<form class="flex flex-col" @submit.prevent="submitForm">
							<!-- 2FA 部分 -->
							<template v-if="is2FA">
								<FormControl
									:label="$t('2FA code from your authenticator app')"
									placeholder="123456"
									v-model="twoFactorCode"
									required
								/>
								<Button
									class="mt-4"
									:loading="
										$resources.verify2FA.loading ||
										$session.login.loading ||
										$resources.resetPassword.loading
									"
									variant="solid"
									@click="
										$resources.verify2FA.submit({
											user: email,
											totp_code: twoFactorCode,
										})
									"
								>
									{{ $t('Verify') }}
								</Button>
								<ErrorMessage
									class="mt-2"
									:message="$resources.verify2FA.error"
								/>
							</template>

							<!-- 忘记密码部分 -->
							<template v-else-if="hasForgotPassword">
								<FormControl
									:label="$t('Email')"
									type="email"
									placeholder="email@example.com"
									autocomplete="email"
									v-model="email"
									required
								/>
								<router-link
									class="mt-2 text-sm"
									v-if="hasForgotPassword"
									:to="{
										name: 'Login',
										query: { ...$route.query, forgot: undefined },
									}"
								>
									{{ $t('I remember my password') }}
								</router-link>
								<Button
									class="mt-4"
									:loading="$resources.resetPassword.loading"
									variant="solid"
								>
									{{ $t('Reset Password') }}
								</Button>
							</template>

							<!-- 登录部分 -->
							<template v-else-if="isLogin">
								<FormControl
									:label="$t('Username or Email')"
									placeholder="email@example.com"
									autocomplete="email"
									v-model="email"
									:disabled="otpSent && useEmail"
									required
								/>

								<!-- 密码验证 -->
								<template v-if="!isOauthLogin && !useEmail">
									<FormControl
										class="mt-4"
										:label="$t('Password')"
										type="password"
										placeholder="•••••"
										v-model="password"
										name="password"
										autocomplete="current-password"
										required
									/>
									<div class="mt-2 flex flex-col gap-2">
										<router-link
											class="text-sm"
											:to="{
												name: 'Login',
												query: { ...$route.query, forgot: 1 },
											}"
										>
											{{ $t('Forgot Password?') }}
										</router-link>
									</div>
									<Button
										class="mt-4"
										variant="solid"
										:loading="$session.login.loading"
										type="submit"
									>
										{{ $t('Log In') }}
									</Button>
								</template>

								<!-- OTP 验证 -->
								<template v-else-if="useEmail">
									<!-- OTP 验证输入（当 OTP 已发送时） -->
									<template v-if="otpSent">
										<FormControl
											class="mt-4"
											:label="$t('Verification Code')"
											placeholder="123456"
											v-model="otp"
											required
										/>
										<div class="mt-4 space-y-2">
											<Button
												class="w-full"
												:loading="$resources.verifyOTPAndLogin.loading"
												variant="solid"
												@click="verifyOTPAndLogin"
											>
												{{ $t('Log In') }}
											</Button>
											<Button
												class="w-full"
												:loading="$resources.sendOTP.loading"
												variant="outline"
												:disabled="otpResendCountdown > 0"
												@click="$resources.sendOTP.submit()"
											>
												{{ $t('Resend Verification Code') }}
												{{
													otpResendCountdown > 0
														? ` ${$t('in')} ${otpResendCountdown} ${$t('seconds')}`
														: ''
												}}
											</Button>
										</div>
									</template>

									<!-- 初始 OTP 请求按钮 -->
									<template v-else>
										<Button
											class="mt-4"
											:loading="$resources.sendOTP.loading"
											variant="solid"
											@click="$resources.sendOTP.submit()"
										>
											{{ $t('Send Verification Code') }}
										</Button>
									</template>
								</template>

								<!-- OAuth 验证 -->
								<template v-else>
									<Button class="mt-4" variant="solid">
										{{ $t('Log in with') }} {{ oauthProviderName }}
									</Button>
								</template>

								<!-- 错误信息 -->
								<ErrorMessage
									class="mt-2"
									:message="
										$session.login.error ||
										$resources.is2FAEnabled.error ||
										$resources.sendOTP.error ||
										$resources.verifyOTPAndLogin.error
									"
								/>
							</template>

							<!-- 注册部分 -->
							<template v-else>
								<FormControl
									:label="$t('Username')"
									type="text"
									:placeholder="$t('Set username')"
									v-model="username"
									autocomplete="username"
									required
								/>
								<FormControl
									:label="$t('Email (optional)')"
									type="email"
									placeholder="email@example.com"
									autocomplete="email"
									class="mt-4"
									v-model="email"
								/>
								<FormControl
									:label="$t('Phone Number')"
									type="tel"
									:placeholder="$t('Please enter your phone number')"
									class="mt-4"
									v-model="phoneNumber"
									autocomplete="tel"
									required
									@blur="validatePhoneNumber"
								/>
								<div v-if="phoneNumberFormatError" class="mt-2 text-sm text-red-600">
									{{ $t('Please enter a valid phone number format') }}
								</div>
								<FormControl
									:label="$t('Password')"
									type="password"
									:placeholder="$t('Set login password')"
									class="mt-4"
									v-model="signupPassword"
									autocomplete="new-password"
									required
								/>
								<div class="mt-1 text-sm text-gray-600">
									{{ $t('Password must be at least 8 characters and contain uppercase and lowercase letters and numbers') }}
								</div>
								<div class="mt-2" v-if="signupPassword">
									<div class="flex items-center">
										<div class="text-sm w-20">{{ $t('Password Strength') }}:</div>
										<div class="flex-1 bg-gray-200 rounded-full h-2">
											<div 
												class="h-2 rounded-full transition-all" 
												:class="passwordStrengthClass"
												:style="{width: passwordStrength + '%'}"></div>
										</div>
										<div class="ml-2 text-sm" :class="passwordStrengthTextClass">{{passwordStrengthText}}</div>
									</div>
								</div>
								<FormControl
									:label="$t('Confirm Password')"
									type="password"
									:placeholder="$t('Enter password again')"
									class="mt-4"
									v-model="confirmPassword"
									autocomplete="new-password"
									required
								/>
								<div v-if="passwordMismatch" class="mt-2 text-sm text-red-600">
									{{ $t('Passwords do not match') }}
								</div>
								<Button
									class="mt-4"
									:loading="$resources.signupWithUsername.loading"
									variant="solid"
									type="submit"
									:disabled="(passwordMismatch && confirmPassword) || phoneNumberFormatError"
								>
									{{ $t('Sign Up') }}
								</Button>
							</template>

							<ErrorMessage class="mt-2" :message="error" />
						</form>
						<div
							class="flex flex-col"
							v-if="!hasForgotPassword && !isOauthLogin && !is2FA"
						>
							<div class="-mb-2 mt-6 border-t text-center">
								<div class="-translate-y-1/2 transform">
									<span
										class="relative bg-white px-2 text-sm font-medium leading-8 text-gray-800"
									>
										{{ $t('Or') }}
									</span>
								</div>
							</div>

							<div class="flex flex-col gap-2">
								<Button
									v-if="isLogin && !useEmail"
									@click="switchToEmailLogin"
									icon-left="mail"
								>
									{{ $t('Log in with email verification code') }}
								</Button>
								<Button
									v-else-if="isLogin && useEmail"
									@click="switchToPasswordLogin"
									icon-left="key"
								>
									{{ $t('Log in with password') }}
								</Button>
							</div>
							<div
								class="mt-6 text-center"
								v-if="!(otpRequested || resetPasswordEmailSent)"
							>
								<router-link
									class="text-center text-base font-medium text-gray-900 hover:text-gray-700"
									:to="{
										name: $route.name == 'Login' ? 'Signup' : 'Login',
										query: { ...$route.query, forgot: undefined },
									}"
								>
									{{
										$route.name == 'Login'
											? $t("Don't have an account? Create one.")
											: $t('Already have an account? Log in.')
									}}
								</router-link>
							</div>
						</div>
					</div>
					<div v-else-if="otpRequested">
						<form class="flex flex-col">
							<FormControl
								:label="$t('Email')"
								type="email"
								placeholder="email@example.com"
								autocomplete="email"
								v-model="email"
								required
							/>
							<FormControl
								:label="$t('Verification Code')"
								type="text"
								class="mt-4"
								placeholder="123456"
								maxlength="6"
								v-model="otp"
								required
							/>
							<ErrorMessage
								class="mt-2"
								:message="$resources.verifyOTP.error"
							/>
							<Button
								class="mt-4"
								variant="solid"
								:loading="$resources.verifyOTP.loading"
								@click="$resources.verifyOTP.submit()"
							>
								{{ $t('Verify') }}
							</Button>
							<Button
								class="mt-2"
								variant="outline"
								:loading="$resources.resendOTP.loading"
								@click="$resources.resendOTP.submit()"
								:disabled="otpResendCountdown > 0"
							>
								{{ $t('Resend Verification Code') }}
								{{
									otpResendCountdown > 0
										? ` ${$t('in')} ${otpResendCountdown} ${$t('seconds')}`
										: ''
								}}
							</Button>
						</form>
						<div class="mt-6 text-center">
							<router-link
								class="text-center text-base font-medium text-gray-900 hover:text-gray-700"
								:to="{
									name: $route.name == 'Login' ? 'Signup' : 'Login',
									query: { ...$route.query, forgot: undefined },
								}"
							>
								{{
									$route.name == 'Login'
										? $t('New user? Create a new account.')
										: $t('Already have an account? Log in.')
								}}
							</router-link>
						</div>
					</div>
					<div
						class="text-p-base text-gray-700"
						v-else-if="resetPasswordEmailSent"
					>
						<p>
							{{ $t('We have sent an email to') }}
							<span class="font-semibold">{{ email }}</span
							>{{ $t('. Please click on the link received to reset your password.') }}
						</p>
					</div>
				</template>
				<template v-slot:logo v-if="saasProduct">
					<div class="mx-auto flex items-center space-x-2">
						<img
							class="inline-block h-7 w-7 rounded-sm"
							:src="saasProduct?.logo"
						/>
						<span
							class="select-none text-xl font-semibold tracking-tight text-gray-900"
						>
							{{ saasProduct?.title }}
						</span>
					</div>
				</template>
				<template v-slot:footer v-if="saasProduct">
					<div
						class="mt-2 flex w-full items-center justify-center text-sm text-gray-600"
					>
						{{ $t('Powered by Jingrow') }}
					</div>
				</template>
			</LoginBox>
		</div>
	</div>
</template>

<script>
import LoginBox from '../components/auth/LoginBox.vue';
import { toast } from 'vue-sonner';
import { getToastErrorMessage } from '../utils/toast';

export default {
	name: 'Signup',
	components: {
		LoginBox,
	},
	data() {
		return {
			email: '',
			username: '',
			phoneNumber: '',
			signupPassword: '',
			account_request: '',
			otpRequested: false,
			otp: '',
			otpSent: false,
			twoFactorCode: '',
			password: null,
			otpResendCountdown: 0,
			resetPasswordEmailSent: false,
			confirmPassword: '',
			phoneNumberFormatError: false,
		};
	},
	mounted() {
		this.email = localStorage.getItem('login_email');
		setInterval(() => {
			if (this.otpResendCountdown > 0) {
				this.otpResendCountdown -= 1;
			}
		}, 1000);
	},
	watch: {
		email() {
			this.resetSignupState();
		},
	},
	resources: {
		signup() {
			return {
				url: 'jcloud.api.account.signup',
				params: {
					email: this.email,
					referrer: this.getReferrerIfAny(),
					product: this.$route.query.product,
				},
				onSuccess(account_request) {
					this.account_request = account_request;
					this.otpRequested = true;
					this.otpResendCountdown = 30;
					toast.success(this.$t('Verification code has been sent to your email'));
				},
				onError: (error) => {
					if (error?.exc_type !== 'ValidationError') {
						return;
					}
					let errorMessage = '';
					if ((error?.messages ?? []).length) {
						errorMessage = error?.messages?.[0];
					}
					// check if error message has `is already registered` substring
					if (errorMessage.includes('is already registered')) {
						localStorage.setItem('login_email', this.email);

						if (this.$route.query?.product) {
							this.$router.push({
								name: 'Login',
								query: {
									redirect: `/dashboard/create-site/${this.$route.query.product}/setup`,
								},
							});
						} else {
							this.$router.push({
								name: 'Login',
							});
						}
					}
				},
			};
		},
		verifyOTP() {
			return {
				url: 'jcloud.api.account.verify_otp',
				params: {
					account_request: this.account_request,
					otp: this.otp,
				},
				onSuccess(key) {
					window.open(`/dashboard/setup-account/${key}`, '_self');
				},
			};
		},
		resendOTP() {
			return {
				url: 'jcloud.api.account.resend_otp',
				params: {
					account_request: this.account_request,
				},
				onSuccess() {
					this.otp = '';
					this.otpResendCountdown = 30;
					toast.success(this.$t('Verification code has been sent to your email'));
				},
				onError(err) {
					toast.error(
						getToastErrorMessage(err, this.$t('Failed to resend verification code')),
					);
				},
			};
		},
		sendOTP() {
			return {
				url: 'jcloud.api.account.send_otp',
				params: {
					email: this.email,
				},
				onSuccess() {
					this.otpSent = true;
					this.otpResendCountdown = 30;
					toast.success(this.$t('Verification code has been sent to your email'));
				},
				onError(err) {
					toast.error(
						getToastErrorMessage(err, this.$t('Failed to send verification code')),
					);
				},
			};
		},
		verifyOTPAndLogin() {
			return {
				url: 'jcloud.api.account.verify_otp_and_login',
				params: {
					email: this.email,
					otp: this.otp,
				},
				onSuccess(res) {
					this.afterLogin(res);
				},
			};
		},
		oauthLogin() {
			return {
				url: 'jcloud.api.oauth.oauth_authorize_url',
				onSuccess(url) {
					localStorage.setItem('login_email', this.email);
					window.location.href = url;
				},
			};
		},
		resetPassword() {
			return {
				url: 'jcloud.api.account.send_reset_password_email',
				onSuccess() {
					this.resetPasswordEmailSent = true;
				},
			};
		},
		signupSettings() {
			return {
				url: 'jcloud.api.account.signup_settings',
				params: {
					product: this.$route.query.product,
				},
				auto: true,
			};
		},
		is2FAEnabled() {
			return {
				url: 'jcloud.api.account.is_2fa_enabled',
			};
		},
		verify2FA() {
			return {
				url: 'jcloud.api.account.verify_2fa',
				onSuccess: async () => {
					if (this.isLogin) {
						if (!this.useEmail) {
							await this.$resources.verifyOTPAndLogin.submit();
						} else {
							await this.login();
						}
					} else if (this.hasForgotPassword) {
						await this.$resources.resetPassword.submit({
							email: this.email,
						});
					}
				},
			};
		},
			signupWithUsername() {
				return {
					url: 'jcloud.api.account.signup_with_username',
					params: {
						username: this.username,
						email: this.email || null,
						phone_number: this.phoneNumber || null,
						password: this.signupPassword,
						referrer: this.getReferrerIfAny(),
						product: this.$route.query.product,
					},
					onSuccess(res) {
						if (res && res.success === false) {
							toast.error(res.message || this.$t('Sign up failed, please check your information'));
							return;
						}
						
						localStorage.setItem('login_email', this.username || this.email);
						
						if (res && res.dashboard_route) {
							window.location.href = res.dashboard_route;
						} else {
							window.location.href = '/dashboard/welcome';
						}
					},
					onError(err) {
						const errorMessage = err?.messages?.length
							? err.messages.join('\n')
							: (err?.message || this.$t('Sign up failed, please check your information'));
						toast.error(errorMessage);
					},
				};
			},
	},
	methods: {
		resetSignupState() {
			if (!this.isLogin && !this.hasForgotPassword && this.otpRequested) {
				this.otpRequested = false;
				this.account_request = '';
				this.otp = '';
			}
		},
		async submitForm() {
			if (this.isLogin) {
				if (this.isOauthLogin) {
					this.$resources.oauthLogin.submit({
						provider: this.socialLoginKey,
					});
				} else if (this.useEmail && this.otpSent) {
					return;
				} else if (!this.useEmail && this.email && this.password) {
					this.checkTwoFactorAndLogin();
				} else if (this.useEmail && !this.otpSent) {
					this.$resources.sendOTP.submit();
				}
			} else if (this.hasForgotPassword) {
				this.checkTwoFactorAndResetPassword();
			} else {
				if (!this.username) {
					toast.error(this.$t('Username cannot be empty'));
					return;
				}
				if (!this.phoneNumber) {
					toast.error(this.$t('Phone number cannot be empty'));
					return;
				}
				if (!this.isPhoneNumberValid) {
					toast.error(this.$t('Please enter a valid phone number format'));
					return;
				}
				if (!this.signupPassword) {
					toast.error(this.$t('Password cannot be empty'));
					return;
				}
				if (this.signupPassword !== this.confirmPassword) {
					toast.error(this.$t('Passwords do not match'));
					return;
				}
				if (!this.isPasswordValid) {
					toast.error(this.$t('Password must be at least 8 characters and contain uppercase and lowercase letters and numbers'));
					return;
				}
				this.$resources.signupWithUsername.submit();
			}
		},

		async checkTwoFactorAndLogin() {
			await this.$resources.is2FAEnabled.submit(
				{ user: this.email },
				{
					onSuccess: async (two_factor_enabled) => {
						if (two_factor_enabled) {
							this.$router.push({
								name: 'Login',
								query: {
									...this.$route.query,
									two_factor: 1,
								},
							});
						} else {
							await this.login();
						}
					},
				},
			);
		},

		async checkTwoFactorAndResetPassword() {
			await this.$resources.is2FAEnabled.submit(
				{ user: this.email },
				{
					onSuccess: async (two_factor_enabled) => {
						if (two_factor_enabled) {
							this.$router.push({
								name: 'Login',
								query: {
									two_factor: 1,
									forgot: 1,
								},
							});
						} else {
							await this.$resources.resetPassword.submit({
								email: this.email,
							});
						}
					},
				},
			);
		},

		verifyOTPAndLogin() {
			this.$resources.is2FAEnabled.submit(
				{ user: this.email },
				{
					onSuccess: async (two_factor_enabled) => {
						if (two_factor_enabled) {
							this.$router.push({
								name: 'Login',
								query: {
									...this.$route.query,
									two_factor: 1,
								},
							});
						} else {
							await this.$resources.verifyOTPAndLogin.submit();
						}
					},
				},
			);
		},
		getReferrerIfAny() {
			const params = location.search;
			const searchParams = new URLSearchParams(params);
			return searchParams.get('referrer');
		},
		async login() {
			await this.$session.login.submit(
				{
					email: this.email,
					password: this.password,
				},
				{
					onSuccess: (res) => {
						// 直接在此处处理重定向，不调用afterLogin
						localStorage.setItem('login_email', this.email || this.username);
						
						// 老用户直接进入主仪表板
						window.location.href = '/dashboard';
					},
					onError: (err) => {
						if (this.$route.name === 'Login' && this.$route.query.two_factor) {
							this.$router.push({
								name: 'Login',
								query: {
									two_factor: undefined,
								},
							});
							this.twoFactorCode = '';
						}
					},
				},
			);
		},
		afterLogin(res) {
			let loginRoute = `/dashboard${res.dashboard_route || '/'}`;
			// if query param redirect is present, redirect to that route
			if (this.$route.query.redirect) {
				loginRoute = this.$route.query.redirect;
			}
			localStorage.setItem('login_email', this.email);
			window.location.href = loginRoute;
		},
		switchToEmailLogin() {
			this.$router.push({
				name: 'Login',
				query: { 
					...this.$route.query, 
					use_email: 1
				}
			});
		},
		switchToPasswordLogin() {
			this.$router.push({
				name: 'Login',
				query: { 
					...this.$route.query, 
					use_email: undefined
				}
			});
		},
		validatePhoneNumber() {
			// 失焦时验证手机号格式
			if (this.phoneNumber && this.phoneNumber.length > 0) {
				this.phoneNumberFormatError = !this.isPhoneNumberValid;
			} else {
				this.phoneNumberFormatError = false;
			}
		},
	},
	computed: {
		error() {
			if (this.$resources.signup.error) {
				return this.$resources.signup.error;
			}

			if (this.$resources.resetPassword.error) {
				return this.$resources.resetPassword.error;
			}
		},
		saasProduct() {
			return this.$resources.signupSettings.data?.product_trial;
		},
		isLogin() {
			return this.$route.name == 'Login' && !this.$route.query.forgot;
		},
		hasForgotPassword() {
			return this.$route.name == 'Login' && this.$route.query.forgot;
		},
		is2FA() {
			return this.$route.name == 'Login' && this.$route.query.two_factor;
		},
		emailDomain() {
			return this.email?.includes('@') ? this.email?.split('@').pop() : '';
		},
		isOauthLogin() {
			return (
				this.oauthEmailDomains.has(this.emailDomain) &&
				this.emailDomain.length > 0
			);
		},
		oauthProviders() {
			const domains = this.$resources.signupSettings.data?.oauth_domains;
			let providers = {};

			if (domains) {
				domains.map(
					(d) =>
						(providers[d.email_domain] = {
							social_login_key: d.social_login_key,
							provider_name: d.provider_name,
						}),
				);
			}

			return providers;
		},
		oauthEmailDomains() {
			return new Set(Object.keys(this.oauthProviders));
		},
		socialLoginKey() {
			return this.oauthProviders[this.emailDomain].social_login_key;
		},
		oauthProviderName() {
			return this.oauthProviders[this.emailDomain].provider_name;
		},
		title() {
			if (this.hasForgotPassword) {
				return this.$t('Reset Password');
			} else if (this.isLogin) {
				if (this.saasProduct) {
					return this.$t('Log in to your account to start using {product}', { product: this.saasProduct.title });
				}
				return this.$t('Log in to your account');
			} else {
				if (this.saasProduct) {
					return this.$t('Sign up to create your {product} site', { product: this.saasProduct.title });
				}
				return this.$t('Create New Account');
			}
		},
		useEmail() {
			// 默认使用密码登录，只有当明确指定use_email时才使用邮箱验证码
			return Boolean(this.$route.query.use_email);
		},
		passwordMismatch() {
			return this.signupPassword !== this.confirmPassword && this.confirmPassword;
		},
		passwordStrength() {
			if (!this.signupPassword) return 0;
			
			let strength = 0;
			
			// 密码长度
			if (this.signupPassword.length >= 8) strength += 25;
			
			// 包含小写字母
			if (/[a-z]/.test(this.signupPassword)) strength += 25;
			
			// 包含大写字母
			if (/[A-Z]/.test(this.signupPassword)) strength += 25;
			
			// 包含数字
			if (/[0-9]/.test(this.signupPassword)) strength += 25;
			
			return strength;
		},
		passwordStrengthClass() {
			if (this.passwordStrength < 40) return 'bg-red-500';
			if (this.passwordStrength < 60) return 'bg-yellow-500';
			if (this.passwordStrength < 80) return 'bg-blue-500';
			return 'bg-green-500';
		},
		passwordStrengthText() {
			if (this.passwordStrength < 40) return this.$t('Weak');
			if (this.passwordStrength < 60) return this.$t('Fair');
			if (this.passwordStrength < 80) return this.$t('Strong');
			return this.$t('Very Strong');
		},
		passwordStrengthTextClass() {
			if (this.passwordStrength < 40) return 'text-red-500';
			if (this.passwordStrength < 60) return 'text-yellow-500';
			if (this.passwordStrength < 80) return 'text-blue-500';
			return 'text-green-500';
		},
		isPasswordValid() {
			return this.signupPassword && 
				   this.signupPassword.length >= 8 && 
				   /[a-z]/.test(this.signupPassword) && 
				   /[A-Z]/.test(this.signupPassword) && 
				   /[0-9]/.test(this.signupPassword);
		},
		isPhoneNumberValid() {
			const phoneRegex = /^1[3-9]\d{9}$/;
			return phoneRegex.test(this.phoneNumber);
		},
	},
};
</script>