/**
 * Smoke suite — API
 *
 * Runs after every deploy to verify core API paths are healthy.
 * Tests are tagged with @smoke so they can be isolated:
 *
 *   npx playwright test --project=api --grep @smoke
 *
 * Intentionally lightweight: each test makes at most one API call and
 * asserts only on status code + structural shape.  No heavy fixtures,
 * no side effects that require cleanup.
 */
import { test, expect } from '@playwright/test';
import { createTestUser, registerUser } from '../fixtures';

// ── Health ────────────────────────────────────────────────────────────────────

test('@smoke API health check returns 200', async ({ request }) => {
  // Playwright baseURL ends with /api/v1/ — health is at the root
  const res = await request.get('../../health');
  expect(res.status()).toBe(200);
  const body = await res.json();
  expect(body.status).toBe('ok');
});

// ── Auth ──────────────────────────────────────────────────────────────────────

test('@smoke auth register + login roundtrip', async ({ request }) => {
  const user = createTestUser();
  const registered = await registerUser(request, user);

  expect(registered).toHaveProperty('accessToken');
  expect(registered).toHaveProperty('refreshToken');
  expect(typeof registered.accessToken).toBe('string');

  const loginRes = await request.post('auth/login', {
    data: { phone: user.phone, password: user.password },
  });
  expect(loginRes.status()).toBe(201);
  const tokens = await loginRes.json();
  expect(tokens).toHaveProperty('accessToken');
});

test('@smoke auth token refresh', async ({ request }) => {
  const user = createTestUser();
  const { refreshToken } = await registerUser(request, user);

  const res = await request.post('auth/refresh', {
    data: { refreshToken },
  });
  expect(res.status()).toBe(201);
  const body = await res.json();
  expect(body).toHaveProperty('accessToken');
});

test('@smoke protected route rejects unauthenticated request', async ({ request }) => {
  const res = await request.get('auth/profile');
  expect([401, 403]).toContain(res.status());
});

// ── Listings ─────────────────────────────────────────────────────────────────

test('@smoke listings list returns paginated results', async ({ request }) => {
  const res = await request.get('listings', {
    params: { page: 1, limit: 5 },
  });
  expect(res.status()).toBe(200);
  const body = await res.json();
  expect(body).toHaveProperty('data');
  expect(Array.isArray(body.data)).toBeTruthy();
  expect(body).toHaveProperty('meta');
});

test('@smoke listing creation requires auth', async ({ request }) => {
  const res = await request.post('listings', {
    data: { title: 'Smoke test listing' },
  });
  expect([401, 403]).toContain(res.status());
});

// ── Search ────────────────────────────────────────────────────────────────────

test('@smoke search endpoint is reachable', async ({ request }) => {
  const res = await request.get('search', {
    params: { q: 'apartment', limit: 5 },
  });
  // 200 = Typesense available; 500/503 = service unavailable (accepted in smoke)
  expect([200, 500, 503]).toContain(res.status());
});

test('@smoke geo search endpoint is reachable', async ({ request }) => {
  const res = await request.get('search/geo', {
    params: { lat: 10.7769, lng: 106.7009, radius: 5000, limit: 5 },
  });
  expect([200, 500, 503]).toContain(res.status());
});

// ── Payments ──────────────────────────────────────────────────────────────────

test('@smoke payment initiation requires auth', async ({ request }) => {
  const res = await request.post('payments', {
    data: { amount: 100000, gateway: 'VNPAY' },
  });
  expect([401, 403]).toContain(res.status());
});

// ── Subscriptions ─────────────────────────────────────────────────────────────

test('@smoke subscription plans are publicly readable', async ({ request }) => {
  const res = await request.get('subscriptions/plans');
  expect(res.status()).toBe(200);
  const body = await res.json();
  expect(Array.isArray(body)).toBeTruthy();
});

// ── Inquiries ─────────────────────────────────────────────────────────────────

test('@smoke inquiry creation requires auth', async ({ request }) => {
  const res = await request.post('inquiries', {
    data: { listingId: 'smoke-listing-id', message: 'Smoke test inquiry' },
  });
  expect([401, 403]).toContain(res.status());
});
