<template>
	<div class="login-shell">
		<transition name="sso-overlay">
			<div v-if="ssoSuccess.active" class="sso-overlay" role="status" aria-live="polite">
				<div class="sso-overlay__card" :class="'sso-overlay__card--' + ssoSuccess.phase">
					<div class="sso-overlay__icon" aria-hidden="true">
						<div v-if="ssoSuccess.phase === 'loading'" class="sso-overlay__spinner"></div>
						<svg v-else class="sso-overlay__check" viewBox="0 0 24 24" focusable="false">
							<path
								d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm-1.35 13.15-3.4-3.35a1 1 0 1 1 1.4-1.42l2.68 2.64 5.28-5.22a1 1 0 0 1 1.4 1.42l-6 5.93a1 1 0 0 1-1.36 0Z" />
						</svg>
					</div>
					<p class="sso-overlay__title">{{ ssoSuccess.title }}</p>
					<p class="sso-overlay__message">{{ ssoSuccess.message }}</p>
					<div v-if="ssoSuccess.phase === 'loading'" class="sso-overlay__progress">
						<div class="sso-overlay__progress-bar" :style="{ animationDuration: SSO_LOADING_MS + 'ms' }">
						</div>
					</div>
				</div>
			</div>
		</transition>

		<div class="login-card"
			:class="{ 'login-card--shake': ssoAlert.shake, 'login-card--dimmed': ssoSuccess.active }">
			<div class="login-header">
				<img class="login-logo" src="/images/MyKoPKB-logo.png" alt="MyKoPKB" />
				<h1 class="login-title">Selamat Datang</h1>
				<p class="login-subtitle">Log masuk untuk meneruskan ke Portal MyKoPKB</p>
			</div>

			<transition name="sso-alert">
				<div v-if="ssoAlert.visible" class="sso-alert" :class="'sso-alert--' + ssoAlert.code" role="alert"
					aria-live="assertive">
					<div class="sso-alert__icon" aria-hidden="true">
						<svg v-if="ssoAlert.code === 'voter_not_found'" viewBox="0 0 24 24" focusable="false">
							<path
								d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm0 5a1.25 1.25 0 1 1 0 2.5A1.25 1.25 0 0 1 12 7Zm-1 4.25a1 1 0 0 1 2 0V16a1 1 0 1 1-2 0v-4.75Z" />
						</svg>
						<svg v-else viewBox="0 0 24 24" focusable="false">
							<path
								d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm-.75 5.5a.75.75 0 0 1 1.5 0v6a.75.75 0 0 1-1.5 0v-6Zm.75 9.25a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z" />
						</svg>
					</div>
					<div class="sso-alert__body">
						<p class="sso-alert__title">{{ ssoAlert.title }}</p>
						<p class="sso-alert__message">{{ ssoAlert.message }}</p>
					</div>
					<button type="button" class="sso-alert__close" aria-label="Tutup" @click="dismissSsoAlert">
						&times;
					</button>
				</div>
			</transition>

			<!-- Local / development: OTP login via IC number -->
			<form v-if="isLocalDev" @submit.prevent="login" id="login_form" class="login-form" novalidate>
				<div class="form-group mb-3">
					<label class="login-label" for="no_kp">No. Kad Pengenalan</label>
					<div class="login-field">
						<span class="login-field-icon" aria-hidden="true">
							<svg viewBox="0 0 24 24" focusable="false">
								<path
									d="M4 7.5A3.5 3.5 0 0 1 7.5 4h9A3.5 3.5 0 0 1 20 7.5v9A3.5 3.5 0 0 1 16.5 20h-9A3.5 3.5 0 0 1 4 16.5v-9Zm3.5-1.5A1.5 1.5 0 0 0 6 7.5v9A1.5 1.5 0 0 0 7.5 18h9a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 16.5 6h-9Zm1.5 3h6v2H9V9Zm0 4h10v2H9v-2Z" />
							</svg>
						</span>
						<input v-model.trim="no_kp" @input="onNoKpInput" :disabled="loading" type="text" id="no_kp"
							name="no_kp" class="form-control login-input" placeholder="Contoh: 901010101010"
							autocomplete="off" inputmode="numeric" enterkeyhint="go" required />
					</div>
					<small class="login-help">Masukkan tanpa dash (-) atau jarak.</small>
				</div>

				<button type="submit" class="btn login-btn" :disabled="loading || !no_kp">
					<span v-if="loading" class="spinner-border spinner-border-sm mr-2" role="status"
						aria-hidden="true"></span>
					<span>{{ loading ? 'Sedang log masuk…' : 'Masuk' }}</span>
				</button>
			</form>

			<!-- Production: SSO only -->
			<div v-else class="sso-only-notice">
				<div class="sso-only-notice__icon" aria-hidden="true">
					<svg viewBox="0 0 24 24" focusable="false">
						<path
							d="M12 2a5 5 0 0 0-5 5v2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2h-1V7a5 5 0 0 0-5-5Zm-3 7V7a3 3 0 1 1 6 0v2H9Zm3 4a1.5 1.5 0 0 1 .75 2.8V18h-1.5v-2.2A1.5 1.5 0 0 1 12 13Z" />
					</svg>
				</div>
				<div>
					<p class="sso-only-notice__title">
						Sila log masuk melalui
						<a href="https://mykopkb.koppkb.com" class="sso-only-notice__link" target="_blank"
							rel="noopener noreferrer">MyKoPKB</a>.
					</p>
				</div>
			</div>
		</div>
	</div>
