import { QRCodeSVG } from "qrcode.react";
import { ChevronLeft, ChevronRight, LoaderCircle, X } from "lucide-react";
import { useEffect, useState } from "react";
import { useI18n } from "../i18n";

import { openWalletDeepLink } from "./deepLinks";
import { getInjectedWallet, type WalletKind } from "./injected";
import { useWallet } from "./WalletProvider";
import { useWalletConnectLogin } from "./useWalletConnectLogin";
import { WalletBrandIcon } from "./WalletBrandIcon";

type ModalState = "idle" | "signing";
type Step = "wallet" | "method";

const wallets: WalletKind[] = ["tokenPocket", "metaMask", "imToken"];

function isMobileDevice(): boolean {
  if (typeof navigator === "undefined") return false;
  const ua = navigator.userAgent || "";
  if (
    /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile/i.test(
      ua,
    )
  ) {
    return true;
  }
  // iPadOS 13+ reports a desktop "Macintosh" UA. A genuine touch-primary iPad
  // exposes a coarse pointer; a Mac (even with a touch peripheral) keeps a fine
  // pointer, so it stays on the desktop flow instead of the wallet-app jump.
  const coarsePointer =
    typeof window !== "undefined" &&
    typeof window.matchMedia === "function" &&
    window.matchMedia("(pointer: coarse)").matches;
  return /Macintosh/i.test(ua) && navigator.maxTouchPoints > 1 && coarsePointer;
}

