import React, { useEffect, useRef, useState } from "react";
import { Pressable, View } from "react-native";
import { useNavigation } from "../../context/NavigationContext";
import { Ionicons } from "@expo/vector-icons";
import { useColorScheme } from "nativewind";
import * as Haptics from "expo-haptics";
import { copyToClipboard as sharedCopy } from "../../utils/clipboard";
import QRCode from "react-native-qrcode-svg";
import Toast from "react-native-toast-message";
import { MonoText, MutedText } from "../../components/text";
import { Button } from "../../components/button";
import { withClickTracking } from "../../services/telemetry";
import { Input } from "../../components/input";
import { Separator } from "../../components/separator";
import AuthService from "../../services/auth.service";
import { useAuth } from "../../hooks/useAuth";
import { useAppConfig } from "../../context/AppConfigContext";
import { getErrorMessage } from "../../utils/error";
import { AuthPage } from "./AuthPage";
export function MfaEnrollScreen({ authenticatorAppPromo, layout } = {}) {
    const { refreshUser } = useAuth();
    const { colorScheme } = useColorScheme();
    const isDark = colorScheme === "dark";
    const router = useNavigation();
    const { appName, routes } = useAppConfig();
    const [step, setStep] = useState("prompt");
    const [setupData, setSetupData] = useState(null);
    const [code, setCode] = useState("");
    const [error, setError] = useState("");
    const [isLoading, setIsLoading] = useState(false);
    const [copied, setCopied] = useState(null);
    const copiedResetTimerRef = useRef(undefined);
    useEffect(() => () => {
        if (copiedResetTimerRef.current) {
            clearTimeout(copiedResetTimerRef.current);
        }
    }, []);
    // The shared `copyToClipboard` writes the value AND schedules the
    // 30s auto-wipe at module scope, so unmounting this screen no
    // longer cancels the wipe (the previous component-scoped timer
    // was the exact footgun the shared helper exists to avoid).
    const copyToClipboard = async (text, label) => {
        const ok = await sharedCopy(text);
        if (!ok) {
            return;
        }
        setCopied(label);
        Toast.show({ type: "success", text1: `${label} copied`, visibilityTime: 1500 });
        if (copiedResetTimerRef.current) {
            clearTimeout(copiedResetTimerRef.current);
        }
        copiedResetTimerRef.current = setTimeout(() => {
            setCopied(null);
        }, 30_000);
    };
    const handleStartSetup = async () => {
        setIsLoading(true);
        try {
            const data = await AuthService.setupMfa();
            setSetupData(data);
            setStep("setup");
        }
        catch (e) {
            Toast.show({
                type: "error",
                text1: getErrorMessage(e, "Failed to start MFA setup"),
                visibilityTime: 3000,
            });
        }
        finally {
            setIsLoading(false);
        }
    };
    const handleVerifyCode = async () => {
        if (code.length !== 6) {
            setError("Enter the 6-digit code from your authenticator app");
            return;
        }
        setIsLoading(true);
        try {
            await AuthService.verifyMfaSetup(code);
            await Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
            if (setupData) {
                setSetupData({ ...setupData, secret: "", uri: "" });
            }
            setStep("recovery");
        }
        catch (e) {
            setError(getErrorMessage(e, "Invalid code. Make sure your authenticator is synced."));
            await Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
        }
        finally {
            setIsLoading(false);
        }
    };
    const handleFinish = async () => {
        try {
            await refreshUser();
            setSetupData(null);
            Toast.show({
                type: "success",
                text1: "MFA enabled!",
                text2: "Your account is now protected with two-factor authentication.",
                visibilityTime: 3000,
            });
            router.replace(routes.importData);
        }
        catch (e) {
            Toast.show({
                type: "error",
                text1: getErrorMessage(e, "Failed to continue"),
                visibilityTime: 3000,
            });
        }
    };
    const handleSkip = async () => {
        try {
            setSetupData(null);
            await AuthService.completeOnboarding();
            await refreshUser();
            router.replace(routes.importData);
        }
        catch (e) {
            Toast.show({
                type: "error",
                text1: getErrorMessage(e, "Failed to skip"),
                visibilityTime: 3000,
            });
        }
    };
    /**
     * What the page says, per step.
     *
     * Held here rather than inline because the frame below takes one title and
     * one subtitle, and three branches each rendering their own header is what
     * made this screen three screens wearing the same card.
     */
    const page = step === "prompt"
        ? {
            title: "Secure your account",
            subtitle: "Two-factor authentication asks for a code from an authenticator app as well as your password.",
        }
        : step === "setup"
            ? {
                title: "Scan the QR code",
                subtitle: "Open your authenticator app and scan this, or enter the key by hand.",
            }
            : { title: "MFA is on", subtitle: "Save these recovery codes somewhere safe." };
    return (<AuthPage layout={layout} title={page.title} subtitle={page.subtitle} icon={step === "setup" ? null : (<View className="mb-3 h-16 w-16 items-center justify-center rounded-full bg-secondary dark:bg-neutral-800">
            <Ionicons name={step === "prompt" ? "shield-checkmark-outline" : "shield-checkmark"} size={32} color={isDark ? "#FFFFFF" : "#000000"}/>
          </View>)} maxWidth={400} footer={step === "prompt" ? (<>
            <Button className="w-full" telemetryId="auth.mfa_enroll.start_setup" onPress={handleStartSetup} isLoading={isLoading} accessibilityLabel="Enable MFA" accessibilityRole="button">
              Enable MFA
            </Button>
            <Button variant="ghost" className="w-full" telemetryId="auth.mfa_enroll.skip" onPress={handleSkip} accessibilityLabel="Skip for now" accessibilityRole="button">
              Skip for now
            </Button>
          </>) : step === "setup" ? (<>
            <Button className="w-full" telemetryId="auth.mfa_enroll.verify_code" onPress={handleVerifyCode} isLoading={isLoading} disabled={code.length !== 6} accessibilityLabel="Verify and enable MFA" accessibilityRole="button">
              Verify &amp; Enable
            </Button>
            <Button variant="ghost" className="w-full" telemetryId="auth.mfa_enroll.skip_2" onPress={handleSkip} accessibilityLabel="Skip for now" accessibilityRole="button">
              Skip for now
            </Button>
          </>) : (<Button className="w-full" telemetryId="auth.mfa_enroll.finish" onPress={handleFinish} accessibilityLabel={`Continue to ${appName}`} accessibilityRole="button">
            Continue to {appName}
          </Button>)}>
      {step === "prompt" ? authenticatorAppPromo : null}

      {step === "setup" && setupData ? (<>
          <View className="items-center">
            <View className="rounded-xl bg-white p-4">
              <QRCode value={setupData.uri} size={200} backgroundColor="#FFFFFF" color="#000000"/>
            </View>
          </View>

          <Separator />

          <View>
            <MutedText className="mb-2 text-center text-xs font-medium">
              Can&apos;t scan? Enter the key by hand
            </MutedText>
            <Pressable onPress={withClickTracking("auth.mfa_enroll.copy_to_clipboard", () => copyToClipboard(setupData.secret, "Secret"))} className="rounded-lg bg-secondary p-3 active:opacity-70 dark:bg-neutral-800" accessibilityRole="button" accessibilityLabel="Copy secret key" accessibilityHint="Double tap to copy the secret key to clipboard">
              <MonoText className="text-center text-base font-bold tracking-widest">
                {setupData.secret}
              </MonoText>
            </Pressable>
            <MutedText className="mt-1 text-center text-xs">Tap to copy</MutedText>
          </View>

          <Pressable onPress={withClickTracking("auth.mfa_enroll.copy_to_clipboard_2", () => copyToClipboard(setupData.uri, "URI"))} className="rounded-lg bg-secondary px-3 py-2 active:opacity-70 dark:bg-neutral-800" accessibilityRole="button" accessibilityLabel="Copy full OTP URI">
            <MutedText className="text-center text-xs">Copy full OTP URI</MutedText>
          </Pressable>

          <Separator />

          <View>
            <MutedText className="mb-1.5 text-center text-xs font-medium">
              Enter the 6-digit code from your authenticator
            </MutedText>
            <Input value={code} onChangeText={(text) => {
                setCode(text.replace(/[^0-9]/g, "").slice(0, 6));
                if (error) {
                    setError("");
                }
            }} error={error} placeholder="000000" keyboardType="number-pad" className="text-center font-mono text-xl tracking-widest" returnKeyType="done" onSubmitEditing={handleVerifyCode} accessibilityLabel="Authenticator code"/>
          </View>
        </>) : null}

      {step === "recovery" && setupData ? (<>
          <View className="rounded-lg bg-secondary p-4 dark:bg-neutral-800">
            {setupData.recovery_codes.map((rc) => (<MonoText key={rc} className="text-center text-sm leading-6">
                {rc}
              </MonoText>))}
          </View>

          <Button variant="outline" className="w-full" telemetryId="auth.mfa_enroll.copy_to_clipboard_3" onPress={() => copyToClipboard(setupData.recovery_codes.join("\n"), "Recovery codes")} accessibilityLabel="Copy all recovery codes" accessibilityRole="button">
            {copied === "Recovery codes" ? "Copied!" : "Copy all codes"}
          </Button>

          <View className="flex-row items-start gap-2 rounded-lg bg-secondary p-3 dark:bg-neutral-800">
            <Ionicons name="warning-outline" size={16} color={isDark ? "#F59E0B" : "#D97706"}/>
            <MutedText className="flex-1 text-xs leading-4">Each code works once.</MutedText>
          </View>
        </>) : null}
    </AuthPage>);
}
export default MfaEnrollScreen;
//# sourceMappingURL=MfaEnrollScreen.jsx.map