import { chromium } from 'playwright';
import { execSync } from 'child_process';

const ARCHWEB = 'http://localhost:8080';
const MANAGE = '/home/josie/development/archlinux/archweb/.venv/bin/python /home/josie/development/archlinux/archweb/manage.py';
const KC_USER = 'testdev';
const KC_PASS = 'testpass';
const KC_SUB = 'a135bad2-5164-44bc-a5e9-c6ff4cc21af9';
const DJANGO_USER = 'admin';
const DJANGO_PASS = 'admin';

function django(cmd) {
  return execSync(`${MANAGE} shell -c "${cmd}"`, { encoding: 'utf8' }).trim();
}

function setSsoAccountId(value) {
  const val = value === null ? 'None' : `'${value}'`;
  django(
    `from django.contrib.auth.models import User; from devel.models import UserProfile; ` +
    `p = UserProfile.objects.get(user__username='admin'); p.sso_accountid = ${val}; p.save(); ` +
    `print('sso_accountid set to', p.sso_accountid)`
  );
}

async function sleep(ms) {
  return new Promise(r => setTimeout(r, ms));
}

async function typeIntoRole(page, role, name, text) {
  const el = page.getByRole(role, { name });
  await el.click();
  await sleep(150 + Math.random() * 200);
  await el.pressSequentially(text, { delay: 55 + Math.random() * 40 });
}

async function hoverAndClick(el, pauseMs = 500) {
  await el.hover();
  await sleep(pauseMs + Math.random() * 300);
  await el.click();
}

(async () => {
  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({
    viewport: { width: 1280, height: 800 },
    recordVideo: {
      dir: '/tmp/archweb-demo/raw/',
      size: { width: 1280, height: 800 },
    },
  });

  const page = await context.newPage();

  // =============================================
  // FLOW 1: SSO Login
  // =============================================
  console.log('--- Flow 1: SSO Login ---');

  // Pre-link admin account so SSO login maps to admin user
  setSsoAccountId(KC_SUB);
  console.log('Pre-seeded admin sso_accountid for SSO login demo');

  await page.goto(ARCHWEB + '/login/');
  await sleep(2000);

  // Click "Login with SSO"
  await hoverAndClick(page.getByRole('link', { name: 'Login with SSO' }), 700);
  await page.waitForURL('**/auth.josie.cloud/**');
  await sleep(1500);

  // Type credentials on Keycloak
  await typeIntoRole(page, 'textbox', 'Username or email', KC_USER);
  await sleep(500);
  await typeIntoRole(page, 'textbox', 'Password', KC_PASS);
  await sleep(700);

  // Sign in
  await hoverAndClick(page.getByRole('button', { name: 'Sign In' }), 500);

  // Wait for redirect back to archweb
  await page.waitForURL(ARCHWEB + '/**', { timeout: 15000 });
  await sleep(2000);

  // Show profile page to prove we're logged in and SSO is linked
  await page.goto(ARCHWEB + '/devel/profile/');
  await sleep(1500);
  const linkedText = page.getByText('Linked to SSO.');
  await linkedText.scrollIntoViewIfNeeded();
  await sleep(2500);

  console.log('Flow 1 complete: logged in via SSO');

  // =============================================
  // FLOW 2: SSO Account Linking
  // =============================================
  console.log('--- Flow 2: SSO Account Linking ---');

  // Log out via POST form
  await hoverAndClick(page.locator('input[value="Logout"]'), 600);
  await sleep(1500);

  // Clear the SSO link so we can demo linking
  setSsoAccountId(null);
  console.log('Cleared admin sso_accountid for linking demo');

  // Log in with Django password
  await page.goto(ARCHWEB + '/login/');
  await sleep(1200);

  await typeIntoRole(page, 'textbox', 'Username:', DJANGO_USER);
  await sleep(400);
  await typeIntoRole(page, 'textbox', 'Password:', DJANGO_PASS);
  await sleep(600);

  await hoverAndClick(page.getByRole('button', { name: 'Login' }), 400);
  await page.waitForURL(ARCHWEB + '/**');
  await sleep(1500);

  // Go to profile page to show "Not linked"
  await page.goto(ARCHWEB + '/devel/profile/');
  await sleep(2000);

  // Scroll to SSO section
  const ssoText = page.getByText('Not linked.');
  await ssoText.scrollIntoViewIfNeeded();
  await sleep(1800);

  // Click "Link your SSO account"
  await hoverAndClick(page.getByRole('link', { name: 'Link your SSO account' }), 600);
  await sleep(1500);

  // On link-sso page, click "Link SSO Account"
  await hoverAndClick(page.getByRole('button', { name: 'Link SSO Account' }), 600);

  // Keycloak session might still be active from Flow 1
  await sleep(2000);
  if (page.url().includes('auth.josie.cloud')) {
    console.log('Keycloak login required for linking');
    const kcUser = page.getByRole('textbox', { name: 'Username or email' });
    if (await kcUser.isVisible({ timeout: 3000 }).catch(() => false)) {
      await typeIntoRole(page, 'textbox', 'Username or email', KC_USER);
      await sleep(400);
      await typeIntoRole(page, 'textbox', 'Password', KC_PASS);
      await sleep(500);
      await page.getByRole('button', { name: 'Sign In' }).click();
    }
    await page.waitForURL(ARCHWEB + '/**', { timeout: 15000 });
  }

  await sleep(2500);

  // Show profile page with linked status
  await page.goto(ARCHWEB + '/devel/profile/');
  await sleep(1500);
  const linkedAfterLink = page.getByText('Linked to SSO.');
  await linkedAfterLink.scrollIntoViewIfNeeded();
  await sleep(2500);

  console.log('Flow 2 complete: SSO account linked');

  // =============================================
  // FLOW 3: SSO Account Unlinking
  // =============================================
  console.log('--- Flow 3: SSO Account Unlinking ---');

  // Navigate to link-sso page for unlinking
  await page.goto(ARCHWEB + '/devel/link-sso/');
  await sleep(1500);

  // Click "Unlink SSO Account"
  await hoverAndClick(page.getByRole('button', { name: 'Unlink SSO Account' }), 800);
  await sleep(2500);

  // Show profile page with unlinked status
  await page.goto(ARCHWEB + '/devel/profile/');
  await sleep(1500);
  const unlinkedText = page.getByText('Not linked.');
  await unlinkedText.scrollIntoViewIfNeeded();
  await sleep(2500);

  console.log('Flow 3 complete: SSO account unlinked');

  // Finalize
  await context.close();
  await browser.close();

  console.log('Recording complete. Raw video in /tmp/archweb-demo/raw/');
})();