</template>

<script>
const SSO_LOADING_MS = 2500;
const SSO_SUCCESS_MS = 2500;
const LOCAL_ENVS = ['local', 'development'];

export default {
	data() {
		return {
			SSO_LOADING_MS,
			SSO_SUCCESS_MS,
			loading: false,
			no_kp: '',
			ssoAlert: {
				visible: false,
				title: '',
				message: '',
				code: 'sso_error',
				shake: false
			},
			ssoSuccess: {
				active: false,
				phase: 'loading',
				title: 'Mengesahkan log masuk SSO',
				message: 'Sila tunggu sebentar…'
			},
			ssoRedirectTimer: null
		};
	},

	computed: {
		isLocalDev() {
			const env = (window.config && window.config.env) || '';
			return LOCAL_ENVS.indexOf(String(env).toLowerCase()) !== -1;
		}
	},

	beforeDestroy() {
		if (this.ssoRedirectTimer) {
			window.clearTimeout(this.ssoRedirectTimer);
		}
	},

	created() {
		if (this.util.isAdminPortalSession()) {
			this.$router.replace(this.util.getAdminEntryRoute());
			return;
		}

		this.handleSsoCallback();
	},

	methods: {
		onNoKpInput() {
			this.no_kp = (this.no_kp || '').replace(/[\s-]+/g, '').replace(/[^\d]/g, '');
		},
		login() {
			if (!this.isLocalDev) {
				return;
			}

			this.startLoading();
			const noKp = (this.no_kp || '').trim();
			axios
				.post(config.API + 'voter/login', {
					no_kp: noKp,
					send_otp: false
				})
				.then(response => {
					this.stopLoading();
					if (this.util.showResult(response, 'success')) {
						this.$router.push({
							name: 'Voter Verify',
							params: {
								nokp: response.data.nokp,
								notel: response.data.notel,
								debug_otp: response.data.debug_otp || null
							}
						});
					}
				})
				.catch(error => {
					this.stopLoading();
					this.util.showResult(error, 'error');
				});
		},
		startLoading() {
			this.loading = true;
		},
		stopLoading() {
			this.loading = false;
		},
		handleSsoCallback() {
			const params = new URLSearchParams(window.location.search);
			const ssoError = params.get('sso_error');

			if (ssoError) {
				const code = params.get('sso_error_code') || 'sso_error';
				this.showSsoError(ssoError, code);
				this.clearSsoQueryParams();
				return;
			}

			const ssoToken = params.get('sso_token');
			const tokenExpiresAt = params.get('token_expires_at');

			if (!ssoToken) {
				return;
			}

			this.clearSsoQueryParams();
			this.completeSsoLogin(ssoToken, tokenExpiresAt);
		},
		completeSsoLogin(ssoToken, tokenExpiresAt) {
			this.ssoSuccess = {
				active: true,
				phase: 'loading',
				title: 'Mengesahkan log masuk SSO',
				message: 'Sila tunggu sebentar…'
			};

			window.setTimeout(() => {
				this.util.persistLoginSession(ssoToken, tokenExpiresAt, {
					clearAdminSession: true
				});

				this.ssoSuccess = {
					active: true,
					phase: 'success',
					title: 'Log masuk berjaya',
					message: 'Anda akan dialihkan ke portal…'
				};

				this.util.notify('Log masuk SSO berjaya.', 'success');

				this.ssoRedirectTimer = window.setTimeout(() => {
					this.$router.replace({ name: 'Voter Home' });
				}, SSO_SUCCESS_MS);
			}, SSO_LOADING_MS);
		},
		clearSsoQueryParams() {
			if (!window.location.search) {
				return;
			}

			window.history.replaceState({}, document.title, window.location.pathname);
		},
		showSsoError(message, code) {
			const titles = {
				voter_not_found: 'Akaun pengundi tidak dijumpai',
				token_invalid: 'Log masuk SSO gagal',
				token_used: 'Token SSO telah digunakan',
				sso_error: 'Log masuk SSO gagal'
			};

			this.ssoAlert = {
				visible: true,
				title: titles[code] || titles.sso_error,
				message: message,
				code: code,
				shake: true
			};

			this.util.notify(message, 'error');

			window.setTimeout(() => {
				this.ssoAlert.shake = false;
			}, 650);
		},
		dismissSsoAlert() {
			this.ssoAlert.visible = false;
			this.ssoAlert.shake = false;
		}
	}
};
</script>

