/* eslint-disable no-restricted-syntax -- waitForTimeout: no event source exists for Vue component animation settling and wagmi wallet connector state transitions. See AGENTS.md #Engineering Principles. */
/**
 * Shared wallet helpers for holdout scenarios.
 *
 * Functions here operate in the Playwright Node.js context (not the browser).
 * UI interactions use Playwright locators; on-chain reads use direct RPC calls
 * so that tests do not depend on the app's wallet state for balance queries.
 */
import type { Page } from '@playwright/test';
import { expect } from '@playwright/test';
import { rpcCall } from './rpc';

// ── Balance readers ──────────────────────────────────────────────────────────

/** Return the native ETH balance (in wei) of `address`. */
export async function getEthBalance(rpcUrl: string, address: string): Promise<bigint> {
  const result = (await rpcCall(rpcUrl, 'eth_getBalance', [address, 'latest'])) as string;
  return BigInt(result);
}

/** Return the ERC-20 KRK balance (in wei) of `address` on the given token contract. */
export async function getKrkBalance(rpcUrl: string, krkAddress: string, address: string): Promise<bigint> {
  const selector = '0x70a08231'; // balanceOf(address)
  const data = selector + address.slice(2).padStart(64, '0');
  const result = (await rpcCall(rpcUrl, 'eth_call', [{ to: krkAddress, data }, 'latest'])) as string;
  return BigInt(result);
}

// ── UI helpers ───────────────────────────────────────────────────────────────

/**
 * Connect the test wallet via the desktop UI flow.
 *
 * Expects the page to already be on the web app with the navbar visible.
 * The injected wallet provider must already be set up by createWalletContext.
 * Verifies connection by waiting for the connected button to appear in the navbar.
 */
export async function connectWallet(page: Page): Promise<void> {
  // Trigger resize so Vue's useMobile composable re-evaluates with screen.width=1280.
  await page.evaluate(() => window.dispatchEvent(new Event('resize')));
  await page.waitForTimeout(2_000);

  const screenWidth = await page.evaluate(() => window.screen.width);
  console.log(`[wallet] screen.width = ${screenWidth}`);

  // Check if wallet is already connected (e.g. wagmi auto-reconnected from storage)
  const connectedButton = page.locator('.connect-button--connected').first();
  if (await connectedButton.isVisible({ timeout: 1_000 }).catch(() => false)) {
    console.log('[wallet] Wallet already connected (auto-reconnect)');
    return;
  }

  let panelOpened = false;

  const connectButton = page.locator('.connect-button--disconnected').first();
  if (await connectButton.isVisible({ timeout: 10_000 })) {
    console.log('[wallet] Found desktop Connect button, clicking...');
    await connectButton.click();
    panelOpened = true;
  } else {
    // Fallback: mobile login icon. Dead code when screen.width=1280 but kept for safety.
    const mobileLoginIcon = page.locator('.navbar-end svg').first();
    if (await mobileLoginIcon.isVisible({ timeout: 2_000 })) {
      console.log('[wallet] Found mobile login icon, clicking...');
      await mobileLoginIcon.click();
      panelOpened = true;
    }
  }

  if (panelOpened) {
    await page.waitForTimeout(1_000);
    const injectedConnector = page.locator('.connectors-element').first();
    if (await injectedConnector.isVisible({ timeout: 5_000 })) {
      console.log('[wallet] Clicking wallet connector...');
      await injectedConnector.click();
      await page.waitForTimeout(2_000);
    } else {
      console.log('[wallet] WARNING: No wallet connector found in panel');
    }
  }

  // The navbar shows .connect-button--connected once wagmi reports status=connected.
  await expect(page.locator('.connect-button--connected').first()).toBeVisible({ timeout: 15_000 });
  console.log('[wallet] Wallet connected');
}

/**
 * Disconnect the wallet by opening the connected panel and clicking the logout icon.
 *
 * Verifies disconnection by waiting for the Connect button to reappear.
 */
export async function disconnectWallet(page: Page): Promise<void> {
  const connectedButton = page.locator('.connect-button--connected').first();
  await expect(connectedButton).toBeVisible({ timeout: 5_000 });
  await connectedButton.click();

  // Panel opens showing .connected-header-logout (img alt="Logout").
  const logoutIcon = page.locator('.connected-header-logout').first();
  await expect(logoutIcon).toBeVisible({ timeout: 5_000 });
  await logoutIcon.click();

  await expect(page.locator('.connect-button--disconnected').first()).toBeVisible({ timeout: 10_000 });
  console.log('[wallet] Wallet disconnected');
}
