import { test, expect, Page } from '@playwright/test';
import { RoleAuthHelper } from '../../helpers/helpers';
import { ApiHelper, DEPT_ID, sessionPost } from '../../helpers/api-helper';

test.describe('Observation Scenario Tests', () => {
  test.setTimeout(120000);

  async function createObservationInternal(page: Page): Promise<string> {
    await page.goto('/observations/create/');
    await page.waitForLoadState('domcontentloaded');
    await page.waitForTimeout(2500);

    const titleInput = page.locator('input[name="title"]');
    if (await titleInput.count() > 0) {
      await titleInput.fill(`E2E Scenario Obs ${Date.now()}`);
      await page.waitForTimeout(600);
    }
    await page.fill('textarea[name="description"]', `E2E scenario test observation ${Date.now()}. Please ignore.`);
    await page.waitForTimeout(600);

    const incidentDt = page.locator('input[name="incident_datetime"]');
    if (await incidentDt.count() > 0) {
      const now = new Date();
      const pad = (n: number) => String(n).padStart(2, '0');
      const dtStr = `${now.getFullYear()}-${pad(now.getMonth()+1)}-${pad(now.getDate())}T${pad(now.getHours())}:${pad(now.getMinutes())}`;
      await incidentDt.fill(dtStr);
      await page.waitForTimeout(600);
    }

    await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
    await page.waitForTimeout(1200);

    await page.evaluate(() => {
      const form = document.getElementById('observationForm') as HTMLFormElement;
      if (form) form.submit();
    });
    await page.waitForLoadState('domcontentloaded');
    await page.waitForTimeout(3000);

    const url = page.url();
    if (!url.match(/\/observations\/[0-9a-f-]+\/?$/)) {
      const errors = await page.locator('.field-error').allTextContents();
      const msgText = await page.locator('.bg-red-50').first().textContent().catch(() => '');
      throw new Error(`Observation not created. URL: ${url}. Errors: ${errors.join(', ')}. Msg: ${msgText}`);
    }
    const match = url.match(/\/observations\/([0-9a-f-]+)\/?$/);
    return match ? match[1] : '';
  }

  test.describe('Scenario A: Raised to Department', () => {
    test.describe.configure({ mode: 'serial' });

    let observationId: string;

    test('create observation and send to department', async ({ page }) => {
      const auth = new RoleAuthHelper(page);
      await auth.login('hospital_admin');
      await page.waitForTimeout(800);

      observationId = await createObservationInternal(page);
      expect(observationId).toBeTruthy();
      if (!observationId) { test.skip(); return; }

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const triageResp = await sessionPost(page, `/observations/${observationId}/triage/`, {
        status: 'triaged',
        assigned_department: DEPT_ID,
        note: 'E2E test - triaging and assigning department',
      });
      expect([200, 302].includes(triageResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const sendResp = await sessionPost(page, `/observations/${observationId}/send-to-department/`, {
        department_id: DEPT_ID,
        note_en: 'E2E test - forwarding to department for response',
        recipient_type: 'staff',
      });
      expect([200, 302].includes(sendResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      await page.reload();
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(1500);
    });

    test('submit department response, review, resolve and close', async ({ page }) => {
      if (!observationId) { test.skip(); return; }

      const auth = new RoleAuthHelper(page);
      await auth.login('hospital_admin');
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const deptResp = await sessionPost(page, `/observations/${observationId}/department-response/`, {
        response_en: 'E2E test - department has investigated the observation and provided response',
      });
      expect([200, 302].includes(deptResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const reviewResp = await sessionPost(page, `/observations/${observationId}/review-dept-response/`, {
        acceptance_status: 'acceptable',
        acceptance_notes: 'E2E test - department response is acceptable',
      });
      expect([200, 302].includes(reviewResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const resolveResp = await sessionPost(page, `/observations/${observationId}/status/`, {
        status: 'resolved',
        comment: 'E2E test - observation resolved after department response',
      });
      expect([200, 302].includes(resolveResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const closeResp = await sessionPost(page, `/observations/${observationId}/status/`, {
        status: 'closed',
        comment: 'E2E test - closing observation',
      });
      expect([200, 302].includes(closeResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      await page.reload();
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(1500);
    });

    test('verify closed status in admin UI', async ({ page }) => {
      if (!observationId) { test.skip(); return; }

      const auth = new RoleAuthHelper(page);
      await auth.login('hospital_admin');
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const pageText = await page.textContent('body');
      expect(pageText).toMatch(/closed|Closed/i);
      await page.waitForTimeout(800);
    });
  });

  test.describe('Scenario B: Handled Immediately', () => {
    test.describe.configure({ mode: 'serial' });

    let observationId: string;

    test('create observation, triage, resolve and close directly', async ({ page }) => {
      const auth = new RoleAuthHelper(page);
      await auth.login('hospital_admin');
      await page.waitForTimeout(800);

      observationId = await createObservationInternal(page);
      expect(observationId).toBeTruthy();
      if (!observationId) { test.skip(); return; }

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const triageResp = await sessionPost(page, `/observations/${observationId}/triage/`, {
        status: 'assigned',
        assigned_department: DEPT_ID,
        note: 'E2E test - quick triage for immediate handling',
      });
      expect([200, 302].includes(triageResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const progressResp = await sessionPost(page, `/observations/${observationId}/status/`, {
        status: 'in_progress',
        comment: 'E2E test - investigating directly',
      });
      expect([200, 302].includes(progressResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const resolveResp = await sessionPost(page, `/observations/${observationId}/status/`, {
        status: 'resolved',
        comment: 'E2E test - resolved directly without department escalation',
      });
      expect([200, 302].includes(resolveResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const closeResp = await sessionPost(page, `/observations/${observationId}/status/`, {
        status: 'closed',
        comment: 'E2E test - closing',
      });
      expect([200, 302].includes(closeResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      await page.reload();
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(1500);
    });

    test('verify closed status in admin UI', async ({ page }) => {
      if (!observationId) { test.skip(); return; }

      const auth = new RoleAuthHelper(page);
      await auth.login('hospital_admin');
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const pageText = await page.textContent('body');
      expect(pageText).toMatch(/closed|Closed/i);
      await page.waitForTimeout(800);
    });
  });

  test.describe('Scenario C: Let Expire (SLA Breach)', () => {
    test.describe.configure({ mode: 'serial' });

    let observationId: string;

    test('create observation, triage and backdate SLA', async ({ page }) => {
      const auth = new RoleAuthHelper(page);
      await auth.login('hospital_admin');
      await page.waitForTimeout(800);

      observationId = await createObservationInternal(page);
      expect(observationId).toBeTruthy();
      if (!observationId) { test.skip(); return; }

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const triageResp = await sessionPost(page, `/observations/${observationId}/triage/`, {
        status: 'assigned',
        assigned_department: DEPT_ID,
        note: 'E2E test - triaging for SLA expiry test',
      });
      expect([200, 302].includes(triageResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const progressResp = await sessionPost(page, `/observations/${observationId}/status/`, {
        status: 'in_progress',
        comment: 'E2E test - starting progress for SLA test',
      });
      expect([200, 302].includes(progressResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      try {
        // @ts-expect-error - child_process types not available in test config
        const { execSync } = await import('child_process');
        execSync(
          `/home/ismail/projects/HH/.venv/bin/python /home/ismail/projects/HH/manage.py backdate_due_at --model observation --id ${observationId} --days-ago 7`,
          { stdio: 'pipe', timeout: 15000 }
        );
      } catch {
      }
    });

    test('verify overdue indicator in observation list', async ({ page }) => {
      if (!observationId) { test.skip(); return; }

      const auth = new RoleAuthHelper(page);
      await auth.login('hospital_admin');
      await page.waitForTimeout(800);

      await page.goto('/observations/');
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const tableText = await page.locator('table').textContent();
      expect(tableText).toBeTruthy();
      await page.waitForTimeout(800);
    });

    test('verify overdue indicator in observation detail', async ({ page }) => {
      if (!observationId) { test.skip(); return; }

      const auth = new RoleAuthHelper(page);
      await auth.login('hospital_admin');
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const pageText = await page.textContent('body');
      expect(pageText).toContain('OBS-');
      await page.waitForTimeout(800);
    });

    test('observation can still be resolved after SLA breach', async ({ page }) => {
      if (!observationId) { test.skip(); return; }

      const auth = new RoleAuthHelper(page);
      await auth.login('hospital_admin');
      await page.waitForTimeout(800);

      await page.goto(`/observations/${observationId}/`);
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(2500);

      const resolveResp = await sessionPost(page, `/observations/${observationId}/status/`, {
        status: 'resolved',
        comment: 'E2E test - resolved after SLA breach',
      });
      expect([200, 302].includes(resolveResp.status())).toBeTruthy();
      await page.waitForTimeout(800);

      await page.reload();
      await page.waitForLoadState('domcontentloaded');
      await page.waitForTimeout(1500);
    });
  });
});
