<script lang="ts">
	import ButtonText from "$lib/components/atoms/button-text.svelte";
	import Icon from "$lib/components/atoms/icon.svelte";
	import * as AlertDialog from "$lib/components/ui/alert-dialog/index.js";
	import { Button, buttonVariants } from "$lib/components/ui/button";
	import * as Card from "$lib/components/ui/card";
	import * as InputOTP from "$lib/components/ui/input-otp";
	import { twofactorVM } from "$lib/domains/security/2fa.vm.svelte";
	import {
	    CheckCircle,
	    Copy,
	    Download,
	    Loader2,
	    ShieldAlert,
	    ShieldCheck,
	} from "@lucide/svelte";
	import { toast } from "svelte-sonner";

	$inspect(twofactorVM.twoFactorSetupInProgress);
	$inspect(twofactorVM.twoFactorEnabled);
</script>

<Card.Root>
	<Card.Header>
		<div class="flex items-center gap-2">
			<Icon icon={ShieldCheck} cls="h-5 w-5 text-primary" />
			<Card.Title>Two-Factor Authentication</Card.Title>
		</div>
		<Card.Description>
			Add an extra layer of security to your account by enabling two-factor
			authentication.
		</Card.Description>
	</Card.Header>
	<Card.Content>
		{#if twofactorVM.twoFactorSetupInProgress}
			<div class="space-y-6">
				<div class="bg-muted/50 rounded-lg border p-4">
					<h4 class="mb-2 font-medium">Setup Instructions</h4>
					<ol class="list-decimal space-y-2 pl-5 text-sm">
						<li>
							Install an authenticator app like Google Authenticator
							or 2FAS on your mobile device.
						</li>
						<li>
							Scan the QR code below or manually enter the secret
							key into your app.
						</li>
						<li>
							Enter the verification code displayed in your
							authenticator app below.
						</li>
					</ol>
				</div>

				<div class="flex flex-col items-center gap-4">
					{#if twofactorVM.qrCodeUrl && twofactorVM.qrCodeUrl.length > 0}
						<div class="flex flex-col items-center gap-4">
							{#if twofactorVM.qrCodeUrl}
								<div class="rounded-lg border bg-white p-2">
									<img
										src={twofactorVM.qrCodeUrl}
										alt="QR Code for Two-Factor Authentication"
										class="h-48 w-48"
									/>
								</div>
								<Button
									variant="outline"
									size="sm"
									onclick={() => {
										twofactorVM.copyToClipboard(
											twofactorVM.twoFactorSecret || "",
										);
										toast.success(
											"Secret copied to clipboard",
										);
									}}
								>
									<Icon icon={Copy} cls="mr-2 h-4 w-4" />
									Copy secret for manual entry
								</Button>
							{:else}
								<div class="flex justify-center py-6">
									<Icon
										icon={Loader2}
										cls="h-8 w-8 animate-spin text-muted-foreground"
									/>
								</div>
							{/if}
						</div>
					{:else}
						<div class="flex justify-center py-6">
							<Icon
								icon={Loader2}
								cls="h-8 w-8 animate-spin text-muted-foreground"
							/>
						</div>
					{/if}
				</div>

				<div class="space-y-4">
					<div class="flex justify-center">
						<InputOTP.Root
							maxlength={6}
							bind:value={twofactorVM.twoFactorVerificationCode}
						>
							{#snippet children({ cells })}
								<InputOTP.Group>
									{#each cells.slice(0, 3) as cell (cell)}
										<InputOTP.Slot {cell} />
									{/each}
								</InputOTP.Group>
								<InputOTP.Separator />
								<InputOTP.Group>
									{#each cells.slice(3, 6) as cell (cell)}
										<InputOTP.Slot {cell} />
									{/each}
								</InputOTP.Group>
							{/snippet}
						</InputOTP.Root>
					</div>
					<p class="text-muted-foreground text-center text-sm">
						Enter the 6-digit code from your authenticator app
					</p>
				</div>

				<div class="flex w-32 gap-2">
					<Button
						onclick={() => twofactorVM.completeTwoFactorSetup()}
						disabled={!twofactorVM.twoFactorVerificationCode ||
							twofactorVM.twoFactorVerificationCode.length !== 6 ||
							twofactorVM.isLoading}
					>
						{#if twofactorVM.isLoading}
							<Icon
								icon={Loader2}
								cls="mr-2 h-4 w-4 animate-spin"
							/>
						{/if}
						Verify and Enable
					</Button>
					<Button
						variant="outline"
						onclick={() => twofactorVM.cancelSetup()}
					>
						Cancel
					</Button>
				</div>
			</div>
		{:else if !twofactorVM.twoFactorEnabled && !twofactorVM.twoFactorSetupInProgress}
			<div class="flex flex-col gap-4">
				<div
					class="flex flex-col items-center justify-between gap-4 sm:flex-row"
				>
					<div
						class="flex flex-col gap-2 text-amber-700 sm:flex-row sm:items-center dark:text-amber-400"
					>
						<Icon icon={ShieldAlert} cls="h-4 w-4" />
						<span class="text-sm">
							Two-factor authentication is currently disabled.
						</span>
					</div>
					<Button
						variant="outline"
						class="w-full sm:w-max"
						onclick={() => twofactorVM.startTwoFactorSetup()}
						disabled={twofactorVM.isLoading}
					>
						{#if twofactorVM.isLoading}
							<Icon
								icon={Loader2}
								cls="mr-2 h-4 w-4 animate-spin"
							/>
						{/if}
						Enable 2FA
					</Button>
				</div>
			</div>
		{:else if twofactorVM.twoFactorEnabled}
			<div class="space-y-6">
				{#if !twofactorVM.showingBackupCodes}
					<div class="flex items-center justify-between">
						<div
							class="flex items-center gap-2 text-emerald-600 dark:text-emerald-400"
						>
							<Icon icon={ShieldCheck} cls="h-4 w-4" />
							<span>Two-factor authentication is enabled.</span>
						</div>

						<div class="flex gap-2">
							<Button
								variant="outline"
								size="sm"
								onclick={() =>
									twofactorVM.generateNewBackupCodes()}
								disabled={twofactorVM.isLoading}
							>
								{#if twofactorVM.isLoading}
									<Icon
										icon={Loader2}
										cls="mr-2 h-3 w-3 animate-spin"
									/>
								{:else}
									Regenerate Recovery Codes
								{/if}
							</Button>

							<AlertDialog.Root>
								<AlertDialog.Trigger
									class={buttonVariants({
										variant: "destructive",
										size: "sm",
									})}
									disabled={twofactorVM.isLoading}
								>
									<ButtonText
										loading={twofactorVM.isLoading}
										text="Disable 2FA"
										loadingText="Disabling..."
									/>
								</AlertDialog.Trigger>
								<AlertDialog.Content>
									<AlertDialog.Header>
										<AlertDialog.Title
											>Disable Two-Factor Authentication?</AlertDialog.Title
										>
										<AlertDialog.Description>
											This will remove the extra layer of
											security from your account. You will
											no longer need your authenticator app
											to sign in, and all backup codes will
											be invalidated. You can re-enable 2FA
											at any time.
										</AlertDialog.Description>
									</AlertDialog.Header>
									<AlertDialog.Footer>
										<AlertDialog.Cancel
											>Cancel</AlertDialog.Cancel
										>
										<AlertDialog.Action
											onclick={() =>
												twofactorVM.disableTwoFactor()}
										>
											Disable 2FA
										</AlertDialog.Action>
									</AlertDialog.Footer>
								</AlertDialog.Content>
							</AlertDialog.Root>
						</div>
					</div>
				{/if}

				{#if twofactorVM.showingBackupCodes && twofactorVM.backupCodes.length > 0}
					<div class="space-y-4">
						<div class="flex items-center justify-between">
							<h4 class="text-sm font-medium">Recovery Codes</h4>
							<div class="flex gap-2">
								<Button
									variant="outline"
									size="sm"
									onclick={() =>
										twofactorVM.copyAllBackupCodes()}
								>
									<Icon icon={Copy} cls="mr-2 h-3 w-3" />
									Copy All
								</Button>
								<Button
									variant="outline"
									size="sm"
									onclick={() =>
										twofactorVM.downloadBackupCodes()}
								>
									<Icon icon={Download} cls="mr-2 h-3 w-3" />
									Download
								</Button>
							</div>
						</div>

						<div class="bg-muted/50 rounded-lg border p-4">
							<div class="grid grid-cols-2 gap-2">
								{#each twofactorVM.backupCodes as code}
									<div
										class="bg-background flex items-center justify-between rounded border px-3 py-2 font-mono text-sm"
									>
										<span>{code}</span>
									</div>
								{/each}
							</div>
							<div class="mt-4 space-y-3">
								<p class="text-muted-foreground text-xs">
									<Icon
										icon={ShieldCheck}
										cls="mr-1 h-3 w-3 inline-block"
									/>
									Keep these codes in a safe place. Each code can
									only be used once to access your account if you
									lose your phone.
								</p>
								<div
									class="rounded-md border border-amber-200 bg-amber-50 p-3 dark:border-amber-800 dark:bg-amber-950/20"
								>
									<p
										class="text-xs font-medium text-amber-800 dark:text-amber-200"
									>
										⚠️ Important: Save these codes before
										continuing. You won't be able to see them
										again.
									</p>
								</div>
							</div>
						</div>

						<Button
							onclick={() => twofactorVM.confirmBackupCodesSaved()}
							class="w-full"
						>
							<Icon icon={CheckCircle} cls="mr-2 h-4 w-4" />
							I've saved these codes securely
						</Button>
					</div>
				{/if}
			</div>
		{/if}
	</Card.Content>
</Card.Root>