<style scoped>
.login-shell {
	min-height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 32px 16px;
	background: #f6f7fb;
}

.login-card {
	width: 100%;
	max-width: 420px;
	background: #ffffff;
	border: 1px solid rgba(15, 23, 42, 0.08);
	border-radius: 20px;
	box-shadow:
		0 18px 55px rgba(2, 6, 23, 0.12),
		0 2px 10px rgba(2, 6, 23, 0.06);
	padding: 28px 24px;
	position: relative;
	overflow: hidden;
}

.login-card::before {
	content: '';
	position: absolute;
	inset: 0 0 auto 0;
	height: 4px;
	background: linear-gradient(90deg, #22c55e 0%, #3b82f6 55%, #a855f7 100%);
}

.login-header {
	text-align: center;
	margin-bottom: 16px;
	padding-top: 6px;
}

.login-logo {
	display: block;
	margin: 0 auto 10px;
	max-width: 240px;
	height: auto;
}

.login-title {
	margin: 0;
	font-size: 22px;
	font-weight: 900;
	letter-spacing: -0.02em;
	color: #0f172a;
}

.login-subtitle {
	margin: 6px 0 0;
	font-size: 14px;
	color: rgba(15, 23, 42, 0.72);
	line-height: 1.4;
}

.sso-only-notice {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	margin-top: 18px;
	padding: 16px;
	border: 1px solid rgba(37, 99, 235, 0.16);
	border-radius: 14px;
	background: linear-gradient(180deg, #eff6ff 0%, #dbeafe 100%);
	color: #1e3a8a;
}

.sso-only-notice__icon {
	flex: 0 0 24px;
	width: 24px;
	height: 24px;
}

.sso-only-notice__icon svg {
	display: block;
	width: 24px;
	height: 24px;
	fill: currentColor;
}

.sso-only-notice__title {
	margin: 0 0 4px;
	font-size: 14px;
	font-weight: 800;
}

.sso-only-notice__link {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
	transition: opacity 160ms ease;
}

.sso-only-notice__link:hover,
.sso-only-notice__link:focus {
	opacity: 0.8;
}

.sso-only-notice__message {
	margin: 0;
	font-size: 13px;
	line-height: 1.5;
	opacity: 0.9;
}

.sso-alert-enter-active,
.sso-alert-leave-active {
	transition: opacity 280ms ease, transform 280ms ease, max-height 280ms ease;
	overflow: hidden;
}

.sso-alert-enter,
.sso-alert-leave-to {
	opacity: 0;
	transform: translateY(-10px);
	max-height: 0;
}

.sso-alert-enter-to,
.sso-alert-leave {
	max-height: 160px;
}

.sso-alert {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	margin: 0 0 16px;
	padding: 14px 14px 14px 16px;
	border-radius: 14px;
	border: 1px solid transparent;
	position: relative;
	animation: sso-alert-pulse 2.4s ease-in-out 1;
}

.sso-alert--voter_not_found {
	background: linear-gradient(180deg, #fff7ed 0%, #ffedd5 100%);
	border-color: rgba(234, 88, 12, 0.22);
	color: #9a3412;
	animation-name: sso-alert-pulse-warn;
}

.sso-alert--token_invalid,
.sso-alert--token_used,
.sso-alert--sso_error {
	background: linear-gradient(180deg, #fef2f2 0%, #fee2e2 100%);
	border-color: rgba(220, 38, 38, 0.2);
	color: #991b1b;
}

.sso-alert__icon {
	flex: 0 0 22px;
	width: 22px;
	height: 22px;
	margin-top: 1px;
	animation: sso-icon-pop 420ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

.sso-alert__icon svg {
	width: 22px;
	height: 22px;
	fill: currentColor;
	display: block;
}

.sso-alert__body {
	flex: 1;
	min-width: 0;
}

.sso-alert__title {
	margin: 0 0 4px;
	font-size: 14px;
	font-weight: 800;
	line-height: 1.35;
}

.sso-alert__message {
	margin: 0;
	font-size: 13px;
	line-height: 1.45;
	opacity: 0.92;
}

.sso-alert__close {
	flex: 0 0 auto;
	border: 0;
	background: transparent;
	color: inherit;
	font-size: 22px;
	line-height: 1;
	padding: 0 0 0 8px;
	cursor: pointer;
	opacity: 0.65;
	transition: opacity 160ms ease, transform 160ms ease;
}

.sso-alert__close:hover {
	opacity: 1;
	transform: scale(1.08);
}

.login-card--shake {
	animation: login-card-shake 560ms cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

.login-card--dimmed {
	opacity: 0.35;
	filter: blur(1px);
	transform: scale(0.985);
	transition: opacity 320ms ease, filter 320ms ease, transform 320ms ease;
	pointer-events: none;
}

.sso-overlay-enter-active,
.sso-overlay-leave-active {
	transition: opacity 280ms ease;
}

.sso-overlay-enter,
.sso-overlay-leave-to {
	opacity: 0;
}

.sso-overlay {
	position: fixed;
	inset: 0;
	z-index: 1200;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px 16px;
	background: rgba(15, 23, 42, 0.42);
	backdrop-filter: blur(4px);
}

.sso-overlay__card {
	width: 100%;
	max-width: 360px;
	background: #ffffff;
	border-radius: 20px;
	padding: 28px 24px 24px;
	text-align: center;
	box-shadow:
		0 24px 60px rgba(2, 6, 23, 0.22),
		0 4px 14px rgba(2, 6, 23, 0.08);
	animation: sso-overlay-rise 420ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.sso-overlay__card--success {
	animation: sso-overlay-rise 420ms cubic-bezier(0.22, 1, 0.36, 1) both,
		sso-overlay-success-pop 360ms ease 80ms both;
}

.sso-overlay__icon {
	width: 64px;
	height: 64px;
	margin: 0 auto 14px;
	display: flex;
	align-items: center;
	justify-content: center;
}

.sso-overlay__spinner {
	width: 52px;
	height: 52px;
	border-radius: 50%;
	border: 4px solid rgba(37, 99, 235, 0.16);
	border-top-color: #2563eb;
	animation: sso-spinner 760ms linear infinite;
}

.sso-overlay__check {
	width: 64px;
	height: 64px;
	fill: #16a34a;
	animation: sso-check-pop 520ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

.sso-overlay__title {
	margin: 0;
	font-size: 20px;
	font-weight: 900;
	color: #0f172a;
	letter-spacing: -0.02em;
}

.sso-overlay__message {
	margin: 8px 0 0;
	font-size: 14px;
	line-height: 1.45;
	color: rgba(15, 23, 42, 0.72);
}

.sso-overlay__progress {
	margin-top: 18px;
	height: 4px;
	border-radius: 999px;
	background: rgba(37, 99, 235, 0.12);
	overflow: hidden;
}

.sso-overlay__progress-bar {
	height: 100%;
	border-radius: inherit;
	background: linear-gradient(90deg, #2563eb 0%, #3b82f6 100%);
	animation: sso-progress ease-in-out forwards;
}

@keyframes sso-overlay-rise {
	from {
		opacity: 0;
		transform: translateY(18px) scale(0.96);
	}

	to {
		opacity: 1;
		transform: translateY(0) scale(1);
	}
}

@keyframes sso-overlay-success-pop {
	from {
		box-shadow: 0 24px 60px rgba(2, 6, 23, 0.22);
	}

	to {
		box-shadow: 0 24px 60px rgba(22, 163, 74, 0.18);
	}
}

@keyframes sso-spinner {
	to {
		transform: rotate(360deg);
	}
}

@keyframes sso-check-pop {
	0% {
		transform: scale(0.35);
		opacity: 0;
	}

	100% {
		transform: scale(1);
		opacity: 1;
	}
}

@keyframes sso-progress {
	from {
		width: 8%;
	}

	to {
		width: 100%;
	}
}

@keyframes login-card-shake {

	0%,
	100% {
		transform: translateX(0);
	}

	15% {
		transform: translateX(-8px);
	}

	30% {
		transform: translateX(7px);
	}

	45% {
		transform: translateX(-5px);
	}

	60% {
		transform: translateX(4px);
	}

	75% {
		transform: translateX(-2px);
	}
}

@keyframes sso-alert-pulse {

	0%,
	100% {
		box-shadow: 0 0 0 0 rgba(220, 38, 38, 0);
	}

	35% {
		box-shadow: 0 0 0 6px rgba(220, 38, 38, 0.08);
	}
}

@keyframes sso-alert-pulse-warn {

	0%,
	100% {
		box-shadow: 0 0 0 0 rgba(234, 88, 12, 0);
	}

	35% {
		box-shadow: 0 0 0 6px rgba(234, 88, 12, 0.1);
	}
}

@keyframes sso-icon-pop {
	0% {
		transform: scale(0.4);
		opacity: 0;
	}

	100% {
		transform: scale(1);
		opacity: 1;
	}
}

.login-form {
	margin-top: 14px;
}

.login-label {
	font-weight: 700;
	font-size: 13px;
	color: rgba(15, 23, 42, 0.85);
	margin-bottom: 6px;
}

.login-field {
	position: relative;
}

.login-field-icon {
	position: absolute;
	left: 12px;
	top: 50%;
	transform: translateY(-50%);
	width: 18px;
	height: 18px;
	color: rgba(15, 23, 42, 0.55);
	pointer-events: none;
}

.login-field-icon svg {
	width: 18px;
	height: 18px;
	fill: currentColor;
	display: block;
}

.login-input {
	border-radius: 14px;
	padding: 12px 14px 12px 42px;
	font-size: 16px;
	border: 1px solid rgba(15, 23, 42, 0.14);
	transition: box-shadow 160ms ease, border-color 160ms ease, transform 160ms ease;
}

.login-input:focus {
	border-color: rgba(59, 130, 246, 0.55);
	box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.14);
}

.login-help {
	display: block;
	margin-top: 8px;
	color: rgba(15, 23, 42, 0.6);
}

.login-btn {
	width: 100%;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 14px;
	padding: 13px 14px;
	font-weight: 900;
	letter-spacing: 0.01em;
	color: #ffffff;
	background: linear-gradient(180deg, #2563eb 0%, #1d4ed8 100%);
	border: 0;
	box-shadow: 0 12px 24px rgba(29, 78, 216, 0.22);
	transition: transform 160ms ease, box-shadow 160ms ease, filter 160ms ease;
}

.login-btn:hover {
	filter: brightness(1.03);
	transform: translateY(-1px);
	box-shadow: 0 16px 34px rgba(29, 78, 216, 0.26);
}

.login-btn:disabled {
	opacity: 0.72;
	filter: saturate(0.9);
	transform: none;
	box-shadow: none;
	cursor: not-allowed;
}

@media (max-width: 576px) {
	.login-shell {
		align-items: center;
		padding: 20px 14px;
	}

	.login-card {
		max-width: none;
		border-radius: 20px;
		padding: 22px 18px 18px;
	}

	.login-logo {
		max-width: 200px;
	}
}
</style>
