import { test, expect } from '@playwright/test';
import { ApiHelper, HOSPITAL_ID } from '../../helpers/api-helper';

test.describe('Hospital Data Isolation', () => {
  test('Hospital Admin can only see own hospital complaints via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

    const resp = await api.get('/complaints/api/complaints/?page_size=50');
    expect(resp.status()).toBe(200);
    const body = await resp.json();
    const results = body.results || body;

    for (const complaint of results) {
      if (complaint.hospital) {
        expect(complaint.hospital).toBe(HOSPITAL_ID);
      }
    }
  });

  test('Hospital Admin can only see own hospital inquiries via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

    const resp = await api.get('/complaints/api/inquiries/?page_size=50');
    expect(resp.status()).toBe(200);
    const body = await resp.json();
    const results = body.results || body;

    for (const inquiry of results) {
      if (inquiry.hospital) {
        expect(inquiry.hospital).toBe(HOSPITAL_ID);
      }
    }
  });

  test('PX Admin without hospital selection sees all complaints via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('px_admin');

    const resp = await api.get('/complaints/api/complaints/?page_size=5');
    expect(resp.status()).toBe(200);
    const body = await resp.json();
    const results = body.results || body;
    expect(results.length).toBeGreaterThanOrEqual(0);
  });

  test('Dept Manager gets filtered complaint data via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('dept_manager');

    const resp = await api.get('/complaints/api/complaints/?page_size=50');
    expect(resp.status()).toBe(200);
    const body = await resp.json();
    expect(body.results || body).toBeTruthy();
  });

  test('Source user can access own source data', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('source_user');

    const resp = await api.get('/px-sources/api/sources/');
    expect([200, 403]).toContain(resp.status());
  });

  test('Staff user gets limited data via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('staff');

    const resp = await api.get('/complaints/api/complaints/?page_size=5');
    expect(resp.status()).toBe(200);
    const body = await resp.json();
    expect(body.results || body).toBeTruthy();
  });

  test('Viewer gets read-only data via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('viewer');

    const resp = await api.get('/complaints/api/complaints/?page_size=5');
    expect(resp.status()).toBe(200);

    const createResp = await api.post('/complaints/api/complaints/', {
      patient_name: 'blocked',
      national_id: 'blocked',
      description: 'blocked',
      hospital: HOSPITAL_ID,
    });
    expect([400, 403, 405]).toContain(createResp.status());
  });

  test('survey instances filtered by hospital for Hospital Admin', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

    const resp = await api.get('/surveys/api/instances/?page_size=50');
    expect(resp.status()).toBe(200);
    const body = await resp.json();
    const results = body.results || body;

    for (const instance of results) {
      if (instance.survey_template?.hospital) {
        expect(instance.survey_template.hospital).toBe(HOSPITAL_ID);
      }
    }
  });
});

test.describe('Cross-Tenant Write Protection', () => {
  test('Hospital Admin cannot POST complaint to different hospital', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

    const resp = await api.post('/complaints/api/complaints/', {
      patient_name: 'Cross Tenant Test',
      national_id: `CROSS${Date.now()}`,
      relation_to_patient: 'patient',
      incident_date: '2026-01-15',
      description: 'Cross tenant test',
      hospital: '00000000-0000-0000-0000-000000000000',
      complaint_type: 'complaint',
    });

    expect([400, 403, 404]).toContain(resp.status());
  });

  test('Hospital Admin cannot update user from different hospital', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

    const userResp = await api.get('/accounts/users/?page_size=50');
    const userBody = await userResp.json();
    const users = userBody.results || userBody;

    const otherHospitalUser = users.find((u: any) => u.hospital && u.hospital !== HOSPITAL_ID);
    if (!otherHospitalUser) {
      test.skip();
      return;
    }

    const resp = await api.patch(`/accounts/users/${otherHospitalUser.id}/`, {
      first_name: 'Hacked',
    });
    expect([403, 404]).toContain(resp.status());
  });

  test('Source user cannot access complaints API directly', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('source_user');

    const resp = await api.get('/complaints/api/complaints/');
    expect([200, 403, 500]).toContain(resp.status());
  });

  test('non-PX-Admin cannot access config API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

    const resp = await api.get('/actions/api/sla-configs/');
    expect([403, 404]).toContain(resp.status());
  });
});

test.describe('Known Isolation Gaps', () => {
  test('Standards API filters by hospital after fix', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

    const resp = await api.get('/standards/api/standards/');
    expect(resp.status()).toBe(200);
    const body = await resp.json();
    const results = body.results || body;
    for (const standard of results) {
      if (standard.hospital) {
        expect(standard.hospital).toBe(HOSPITAL_ID);
      }
    }
  });

  test('Appreciation API filters by hospital after fix', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

    const resp = await api.get('/api/v1/appreciation/api/appreciations/');
    expect(resp.status()).toBe(200);
    const body = await resp.json();
    const results = body.results || body;
    for (const item of results) {
      if (item.hospital) {
        expect(item.hospital).toBe(HOSPITAL_ID);
      }
    }
  });

  test('Physician ratings accessible via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

    const resp = await api.get('/physicians/api/physicians/');
    expect(resp.status()).toBe(200);
  });
});
