"use client";

import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { useCallback, useEffect, useState } from "react";

import { ActivityList } from "@/components/mavi/activity-list";
import { NetworkSwitcher } from "@/components/mavi/network-switcher";
import { UnlockPanel } from "@/components/mavi/unlock-panel";
import { MaviWalletLogo } from "@/components/wallet/wallet-logos";
import { Badge } from "@/components/ui/badge";
import { Button, buttonVariants } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { EmptyState } from "@/components/ui/empty-state";
import { ErrorBanner } from "@/components/ui/error-banner";
import {
  addActivity,
  notifyActivityChanged,
} from "@/lib/mavi/activity";
import { fetchEthBalance, fundFromAnvil } from "@/lib/mavi/chain";
import { getActiveNetwork } from "@/lib/mavi/network";
import {
  deleteVaultLocal,
  lockSession,
  readUnlockedSession,
  readVault,
  shortAddress,
  type UnlockedMavi,
} from "@/lib/mavi/storage";
import { readLastLoginMethod, type LoginMethodId } from "@/lib/last-login";
import { cn } from "@/lib/utils";

export function MaviHome() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const [mounted, setMounted] = useState(false);
  const [exists, setExists] = useState(false);
  const [address, setAddress] = useState<string | null>(null);
  const [unlocked, setUnlocked] = useState<UnlockedMavi | null>(null);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [info, setInfo] = useState<string | null>(null);
  const [copied, setCopied] = useState(false);
  const [balanceEth, setBalanceEth] = useState<string | null>(null);
  const [chainOk, setChainOk] = useState<boolean | null>(null);
  const [chainNote, setChainNote] = useState<string | null>(null);
  const [lastUsed, setLastUsed] = useState<LoginMethodId | null>(null);

  const nextAfterUnlock = searchParams.get("next");

  const refresh = useCallback(() => {
    const vault = readVault();
    setExists(!!vault);
    setAddress(vault?.address ?? null);
    setUnlocked(readUnlockedSession());
    setLastUsed(readLastLoginMethod());
  }, []);

  const loadBalance = useCallback(async (addr: `0x${string}`) => {
    const b = await fetchEthBalance(addr);
    const net = getActiveNetwork();
    if (b.ok) {
      setBalanceEth(b.eth);
      setChainOk(true);
      setChainNote(
        `${b.networkLabel ?? net.shortLabel} · chain id ${b.chainId ?? net.chainId}`,
      );
    } else {
      setBalanceEth(null);
      setChainOk(false);
      setChainNote(b.error ?? `${net.shortLabel} offline`);
    }
  }, []);

  useEffect(() => {
    setMounted(true);
    refresh();
    const onUnlock = () => setUnlocked(readUnlockedSession());
    window.addEventListener("mavi-unlock", onUnlock);
    window.addEventListener("mavi-network", () => {
      const a = readVault()?.address as `0x${string}` | undefined;
      if (a) void loadBalance(a);
    });
    return () => {
      window.removeEventListener("mavi-unlock", onUnlock);
    };
  }, [loadBalance, refresh]);

  useEffect(() => {
    const addr = (unlocked?.address ?? address) as `0x${string}` | null;
    if (!addr || !exists) return;
    void loadBalance(addr);
    const t = setInterval(() => void loadBalance(addr), 12_000);
    return () => clearInterval(t);
  }, [address, exists, loadBalance, unlocked?.address]);

  function handleUnlocked(u: UnlockedMavi) {
    setUnlocked(u);
    setInfo("Unlocked for this browser tab — Send and tools work until you lock.");
    void loadBalance(u.address);
    if (nextAfterUnlock?.startsWith("/portal/mavi")) {
      router.replace(nextAfterUnlock);
    }
  }

  function onLock() {
    lockSession();
    setUnlocked(null);
    setInfo("Locked. Unlock once to use Send and Get test ETH in this tab.");
  }

  function onCopy() {
    const a = unlocked?.address ?? address;
    if (!a) return;
    void navigator.clipboard.writeText(a).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 1500);
    });
  }

  async function onFund() {
    if (!unlocked) {
      setError("Unlock mavi first, then get test ETH.");
      return;
    }
    setError(null);
    setInfo(null);
    setBusy(true);
    try {
      const { hash } = await fundFromAnvil(unlocked.address, "1");
      setInfo(`Test ETH sent. Tx ${hash.slice(0, 12)}…`);
      addActivity({
        kind: "fund",
        wallet: unlocked.address,
        hash,
        to: unlocked.address,
        amountEth: "1",
        note: `Test bank · ${getActiveNetwork().shortLabel}`,
      });
      notifyActivityChanged();
      await loadBalance(unlocked.address);
    } catch (e) {
      const msg = e instanceof Error ? e.message : "Fund failed";
      setError(
        /connect|fetch|network|ECONNREFUSED/i.test(msg)
          ? "Local chain is not running. Open a terminal and run: bun run chains:up"
          : msg,
      );
    } finally {
      setBusy(false);
    }
  }

  if (!mounted) {
    return (
      <Card>
        <CardContent className="py-10 text-center text-sm text-muted-foreground">
          Loading mavi…
        </CardContent>
      </Card>
    );
  }

  if (!exists) {
    return (
      <div className="space-y-4">
        <EmptyState
          tone="default"
          title="No mavi wallet on this browser yet"
          description="Create a new wallet and back up 24 words, or import a recovery phrase you already wrote down. Keys stay in this browser only."
          action={
            <div className="flex w-full max-w-sm flex-col gap-2">
              <Link
                href="/portal/mavi/create"
                className={cn(
                  buttonVariants({ variant: "primary" }),
                  "inline-flex w-full items-center justify-center gap-2",
                )}
              >
                <MaviWalletLogo size={20} />
                Create mavi wallet
              </Link>
              <Link
                href="/portal/mavi/import"
                className={cn(
                  buttonVariants({ variant: "outline" }),
                  "w-full",
                )}
              >
                Import recovery phrase
              </Link>
            </div>
          }
        />
        {lastUsed === "mavi" ? (
          <p className="text-center text-xs text-muted-foreground">
            You last signed in with mavi on this browser — create or import
            again to continue.
          </p>
        ) : null}
      </div>
    );
  }

  return (
    <div className="space-y-4">
      <Card>
        <CardHeader>
          <div className="mb-2 flex flex-wrap items-center gap-2">
            <MaviWalletLogo size={28} />
            <CardTitle>mavi wallet</CardTitle>
            <Badge variant={unlocked ? "anchored" : "pending"}>
              {unlocked ? "Unlocked" : "Locked"}
            </Badge>
            {lastUsed === "mavi" ? (
              <Badge variant="accent">Last used to sign in</Badge>
            ) : null}
          </div>
          <CardDescription>
            {unlocked
              ? "This tab is unlocked — balance, send, and test ETH work until you lock or close the tab."
              : "Locked — unlock once for this tab, then use Send without typing the password again."}
            {address ? ` · ${shortAddress(address)}` : ""}
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          {error ? (
            <ErrorBanner title="Something went wrong">{error}</ErrorBanner>
          ) : null}
          {info ? (
            <p className="text-sm text-proof" role="status">
              {info}
            </p>
          ) : null}

          <NetworkSwitcher
            onChange={() => {
              const a = (unlocked?.address ?? address) as
                | `0x${string}`
                | null;
              if (a) void loadBalance(a);
            }}
          />

          <div className="grid gap-3 sm:grid-cols-2">
            <div className="rounded-xl border border-border bg-muted/30 px-4 py-3">
              <p className="text-xs uppercase tracking-wide text-muted-foreground">
                Address
              </p>
              <p className="mt-1 break-all font-mono text-xs sm:text-sm">
                {unlocked?.address ?? address}
              </p>
              <Button
                type="button"
                variant="outline"
                size="sm"
                className="mt-2"
                onClick={onCopy}
              >
                {copied ? "Copied" : "Copy address"}
              </Button>
            </div>
            <div className="rounded-xl border border-border bg-muted/30 px-4 py-3">
              <p className="text-xs uppercase tracking-wide text-muted-foreground">
                Balance
              </p>
              <p className="mt-1 font-display text-xl font-semibold tabular-nums">
                {balanceEth != null
                  ? `${formatEth(balanceEth)} ETH`
                  : chainOk === false
                    ? "—"
                    : "…"}
              </p>
              <p className="mt-1 text-[11px] text-muted-foreground leading-snug">
                {chainNote ??
                  (chainOk === null ? "Checking chain…" : null)}
              </p>
            </div>
          </div>

          {unlocked ? (
            <div className="flex flex-wrap gap-2">
              <Button type="button" variant="ghost" size="sm" onClick={onLock}>
                Lock
              </Button>
              <Link
                href="/portal/mavi/send"
                className={cn(buttonVariants({ size: "sm" }))}
              >
                Send
              </Link>
              <Link
                href="/portal/mavi/receive"
                className={cn(
                  buttonVariants({ variant: "outline", size: "sm" }),
                )}
              >
                Receive
              </Link>
              <Button
                type="button"
                variant="outline"
                size="sm"
                disabled={busy || chainOk === false}
                onClick={() => void onFund()}
              >
                {busy ? "Working…" : "Get test ETH"}
              </Button>
              <Link
                href="/portal/sign-in"
                className={cn(
                  buttonVariants({ variant: "outline", size: "sm" }),
                )}
              >
                Portal sign-in
              </Link>
            </div>
          ) : (
            <div className="space-y-3 border-t border-border pt-4">
              <UnlockPanel
                onUnlocked={handleUnlocked}
                title="Unlock for this tab"
                description="Enter password once. Stay unlocked until you click Lock or close the tab. Receive still works while locked."
                submitLabel="Unlock mavi"
              />
              <Link
                href="/portal/mavi/receive"
                className={cn(
                  buttonVariants({ variant: "outline" }),
                  "inline-flex w-full items-center justify-center",
                )}
              >
                Receive (address + QR)
              </Link>
            </div>
          )}
        </CardContent>
      </Card>

      {address ? <ActivityList walletAddress={address} compact /> : null}

      <Card>
        <CardHeader>
          <CardTitle className="text-base">More</CardTitle>
          <CardDescription>
            Import another phrase only after removing this vault (or confirm
            replace on import).
          </CardDescription>
        </CardHeader>
        <CardContent className="flex flex-wrap gap-2">
          <Link
            href="/portal/mavi/import"
            className={cn(buttonVariants({ variant: "outline", size: "sm" }))}
          >
            Import recovery phrase
          </Link>
          <Link
            href="/portal/mavi/create"
            className={cn(buttonVariants({ variant: "ghost", size: "sm" }))}
          >
            Create new (after remove)
          </Link>
          <Link
            href="/portal/mavi/activity"
            className={cn(buttonVariants({ variant: "ghost", size: "sm" }))}
          >
            Activity
          </Link>
          <p className="w-full text-xs text-muted-foreground leading-relaxed pt-1">
            Browser add-on with its own encrypted keys:{" "}
            <code className="text-[11px]">apps/mavi-extension</code> — run{" "}
            <code className="text-[11px]">bun run --cwd apps/mavi-extension build</code>{" "}
            then load unpacked (Chrome, Brave, Edge, Opera, Firefox). Portal and
            extension vaults are separate storage.
          </p>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle className="text-base">Danger zone</CardTitle>
          <CardDescription>
            Removing the local vault only deletes the encrypted copy in this
            browser. Keep your recovery phrase safe.
          </CardDescription>
        </CardHeader>
        <CardContent>
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="border-pending/40 text-pending"
            onClick={() => {
              if (
                window.confirm(
                  "Remove mavi vault from this browser? You will need your recovery phrase to restore.",
                )
              ) {
                deleteVaultLocal();
                refresh();
                setError(null);
                setInfo(null);
                setBalanceEth(null);
              }
            }}
          >
            Remove vault from this browser
          </Button>
        </CardContent>
      </Card>
    </div>
  );
}

function formatEth(eth: string): string {
  const n = Number(eth);
  if (!Number.isFinite(n)) return eth;
  if (n === 0) return "0";
  if (n >= 1000) return n.toFixed(2);
  if (n >= 1) return n.toFixed(4).replace(/\.?0+$/, "");
  return n.toFixed(6).replace(/\.?0+$/, "");
}
