import { expect, test } from '@playwright/test';
import { Wallet } from 'ethers';
import { createWalletContext } from '../../setup/wallet-provider';
import { getStackConfig, validateStackHealthy } from '../../setup/stack';
import {
  createReport,
  connectWallet,
  mintEth,
  buyKrk,
  takeScreenshot,
  logObservation,
  logCopyFeedback,
  logTokenomicsQuestion,
  recordPageVisit,
  recordAction,
  writeReport,
  attemptStake,
  resetChainState,
} from './helpers';

// Sarah uses Anvil account #2
const ACCOUNT_PRIVATE_KEY = '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a';
const ACCOUNT_ADDRESS = new Wallet(ACCOUNT_PRIVATE_KEY).address.toLowerCase();

const STACK_CONFIG = getStackConfig();
const STACK_RPC_URL = STACK_CONFIG.rpcUrl;
const STACK_WEBAPP_URL = STACK_CONFIG.webAppUrl;

test.describe('Sarah Park - Cautious Yield Farmer', () => {
  test.beforeAll(async () => {
    await resetChainState(STACK_RPC_URL);
    await validateStackHealthy(STACK_CONFIG);
  });

  test('Sarah researches thoroughly before committing capital', async ({ browser }) => {
    const report = createReport('Sarah Park');
    const personaName = 'Sarah';
    
    console.log(`[${personaName}] Starting test - Cautious yield farmer seeking sustainable returns...`);
    
    const context = await createWalletContext(browser, {
      privateKey: ACCOUNT_PRIVATE_KEY,
      rpcUrl: STACK_RPC_URL,
    });
    
    const page = await context.newPage();
    page.on('console', msg => console.log(`[BROWSER] ${msg.type()}: ${msg.text()}`));
    page.on('pageerror', error => console.log(`[BROWSER ERROR] ${error.message}`));
    
    try {
      // --- Landing Page (Reads Everything) ---
      let pageStart = Date.now();
      await page.goto(`${STACK_WEBAPP_URL}/app/`, { waitUntil: 'domcontentloaded' });
      // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for animation settling, wallet connector UI transitions, and debounced state updates in user-simulation tests. See AGENTS.md #Engineering Principles.
      await page.waitForTimeout(3_000);
      
      await takeScreenshot(page, personaName, 'landing-page', report);
      logObservation(personaName, 'Reading landing page carefully before connecting wallet', report);
      logCopyFeedback(personaName, 'Landing page should explain "What is Harberger tax?" in simple terms', report);
      
      recordPageVisit('Landing', page.url(), pageStart, report);
      
      // --- Look for About/Docs FIRST ---
      logObservation(personaName, 'Looking for About, Docs, or Team page before doing anything else...', report);
      
      const hasAbout = await page.getByText(/about/i).first().isVisible().catch(() => false);
      const hasDocs = await page.getByText(/docs|documentation/i).first().isVisible().catch(() => false);
      const hasTeam = await page.getByText(/team/i).first().isVisible().catch(() => false);
      
      if (!hasAbout && !hasDocs && !hasTeam) {
        logCopyFeedback(personaName, 'MAJOR ISSUE: No About, Docs, or Team link visible. I need background info before trusting this.', report);
        logObservation(personaName, 'Feeling uncertain - no clear educational resources or team transparency', report);
      }
      
      await takeScreenshot(page, personaName, 'looking-for-info', report);
      
      // --- Check for Audit Badge ---
      const auditVisible = await page.getByText(/audit/i).isVisible().catch(() => false);
      if (!auditVisible) {
        logCopyFeedback(personaName, 'No audit badge visible - this is a dealbreaker for me normally, but will test anyway', report);
        logTokenomicsQuestion(personaName, 'Has this been audited by Certik, Trail of Bits, or similar?', report);
      }
      
      // --- Connect Wallet (Hesitantly) ---
      logObservation(personaName, 'Deciding to connect wallet after reading available info...', report);
      
      pageStart = Date.now();
      await connectWallet(page);
      await takeScreenshot(page, personaName, 'wallet-connected', report);
      recordAction('Connect wallet', true, undefined, report);
      logObservation(personaName, 'Wallet connected. Now checking the staking interface details.', report);
      
      // --- Navigate to Stake Page to Learn ---
      pageStart = Date.now();
      await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
      // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for animation settling, wallet connector UI transitions, and debounced state updates in user-simulation tests. See AGENTS.md #Engineering Principles.
      await page.waitForTimeout(3_000);
      recordPageVisit('Stake (research)', page.url(), pageStart, report);
      
      await takeScreenshot(page, personaName, 'stake-page-reading', report);
      logObservation(personaName, 'Reading staking dashboard carefully - what are these tax rates about?', report);
      logCopyFeedback(personaName, 'The info icon next to "Staking Dashboard" helps, but needs more detail on risks', report);
      logTokenomicsQuestion(personaName, 'If I stake at 10% tax, what\'s my expected APY after taxes?', report);
      logTokenomicsQuestion(personaName, 'What happens if I get snatched? Do I lose my principal or just my position?', report);
      
      // --- Check Statistics Section ---
      const statsSection = page.locator('.statistics-wrapper');
      const statsVisible = await statsSection.isVisible().catch(() => false);
      
      if (statsVisible) {
        await takeScreenshot(page, personaName, 'statistics-analysis', report);
        logObservation(personaName, 'Examining statistics - average tax rate, claimed slots, inflation rate', report);
        logTokenomicsQuestion(personaName, 'How does the 7-day inflation compare to my expected staking returns?', report);
      } else {
        logCopyFeedback(personaName, 'Would be helpful to see protocol statistics and historical data', report);
      }
      
      // --- Mint ETH ---
      pageStart = Date.now();
      await page.goto(`${STACK_WEBAPP_URL}/app/cheats`);
      // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for animation settling, wallet connector UI transitions, and debounced state updates in user-simulation tests. See AGENTS.md #Engineering Principles.
      await page.waitForTimeout(1_000);
      recordPageVisit('Cheats', page.url(), pageStart, report);
      
      logObservation(personaName, 'Using test environment to simulate before committing real funds', report);
      await mintEth(page, STACK_RPC_URL, ACCOUNT_ADDRESS, '20');
      recordAction('Mint 20 ETH', true, undefined, report);
      
      // --- Small Test Purchase ---
      logObservation(personaName, 'Starting with a small test purchase to understand the process', report);
      
      await buyKrk(page, '0.05');
      recordAction('Buy KRK with 0.05 ETH (test)', true, undefined, report);
      await takeScreenshot(page, personaName, 'test-purchase-complete', report);
      logObservation(personaName, 'Test purchase successful. Now buying more for actual staking.', report);
      
      // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for animation settling, wallet connector UI transitions, and debounced state updates in user-simulation tests. See AGENTS.md #Engineering Principles.
      await page.waitForTimeout(2_000);
      
      // --- Buy enough for staking (split to reduce slippage) ---
      await buyKrk(page, '3.0');
      recordAction('Buy KRK with 3.0 ETH total', true, undefined, report);
      logObservation(personaName, 'Bought more KRK. Now ready to stake.', report);
      
      // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for animation settling, wallet connector UI transitions, and debounced state updates in user-simulation tests. See AGENTS.md #Engineering Principles.
      await page.waitForTimeout(2_000);
      
      // --- Navigate Back to Stake ---
      pageStart = Date.now();
      await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
      // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for animation settling, wallet connector UI transitions, and debounced state updates in user-simulation tests. See AGENTS.md #Engineering Principles.
      await page.waitForTimeout(2_000);
      recordPageVisit('Stake (attempt)', page.url(), pageStart, report);
      
      await takeScreenshot(page, personaName, 'stake-form-before-fill', report);
      logObservation(personaName, 'Examining the stake form - trying to understand tax rate implications', report);
      logCopyFeedback(personaName, 'Tax rate dropdown needs explanation: "What tax rate should I choose?"', report);
      logCopyFeedback(personaName, 'Would love a calculator: "Stake X at Y% tax = Z estimated APY"', report);
      
      // --- Conservative Test Stake (High Tax for Safety) ---
      logObservation(personaName, 'Choosing 15% tax rate to minimize snatch risk - prioritizing safety over yield', report);
      logTokenomicsQuestion(personaName, 'Is 15% tax high enough to prevent snatching? What\'s the meta?', report);
      
      try {
        await attemptStake(page, '50', '15', personaName, report);
        await takeScreenshot(page, personaName, 'conservative-stake-success', report);
        logObservation(personaName, 'Stake successful! Now monitoring to see if position stays secure.', report);
        recordAction('Stake 50 KRK at 15% tax (conservative)', true, undefined, report);
      } catch (error: any) {
        logObservation(personaName, `Stake failed: ${error.message}. This is confusing and frustrating.`, report);
        logCopyFeedback(personaName, 'Error messages need to be clearer and suggest solutions', report);
        await takeScreenshot(page, personaName, 'stake-error', report);
      }
      
      // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for animation settling, wallet connector UI transitions, and debounced state updates in user-simulation tests. See AGENTS.md #Engineering Principles.
      await page.waitForTimeout(3_000);
      
      // --- Check Active Positions ---
      await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
      // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for animation settling, wallet connector UI transitions, and debounced state updates in user-simulation tests. See AGENTS.md #Engineering Principles.
      await page.waitForTimeout(2_000);
      await takeScreenshot(page, personaName, 'checking-my-position', report);
      
      const activePositions = page.locator('.active-positions-wrapper');
      const myPositionVisible = await activePositions.isVisible().catch(() => false);
      
      if (myPositionVisible) {
        logObservation(personaName, 'Can see my active position. Would want notifications when something changes.', report);
        logCopyFeedback(personaName, 'Need mobile notifications or email alerts for position activity (snatch attempts, tax due)', report);
      } else {
        logObservation(personaName, 'Can\'t see my position clearly - where is it? Confusing UX.', report);
        logCopyFeedback(personaName, '"My Positions" section should be more prominent', report);
      }
      
      // --- Compare to Mental Model (Aave) ---
      logObservation(personaName, 'Comparing this to Aave in my head - Aave is simpler but boring...', report);
      logTokenomicsQuestion(personaName, 'Aave gives me 8% on USDC with zero snatch risk. Why should I use this instead?', report);
      logCopyFeedback(personaName, 'Needs a "Why Kraiken?" section comparing to traditional staking/lending', report);
      
      // --- Final Thoughts ---
      // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for animation settling, wallet connector UI transitions, and debounced state updates in user-simulation tests. See AGENTS.md #Engineering Principles.
      await page.waitForTimeout(2_000);
      await takeScreenshot(page, personaName, 'final-review', report);
      
      report.overallSentiment = 'Interested but need more information before committing real funds. The Harberger tax mechanism is intriguing but confusing - I don\'t fully understand how to optimize my tax rate or what happens if I get snatched. UI is clean but lacks educational content for newcomers. Missing: audit badge, return calculator, risk disclosures, comparison to alternatives, mobile notifications. Would need to monitor my test stake for 1-2 weeks before scaling up. Compared to Aave (8% risk-free), this needs to offer 10-15% to justify the complexity and snatch risk. Verdict: Promising but not ready for my main capital yet.';
      
      logObservation(personaName, report.overallSentiment, report);
      
    } finally {
      writeReport('sarah-park', report);
      await context.close();
    }
  });
});
