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

test.describe('JWT Authentication', () => {
  test('obtain JWT token pair', async ({ page }) => {
    const resp = await page.request.post('/accounts/token/', {
      data: {
        email: 'e2e-hospital-admin@px360.test',
        password: 'Dev@123456',
      },
    });
    expect(resp.status()).toBe(200);
    const body = await resp.json();
    expect(body.access).toBeTruthy();
    expect(body.refresh).toBeTruthy();
  });

  test('reject invalid credentials', async ({ page }) => {
    const resp = await page.request.post('/accounts/token/', {
      data: {
        email: 'invalid@test.com',
        password: 'wrongpass',
      },
    });
    expect(resp.status()).toBe(401);
  });

  test('access protected API with valid JWT', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

    const resp = await api.get('/accounts/users/me/');
    expect(resp.status()).toBe(200);
    const body = await resp.json();
    expect(body.email).toBe('e2e-hospital-admin@px360.test');
  });

  test('access protected API with no token returns 401', async ({ page }) => {
    const resp = await page.request.get('/complaints/api/complaints/');
    expect(resp.status()).toBe(401);
  });

  test('refresh token works', async ({ page }) => {
    const resp = await page.request.post('/accounts/token/', {
      data: {
        email: 'e2e-hospital-admin@px360.test',
        password: 'Dev@123456',
      },
    });
    const body = await resp.json();

    const refreshResp = await page.request.post('/accounts/token/refresh/', {
      data: { refresh: body.refresh },
    });
    expect(refreshResp.status()).toBe(200);
    const refreshBody = await refreshResp.json();
    expect(refreshBody.access).toBeTruthy();
  });

  test('PX Admin can create user via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('px_admin');

    const resp = await api.get('/accounts/users/');
    expect(resp.status()).toBe(200);
    const body = await resp.json();
    expect(Array.isArray(body.results || body)).toBeTruthy();
  });

  test('Hospital Admin cannot create user via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

    const resp = await api.post('/accounts/users/', {
      email: 'e2e-blocked@test.com',
      password: 'Test@123456',
    });
    expect(resp.status()).toBe(403);
  });
});

test.describe('Critical API Endpoints', () => {
  test('list complaints with JWT returns data', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

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

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

    const { response, body } = await api.createComplaint();
    expect([201, 400]).toContain(response.status());
    if (response.status() === 201) {
      expect(body.reference_number).toMatch(/^CMP-/);
    }
  });

  test('get complaint detail via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

    const listResp = await api.get('/complaints/api/complaints/?page_size=1');
    const listBody = await listResp.json();
    const results = listBody.results || listBody;
    if (results.length === 0) {
      test.skip();
      return;
    }

    const pk = results[0].id;
    const detailResp = await api.get(`/complaints/api/complaints/${pk}/`);
    expect(detailResp.status()).toBe(200);
    const detail = await detailResp.json();
    expect(detail.id).toBe(pk);
  });

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

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

  test('list hospitals respects permissions', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

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

  test('list survey instances via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

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

  test('list PX actions via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

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

  test('survey analytics engagement stats via API', async ({ page }) => {
    const api = new ApiHelper(page);
    await api.authenticate('hospital_admin');

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

  test('list physicians 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);
  });

  test('standards API returns data (known isolation gap)', 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);
  });
});

test.describe('Public Endpoint Security', () => {
  test('API docs accessible without auth', async ({ page }) => {
    const resp = await page.request.get('/api/docs/');
    expect(resp.status()).toBe(200);
  });

  test('public complaint submit endpoint exists', async ({ page }) => {
    await page.goto('/complaints/public/submit/');
    await page.waitForLoadState('domcontentloaded');
    await page.waitForSelector('#public_complaint_form, form', { timeout: 10000 });
    expect(true).toBeTruthy();
  });

  test('invalid survey token handled gracefully', async ({ page }) => {
    const resp = await page.request.get('/surveys/s/invalid-token/');
    expect(resp.status()).not.toBe(500);
  });

  test('location dropdowns are public', async ({ page }) => {
    const resp = await page.request.get('/organizations/locations/');
    expect([200, 404]).toContain(resp.status());
  });

  test('API schema is accessible', async ({ page }) => {
    const resp = await page.request.get('/api/schema/');
    expect([200, 404, 500]).toContain(resp.status());
  });

  test('simulator health endpoint is public', async ({ page }) => {
    const resp = await page.request.get('/api/simulator/health/');
    expect(resp.status()).toBe(200);
  });
});
