import { writeFileSync } from 'fs';
import { getPage } from './browse.js';

const baseUrl = 'http://localhost:3000';
const username = 'analyst@fhb.local';
const password = process.env.CLOAKBROWSER_PASSWORD ?? '';

const reportPath = '/Users/stefano.fiorini/Documents/projects/fhb-loan-spreading-pilot-a/docs/plans/2026-01-24-financials-analysis-redesign/web-automation-scan.md';

type NavResult = {
  requestedUrl: string;
  url: string;
  status: number | null;
  title: string;
  error?: string;
};

async function gotoWithStatus(page: any, url: string): Promise<NavResult> {
  const resp = await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 }).catch((e: unknown) => ({ error: e }));
  if (resp?.error) {
    return {
      requestedUrl: url,
      url: page.url(),
      status: null,
      title: await page.title().catch(() => ''),
      error: String(resp.error),
    };
  }

  return {
    requestedUrl: url,
    url: page.url(),
    status: resp ? resp.status() : null,
    title: await page.title().catch(() => ''),
  };
}

async function textOrNull(page: any, selector: string): Promise<string | null> {
  const loc = page.locator(selector).first();
  try {
    if ((await loc.count()) === 0) return null;
    const txt = await loc.textContent();
    return txt ? txt.trim().replace(/\s+/g, ' ') : null;
  } catch {
    return null;
  }
}

async function main() {
  const { page, browser } = await getPage({ headless: true });
  const lines: string[] = [];

  lines.push('# Web Automation Scan (local)');
  lines.push('');
  lines.push(`- Base URL: ${baseUrl}`);
  lines.push(`- Timestamp: ${new Date().toISOString()}`);
  lines.push('');

  try {
    lines.push('## Login');
    await gotoWithStatus(page, `${baseUrl}/login`);
    await page.locator('input[name="email"]').fill(username);
    await page.locator('input[name="password"]').fill(password);
    await page.locator('button[type="submit"]').click();
    await page.waitForTimeout(2500);

    const cookies = await page.context().cookies();
    const sessionCookie = cookies.find((c: any) => c.name === 'fhb_session');
    lines.push(`- After submit URL: ${page.url()}`);
    lines.push(`- Has session cookie (fhb_session): ${Boolean(sessionCookie)}`);
    lines.push('');

    lines.push('## Demo Case');
    const casesNav = await gotoWithStatus(page, `${baseUrl}/cases`);
    lines.push(`- GET /cases → status ${casesNav.status ?? 'ERR'}, final ${casesNav.url}`);

    const envCaseId = process.env.SCAN_CASE_ID?.trim() || null;
    let selectedCaseId: string | null = envCaseId;

    if (!selectedCaseId) {
      const caseLinks = await page.$$eval('a[href^="/cases/"]', (as) =>
        as
          .map((a) => ({
            href: (a as HTMLAnchorElement).getAttribute('href') || '',
            text: (a.textContent || '').trim(),
          }))
          .filter((x) => x.href.includes('/cases/'))
      );

      const preferredTitles = ['Demo - Strong Borrower', 'Demo - Weak Borrower', 'Demo - Incomplete'];
      for (const title of preferredTitles) {
        const match = caseLinks.find((l) => l.text.includes(title) && l.href.includes('/cases/'));
        const href = match?.href ?? '';
        const m = href.match(/\/cases\/([0-9a-f-]{36})/i);
        if (m) {
          selectedCaseId = m[1];
          break;
        }
      }

      if (!selectedCaseId) {
        const firstHref =
          caseLinks.map((l) => l.href).find((h) => /\/cases\/[0-9a-f-]{36}/i.test(h)) ?? null;
        const m = firstHref?.match(/\/cases\/([0-9a-f-]{36})/i) ?? null;
        selectedCaseId = m?.[1] ?? null;
      }
    }

    lines.push(`- Selected caseId: ${selectedCaseId ?? '(none found)'}`);

    if (!selectedCaseId) {
      lines.push('');
      lines.push('⚠️ Could not find a demo case link on /cases.');
      writeFileSync(reportPath, lines.join('\n') + '\n', 'utf-8');
      return;
    }

    const caseBase = `${baseUrl}/cases/${selectedCaseId}/journey`;

    lines.push('');
    lines.push('## Route Checks');

    const routesToCheck = [
      `${caseBase}`,
      `${caseBase}/financials`,
      `${caseBase}/financials/income`,
      `${caseBase}/analysis`,
      `${caseBase}/analysis/configure`,
      `${caseBase}/analysis/ai`,
      `${caseBase}/analysis/ai/detail`,
      `${caseBase}/spreads`,
    ];

    for (const url of routesToCheck) {
      const r = await gotoWithStatus(page, url);
      const h1 = await textOrNull(page, 'h1');
      const finalPath = r.url.startsWith(baseUrl) ? r.url.slice(baseUrl.length) : r.url;
      lines.push(`- ${url.slice(baseUrl.length)} → status ${r.status ?? 'ERR'} (final ${finalPath})${h1 ? `, h1="${h1}"` : ''}`);
    }

    lines.push('');
    lines.push('## Spreadsheet Analysis (UI)');
    await gotoWithStatus(page, `${caseBase}/analysis/configure`);

    const runButton = page.locator('button:has-text("Run Analysis")').first();
    const disabled = await runButton.isDisabled().catch(() => true);
    lines.push(`- Run button disabled: ${disabled}`);

    if (!disabled) {
      await runButton.click();

      const resultsWait = page
        .waitForURL('**/journey/analysis/results**', { timeout: 180000 })
        .then(() => 'results' as const);
      const errorWait = page
        .locator('[role="alert"]')
        .filter({ hasText: 'Error' })
        .first()
        .waitFor({ timeout: 180000 })
        .then(() => 'error' as const);

      const outcome = await Promise.race([resultsWait, errorWait]).catch(() => 'timeout' as const);

      if (outcome === 'results') {
        await page.waitForTimeout(1500);
        lines.push(`- Results URL: ${page.url().replace(baseUrl, '')}`);

        const downloadHref = await page
          .locator('a[href*="/journey/analysis/download"]')
          .first()
          .getAttribute('href')
          .catch(() => null);

        if (downloadHref) {
          const dlUrl = downloadHref.startsWith('http') ? downloadHref : `${baseUrl}${downloadHref}`;
          const dlResp = await page.goto(dlUrl, { waitUntil: 'commit', timeout: 60000 }).catch(() => null);
          lines.push(
            `- Download route status: ${dlResp?.status() ?? 'ERR'} (Content-Type: ${dlResp?.headers()?.['content-type'] ?? 'n/a'})`
          );
        } else {
          lines.push('- Download link not found on results page');
        }
      } else if (outcome === 'error') {
        const errorText = await page
          .locator('[role="alert"]')
          .first()
          .textContent()
          .then((t: string | null) => (t ? t.trim().replace(/\\s+/g, ' ') : null))
          .catch(() => null);
        lines.push(`- Stayed on configure page; saw error callout: ${errorText ?? '(unable to read)'}`);
        lines.push('- Skipping download check because analysis did not complete.');
      } else {
        lines.push('- Timed out waiting for results or error after clicking Run Analysis.');
      }
    } else {
      lines.push('- Skipped running analysis because Run button was disabled.');
    }

    lines.push('');
    lines.push('## Notes');
    lines.push('- This scan avoids scraping financial values; it records route availability and basic headings.');

    writeFileSync(reportPath, lines.join('\n') + '\n', 'utf-8');
  } finally {
    await browser.close();
  }
}

main().catch((err) => {
  console.error(err);
  process.exitCode = 1;
});