export function WalletLoginModal() {
  const { t } = useI18n();
  const { closeLoginModal, loginModalOpen, signInInjected } = useWallet();
  const wc = useWalletConnectLogin();
  const [step, setStep] = useState<Step>("wallet");
  const [selected, setSelected] = useState<WalletKind | null>(null);
  const [state, setState] = useState<ModalState>("idle");
  const [error, setError] = useState("");
  const [mobileDevice, setMobileDevice] = useState(false);

  const resetWalletConnect = wc.reset;

  useEffect(() => {
    if (!loginModalOpen) return;
    setMobileDevice(isMobileDevice());
    setStep("wallet");
    setSelected(null);
    setState("idle");
    setError("");
    resetWalletConnect();
  }, [loginModalOpen, resetWalletConnect]);

  const busy = state === "signing";

  const close = () => {
    if (busy) return;
    closeLoginModal();
    setError("");
  };

  if (!loginModalOpen) return null;

  const walletName = (kind: WalletKind) => t(walletNameKey(kind));
  // A wallet's browser flow only works if THAT wallet is injected right now
  // (its desktop extension, or its in-app browser on mobile).
  const injectedAvailable = (kind: WalletKind) =>
    Boolean(getInjectedWallet(kind));
  // All scan/app login paths use RainbowKit/WalletConnect on BNB Chain.
  const qrAvailable = () => wc.available;

  const resetFlow = () => {
    setError("");
    setState("idle");
    wc.reset();
  };

  const pickWallet = (kind: WalletKind) => {
    resetFlow();
    setSelected(kind);
    setStep("method");
  };

  const back = () => {
    if (busy) return;
    resetFlow();
    setSelected(null);
    setStep("wallet");
  };

  const signInjectedFor = async (kind: WalletKind) => {
    setError("");
    if (!getInjectedWallet(kind)) {
      setError(
        t("walletInstallSelected").replace("{wallet}", walletName(kind)),
      );
      return;
    }
    setState("signing");
    await signInInjected(kind)
      .catch((err) => {
        setError(err instanceof Error ? err.message : t("walletLoginFailed"));
      })
      .finally(() => setState("idle"));
  };

  const chooseQr = (kind: WalletKind) => {
    setError("");
    void wc.start(kind);
  };

  const iconButtonClass =
    "inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full border border-white/10 text-neutral-300 transition hover:border-ark-gold/50 hover:text-ark-gold";

  return (
    <div
      className="fixed inset-0 z-[120] flex items-end justify-center bg-black/70 px-3 pb-3 pt-10 backdrop-blur-sm md:items-center md:p-6"
      role="dialog"
      aria-modal="true"
      aria-labelledby="wallet-login-title"
    >
      <div className="max-h-[92dvh] w-full max-w-[460px] overflow-y-auto rounded-3xl border border-white/10 bg-[#17171d] p-5 shadow-2xl shadow-black/70 md:p-6">
        <div className="flex items-start justify-between gap-3">
          <div className="flex min-w-0 items-start gap-2">
            {step === "method" ? (
              <button
                type="button"
                onClick={back}
                aria-label={t("walletBack")}
                className={`${iconButtonClass} mt-0.5`}
              >
                <ChevronLeft size={18} />
              </button>
            ) : null}
            <div className="min-w-0">
              <h2
                id="wallet-login-title"
                className="text-xl font-semibold text-white"
              >
                {t("walletLoginTitle")}
              </h2>
              <p className="mt-2 text-sm leading-6 text-neutral-400">
                {step === "wallet"
                  ? t("walletLoginDesc")
                  : t("walletChooseMethod")}
              </p>
            </div>
          </div>
          <button
            type="button"
            onClick={close}
            aria-label={t("close")}
            className={iconButtonClass}
          >
            <X size={18} />
          </button>
        </div>

        {/* Step 1 — choose a wallet. */}
        {step === "wallet" ? (
          <div className="mt-5 grid gap-2">
            {wallets.map((kind) => (
              <button
                key={kind}
                type="button"
                onClick={() => pickWallet(kind)}
                className="flex items-center gap-3 rounded-2xl border border-white/10 bg-[#20202a] px-4 py-4 text-left transition hover:border-ark-gold/50 hover:bg-ark-gold/10"
              >
                <WalletBrandIcon kind={kind} size={32} />
                <span className="flex-1 text-base font-semibold text-neutral-100">
                  {walletName(kind)}
                </span>
                <ChevronRight size={18} className="text-neutral-500" />
              </button>
            ))}
          </div>
        ) : selected ? (
          <div className="mt-5 grid gap-3">
            {/* Selected wallet header. */}
            <div className="flex items-center gap-3 rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3">
              <WalletBrandIcon kind={selected} size={28} />
              <span className="text-base font-semibold text-white">
                {walletName(selected)}
              </span>
            </div>

            {!mobileDevice && !injectedAvailable(selected) ? (
              <p className="rounded-2xl border border-amber-400/30 bg-amber-400/10 px-4 py-3 text-sm leading-6 text-amber-100">
                {t("walletInstallSelected").replace(
                  "{wallet}",
                  walletName(selected),
                )}
              </p>
            ) : null}

            {mobileDevice ? (
              <button
                type="button"
                onClick={() => openWalletDeepLink(selected)}
                className="flex flex-col items-start gap-1 rounded-2xl border border-white/10 bg-[#20202a] px-4 py-3 text-left transition hover:border-ark-gold/50 hover:bg-ark-gold/10"
              >
                <span className="text-base font-semibold text-neutral-100">
                  {t("walletOpenWalletApp")}
                </span>
                <span className="text-xs leading-5 text-neutral-400">
                  {t("walletOpenWalletAppDesc")}
                </span>
              </button>
            ) : null}

            {/* Method: browser wallet (injected). Hidden on normal mobile browsers,
                because only wallet in-app browsers expose an injected wallet. */}
            {(() => {
              const ok = injectedAvailable(selected);
              if (mobileDevice) return null;
              return (
                <button
                  type="button"
                  onClick={() => void signInjectedFor(selected)}
                  disabled={!ok || busy}
                  className={`flex flex-col items-start gap-1 rounded-2xl border px-4 py-3 text-left transition ${
                    ok
                      ? "border-white/10 bg-[#20202a] hover:border-ark-gold/50 hover:bg-ark-gold/10"
                      : "cursor-not-allowed border-white/5 bg-white/[0.02] opacity-60"
                  }`}
                >
                  <span className="flex items-center gap-2 text-base font-semibold text-neutral-100">
                    {state === "signing" ? (
                      <LoaderCircle className="h-4 w-4 animate-spin text-ark-gold" />
                    ) : null}
                    {mobileDevice ? t("walletUseCurrent") : t("walletInjected")}
                  </span>
                  <span className="text-xs leading-5 text-neutral-400">
                    {ok
                      ? t("walletInjectedDesc")
                      : mobileDevice
                        ? t("walletOpenWalletAppDesc")
                        : t("walletInstallSelected").replace(
                            "{wallet}",
                            walletName(selected),
                          )}
                  </span>
                </button>
              );
            })()}

            {/* Method: scan to log in. */}
            {(() => {
              const ok = qrAvailable();
              const isTp = selected === "tokenPocket";
              const qrBusy = wc.state !== "idle";
              const qrLabel =
                wc.state === "connecting"
                  ? t("walletConnecting")
                  : wc.state === "signing"
                    ? t("walletSigning")
                    : t("walletQrLogin");
              return (
                <div className="grid gap-2">
                  <button
                    type="button"
                    onClick={() => chooseQr(selected)}
                    disabled={!ok || qrBusy || busy}
                    className={`flex flex-col items-start gap-1 rounded-2xl border px-4 py-3 text-left transition ${
                      ok
                        ? "border-white/10 bg-[#20202a] hover:border-ark-gold/50 hover:bg-ark-gold/10"
                        : "cursor-not-allowed border-white/5 bg-white/[0.02] opacity-60"
                    }`}
                  >
                    <span className="text-base font-semibold text-neutral-100">
                      {qrLabel}
                    </span>
                    <span className="text-xs leading-5 text-neutral-400">
                      {ok
                        ? isTp
                          ? mobileDevice
                            ? t("walletTpMobileDesc")
                            : t("walletTokenPocketQrDesc")
                          : t("walletRainbowFallbackDesc")
                        : t("walletRainbowUnavailable")}
                    </span>
                  </button>

                  {ok ? (
                    <p className="text-xs leading-5 text-amber-300/80">
                      {t("walletNetworkWarning")}
                    </p>
                  ) : null}

                  {wc.qrUri ? (
                    <div className="grid place-items-center gap-2 rounded-2xl bg-white p-4 text-center">
                      <QRCodeSVG value={wc.qrUri} size={180} level="M" />
                      <p className="text-xs font-medium text-neutral-700">
                        {mobileDevice
                          ? t("walletTpWaiting")
                          : t("walletQrUseAnotherDevice")}
                      </p>
                    </div>
                  ) : null}
                </div>
              );
            })()}
          </div>
        ) : null}

        {error || wc.error ? (
          <p className="mt-4 rounded-2xl border border-red-500/30 bg-red-500/10 px-4 py-3 text-sm text-red-200">
            {error || wc.error}
          </p>
        ) : null}
      </div>
    </div>
  );
}

function walletNameKey(kind: WalletKind): string {
  if (kind === "tokenPocket") return "walletTokenPocket";
  if (kind === "metaMask") return "walletMetaMask";
  return "walletImToken";
}
