import { useEffect } from "react";
import {
  connectInjectedWallet,
  getInjectedWallet,
  isImTokenBrowser,
  type WalletKind,
} from "./injected";
import { useWallet } from "./WalletProvider";

const AUTO_LOGIN_PARAMS = ["autoLogin", "autologin"];
const ETHEREUM_WAIT_MS = 8000;
const ETHEREUM_POLL_MS = 200;

function parseKind(value: string | null): WalletKind | null {
  const normalized = value?.toLowerCase();
  if (normalized === "tokenpocket") return "tokenPocket";
  if (normalized === "metamask") return "metaMask";
  if (normalized === "imtoken") return "imToken";
  return null;
}

function autoLoginKind(params: URLSearchParams): WalletKind | null {
  for (const key of AUTO_LOGIN_PARAMS) {
    const kind = parseKind(params.get(key));
    if (kind) return kind;
  }
  return isImTokenBrowser() ? "imToken" : null;
}

function hasAutoLoginParam(params: URLSearchParams): boolean {
  return AUTO_LOGIN_PARAMS.some((key) => params.has(key));
}

function stripAutoLoginParam(): void {
  const url = new URL(window.location.href);
  for (const key of AUTO_LOGIN_PARAMS) url.searchParams.delete(key);
  const qs = url.searchParams.toString();
  const next = url.pathname + (qs ? `?${qs}` : "") + url.hash;
  window.history.replaceState({}, "", next);
}

function waitForInjected(kind: WalletKind): Promise<boolean> {
  return new Promise((resolve) => {
    const start = Date.now();
    const tick = () => {
      if (getInjectedWallet(kind)) {
        resolve(true);
        return;
      }
      if (Date.now() - start >= ETHEREUM_WAIT_MS) {
        resolve(false);
        return;
      }
      window.setTimeout(tick, ETHEREUM_POLL_MS);
    };
    tick();
  });
}

export function AutoInjectedLogin() {
  const { loginAddress, status } = useWallet();

  useEffect(() => {
    if (typeof window === "undefined") return;
    const params = new URLSearchParams(window.location.search);
    const kind = autoLoginKind(params);
    if (!kind) return;

    if (hasAutoLoginParam(params)) stripAutoLoginParam();
    if (status === "loggedIn") return;

    let cancelled = false;
    void waitForInjected(kind).then(async (ready) => {
      if (cancelled || !ready) return;
      try {
        const address = await connectInjectedWallet(kind);
        if (cancelled) return;
        await loginAddress(address);
      } catch (err) {
        console.warn("[wallet-autologin] failed", err);
      }
    });
    return () => {
      cancelled = true;
    };
  }, []);

  return null;
}
