"use client";

/**
 * mavi create + 24-word backup + MetaMask-style 6-blank confirm quiz.
 * All secrets stay in this browser.
 */

import {
  buildRecoveryQuiz,
  createWallet,
  MAVI_DEFAULT_WORD_COUNT,
  MAVI_MIN_PASSWORD_LENGTH,
  MAVI_QUIZ_BLANK_COUNT,
  quizAnswersMatch,
  quizProgress,
  type CreatedWallet,
  type RecoveryQuizItem,
} from "@krypco/mavi-core";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useCallback, useMemo, useState } from "react";

import { MaviWalletLogo } from "@/components/wallet/wallet-logos";
import { Button, buttonVariants } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { ErrorBanner } from "@/components/ui/error-banner";
import { PasswordInput } from "@/components/ui/password-input";
import { saveNewVault, shortAddress } from "@/lib/mavi/storage";
import { cn } from "@/lib/utils";

type Step = "setup" | "backup" | "confirm" | "done";

export function CreateWalletFlow() {
  const router = useRouter();
  const [step, setStep] = useState<Step>("setup");
  const [password, setPassword] = useState("");
  const [password2, setPassword2] = useState("");
  const [wallet, setWallet] = useState<CreatedWallet | null>(null);
  const [revealed, setRevealed] = useState(false);
  const [quiz, setQuiz] = useState<RecoveryQuizItem[]>([]);
  /** answers keyed by word index in the full phrase */
  const [answers, setAnswers] = useState<Record<number, string>>({});
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const words = useMemo(
    () => (wallet ? wallet.mnemonic.split(" ") : []),
    [wallet],
  );

  const setupValid =
    password.length >= MAVI_MIN_PASSWORD_LENGTH && password === password2;

  const progress = quizProgress(quiz, answers);
  const quizComplete =
    quiz.length > 0 && progress.filled === progress.total;

  const startQuiz = useCallback((mnemonic: string) => {
    const q = buildRecoveryQuiz(mnemonic, MAVI_QUIZ_BLANK_COUNT);
    setQuiz(q);
    setAnswers({});
  }, []);

  const onGenerate = useCallback(() => {
    setError(null);
    if (password.length < MAVI_MIN_PASSWORD_LENGTH) {
      setError(
        `Password must be at least ${MAVI_MIN_PASSWORD_LENGTH} characters.`,
      );
      return;
    }
    if (password !== password2) {
      setError("Passwords do not match.");
      return;
    }
    try {
      const w = createWallet(MAVI_DEFAULT_WORD_COUNT);
      setWallet(w);
      setRevealed(false);
      setQuiz([]);
      setAnswers({});
      setStep("backup");
    } catch (e) {
      setError(e instanceof Error ? e.message : "Could not create wallet.");
    }
  }, [password, password2]);

  const goToConfirm = useCallback(() => {
    if (!wallet) return;
    setError(null);
    startQuiz(wallet.mnemonic);
    setStep("confirm");
  }, [startQuiz, wallet]);

  const onConfirmBackup = useCallback(async () => {
    if (!wallet) return;
    setError(null);
    if (!quizAnswersMatch(quiz, answers)) {
      setError(
        "Some words are wrong. Pick the correct word for each blank, or go back and check your list.",
      );
      return;
    }
    setBusy(true);
    try {
      await saveNewVault(password, wallet);
      setStep("done");
    } catch (e) {
      setError(e instanceof Error ? e.message : "Could not save wallet.");
    } finally {
      setBusy(false);
    }
  }, [answers, password, quiz, wallet]);

  function pickChoice(index: number, word: string) {
    setAnswers((prev) => ({ ...prev, [index]: word }));
    setError(null);
  }

  return (
    <div className="mx-auto max-w-xl space-y-4">
      <StepDots step={step} />

      {error ? (
        <ErrorBanner title="Something went wrong">{error}</ErrorBanner>
      ) : null}

      {step === "setup" ? (
        <Card>
          <CardHeader>
            <div className="mb-2 flex items-center gap-2">
              <MaviWalletLogo size={28} />
              <CardTitle>Create mavi</CardTitle>
            </div>
            <CardDescription>
              Set a password that locks mavi on{" "}
              <strong className="text-foreground">this browser only</strong>.
              You will get a <strong className="text-foreground">24-word</strong>{" "}
              recovery phrase — never sent to krypco servers.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-5">
            <div className="rounded-lg border border-border bg-muted/20 px-3 py-2 text-xs text-muted-foreground leading-relaxed">
              Recovery phrase: <strong className="text-foreground">24 words</strong>
              . Next you write them down, then confirm{" "}
              <strong className="text-foreground">6 random words</strong> (like
              MetaMask).
            </div>

            <PasswordInput
              id="mavi-pw"
              label="Password"
              value={password}
              onChange={setPassword}
              placeholder={`At least ${MAVI_MIN_PASSWORD_LENGTH} characters`}
              autoComplete="new-password"
            />
            <PasswordInput
              id="mavi-pw2"
              label="Confirm password"
              value={password2}
              onChange={setPassword2}
              placeholder="Type it again"
              autoComplete="new-password"
            />

            <Button
              type="button"
              className="w-full"
              disabled={!setupValid}
              onClick={onGenerate}
            >
              Continue — show recovery phrase
            </Button>
            <p className="text-xs text-muted-foreground leading-relaxed">
              Anyone with your 24 words can control this wallet. krypco cannot
              reset them for you.
            </p>
          </CardContent>
        </Card>
      ) : null}

      {step === "backup" && wallet ? (
        <Card>
          <CardHeader>
            <CardTitle>Write down your Secret Recovery Phrase</CardTitle>
            <CardDescription>
              24 words, in order. Store them offline. Do not email them or post
              them online.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            {!revealed ? (
              <div className="rounded-xl border border-pending/40 bg-pending/5 px-4 py-8 text-center">
                <p className="mb-4 text-sm text-muted-foreground">
                  Phrase is hidden until you are ready to write it down.
                </p>
                <Button type="button" onClick={() => setRevealed(true)}>
                  I am ready — reveal phrase
                </Button>
              </div>
            ) : (
              <ol className="grid grid-cols-2 gap-2 sm:grid-cols-3">
                {words.map((w, i) => (
                  <li
                    key={`${i}-${w}`}
                    className="flex items-center gap-2 rounded-full border border-border bg-muted/30 px-3 py-2 font-mono text-sm"
                  >
                    <span className="w-6 shrink-0 text-xs text-muted-foreground">
                      {i + 1}.
                    </span>
                    <span>{w}</span>
                  </li>
                ))}
              </ol>
            )}

            <div className="rounded-lg border border-border bg-muted/20 px-3 py-2 text-xs text-muted-foreground leading-relaxed">
              Next you will confirm{" "}
              <strong className="text-foreground">6 random words</strong> from
              this list (different words each time you try).
            </div>

            <div className="flex flex-col gap-2 sm:flex-row">
              <Button
                type="button"
                variant="outline"
                className="sm:flex-1"
                onClick={() => {
                  setWallet(null);
                  setRevealed(false);
                  setStep("setup");
                }}
              >
                Back
              </Button>
              <Button
                type="button"
                className="sm:flex-1"
                disabled={!revealed}
                onClick={goToConfirm}
              >
                I wrote it down
              </Button>
            </div>
          </CardContent>
        </Card>
      ) : null}

      {step === "confirm" && wallet && quiz.length > 0 ? (
        <Card>
          <CardHeader>
            <CardTitle>Confirm Secret Recovery Phrase</CardTitle>
            <CardDescription>
              Select each word in the order it was presented to you.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-5">
            <p className="text-sm font-medium text-muted-foreground">
              {progress.filled} of {progress.total}
            </p>

            <div className="space-y-5">
              {quiz.map((q) => {
                const selected = answers[q.index];
                return (
                  <div key={q.index} className="space-y-2">
                    <p className="text-sm font-medium text-foreground">
                      Word #{q.wordNumber}
                    </p>
                    <div className="flex flex-wrap gap-2">
                      {q.choices.map((choice) => {
                        const isSelected = selected === choice;
                        return (
                          <button
                            key={`${q.index}-${choice}`}
                            type="button"
                            onClick={() => pickChoice(q.index, choice)}
                            className={cn(
                              "rounded-full border px-4 py-2 font-mono text-sm transition-colors",
                              isSelected
                                ? "border-accent bg-accent/15 text-accent-hover ring-1 ring-accent/40"
                                : "border-border bg-muted/20 text-foreground hover:bg-muted/50",
                            )}
                          >
                            {choice}
                          </button>
                        );
                      })}
                    </div>
                  </div>
                );
              })}
            </div>

            <div className="flex flex-col gap-2 sm:flex-row">
              <Button
                type="button"
                variant="outline"
                className="sm:flex-1"
                disabled={busy}
                onClick={() => {
                  setError(null);
                  setStep("backup");
                }}
              >
                Back to phrase
              </Button>
              <Button
                type="button"
                variant="ghost"
                className="sm:flex-1"
                disabled={busy}
                onClick={() => {
                  if (wallet) startQuiz(wallet.mnemonic);
                  setError(null);
                }}
              >
                New random words
              </Button>
              <Button
                type="button"
                className="sm:flex-1"
                disabled={busy || !quizComplete}
                onClick={() => void onConfirmBackup()}
              >
                {busy ? "Saving…" : "Continue"}
              </Button>
            </div>
          </CardContent>
        </Card>
      ) : null}

      {step === "done" && wallet ? (
        <Card>
          <CardHeader>
            <div className="mb-2 flex items-center gap-2">
              <MaviWalletLogo size={28} />
              <CardTitle>mavi is ready</CardTitle>
            </div>
            <CardDescription>
              Your wallet is encrypted on this browser. Use your password to
              unlock later. Keep your paper backup safe.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="rounded-xl border border-proof/30 bg-proof/5 px-4 py-3">
              <p className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
                Address
              </p>
              <p className="mt-1 break-all font-mono text-sm text-foreground">
                {wallet.address}
              </p>
              <p className="mt-1 text-xs text-muted-foreground">
                Short form: {shortAddress(wallet.address)}
              </p>
            </div>
            <div className="flex flex-col gap-2">
              <Link
                href="/portal/mavi"
                className={cn(
                  buttonVariants({ variant: "primary" }),
                  "inline-flex w-full items-center justify-center gap-2",
                )}
              >
                <MaviWalletLogo size={20} />
                mavi wallet
              </Link>
              <Button
                type="button"
                variant="outline"
                className="w-full"
                onClick={() => router.push("/portal/dashboard")}
              >
                Go to dashboard
              </Button>
            </div>
          </CardContent>
        </Card>
      ) : null}
    </div>
  );
}

function StepDots({ step }: { step: Step }) {
  const order: Step[] = ["setup", "backup", "confirm", "done"];
  const labels = ["Password", "Write phrase", "Confirm 6", "Ready"];
  const idx = order.indexOf(step);
  return (
    <ol className="flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
      {labels.map((label, i) => (
        <li key={label} className="flex items-center gap-2">
          <span
            className={cn(
              "inline-flex h-6 min-w-6 items-center justify-center rounded-full border px-1.5 font-medium",
              i <= idx
                ? "border-accent/50 bg-accent/10 text-accent-hover"
                : "border-border",
            )}
          >
            {i + 1}
          </span>
          <span className={i === idx ? "text-foreground" : undefined}>
            {label}
          </span>
          {i < labels.length - 1 ? (
            <span className="text-border" aria-hidden>
              →
            </span>
          ) : null}
        </li>
      ))}
    </ol>
  );
}


