import { session, user } from "$lib/global.stores";
import { authClient } from "$lib/auth.client";
import {
    startVerificationSessionSC,
    verifySessionCodeSC,
} from "$lib/domains/security/twofa.remote";
import { toast } from "svelte-sonner";
import { get } from "svelte/store";
import { page } from "$app/state";

class TwoFactorVerifyViewModel {
    verifying = $state(false);
    verificationCode = $state("");
    verificationToken = $state<string | null>(null);
    errorMessage = $state<string | null>(null);
    startingVerification = $state(false);

    async startVerification() {
        this.startingVerification = true;
        this.errorMessage = null;

        const currentUser = get(user);
        const currentSession = get(session);

        const uid = currentUser?.id;
        const sid = currentSession?.id;

        if (!uid || !sid) {
            this.errorMessage = "No active session found";
            toast.error("Failed to start verification", {
                description: this.errorMessage,
            });
            this.startingVerification = false;
            return;
        }

        try {
            const result = await startVerificationSessionSC({
                userId: uid,
                sessionId: sid,
            });

            if (result?.error || !result?.data?.verificationToken) {
                this.errorMessage =
                    result?.error?.message || "Failed to start verification";
                toast.error("Failed to start verification", {
                    description: this.errorMessage,
                });
                return;
            }

            this.verificationToken = result.data.verificationToken;
        } catch (error) {
            this.errorMessage = "Failed to start verification";
            toast.error("Failed to start verification", {
                description:
                    error instanceof Error
                        ? error.message
                        : "Failed to start verification",
            });
        } finally {
            this.startingVerification = false;
        }
    }

    async verifyCode() {
        if (!this.verificationToken) {
            this.errorMessage = "No verification session found";
            return;
        }

        if (!this.verificationCode || this.verificationCode.length !== 6) {
            this.errorMessage = "Please enter a valid 6-digit code";
            return;
        }

        this.verifying = true;
        this.errorMessage = null;

        try {
            const result = await verifySessionCodeSC({
                verificationToken: this.verificationToken,
                code: this.verificationCode,
            });

            if (result?.error || !result?.data?.success) {
                this.errorMessage =
                    result?.error?.message || "Failed to verify code";

                if (result?.error?.code === "BANNED") {
                    await authClient.signOut();
                    window.location.href = "/auth/login";
                    return;
                }

                if (
                    this.errorMessage &&
                    !this.errorMessage.includes("Invalid") &&
                    !this.errorMessage.includes("already been used")
                ) {
                    toast.error("Verification failed", {
                        description: this.errorMessage,
                    });
                }
                return;
            }

            const redirectUrl = page.url.searchParams.get("redirect") || "/";
            window.location.href = redirectUrl;
        } catch (error) {
            this.errorMessage = "Failed to verify code";
            toast.error("Verification failed", {
                description:
                    error instanceof Error ? error.message : this.errorMessage,
            });
        } finally {
            this.verifying = false;
        }
    }

    async handleBackupCode() {
        if (!this.verificationToken || !this.verificationCode) {
            this.errorMessage = "Please enter a valid backup code";
            return;
        }

        this.verifying = true;
        this.errorMessage = null;

        try {
            const result = await verifySessionCodeSC({
                verificationToken: this.verificationToken,
                code: this.verificationCode,
            });

            if (result?.error || !result?.data?.success) {
                this.errorMessage = result?.error?.message || "Invalid backup code";
                return;
            }

            const redirectUrl = page.url.searchParams.get("redirect") || "/";
            window.location.href = redirectUrl;
        } catch (error) {
            this.errorMessage =
                error instanceof Error ? error.message : "Invalid backup code";
        } finally {
            this.verifying = false;
        }
    }

    reset() {
        this.verifying = false;
        this.verificationCode = "";
        this.verificationToken = null;
        this.errorMessage = null;
        this.startingVerification = false;
    }
}

export const twoFactorVerifyVM = new TwoFactorVerifyViewModel();
