import { describe, it, expect, beforeEach, afterAll } from 'vitest';
import Fastify from 'fastify';
import { unlinkSync, existsSync, mkdirSync } from 'node:fs';
import { resolve, dirname } from 'node:path';

const TEST_DB = resolve(process.cwd(), 'data/test-api.db');
process.env.DATABASE_PATH = TEST_DB;
process.env.MAJ_WP_API_KEY = 'test-api-key';
process.env.ADMIN_PASSWORD = 'admin123';
process.env.SESSION_SECRET = 'test';
process.env.NODE_ENV = 'test';

beforeEach(async () => {
  if (existsSync(TEST_DB)) unlinkSync(TEST_DB);
  mkdirSync(dirname(TEST_DB), { recursive: true });
  const { closeDb } = await import('../src/db/index.js');
  closeDb();
});

afterAll(() => {
  if (existsSync(TEST_DB)) unlinkSync(TEST_DB);
});

async function buildTestApp() {
  const { buildApp } = await import('../src/app.js');
  return buildApp();
}

describe('HTTP API', () => {
  it('rejects maj-wp without auth', async () => {
    const app = await buildTestApp();
    const res = await app.inject({ method: 'GET', url: '/api/v1/tickets/ready' });
    expect(res.statusCode).toBe(401);
    await app.close();
  });

  it('rejects extension ingest without token', async () => {
    const app = await buildTestApp();
    const res = await app.inject({
      method: 'POST',
      url: '/api/extension/ingest',
      payload: {
        source_type: 'monday_chrome',
        source_external_id: 'x',
        title: 'T',
      },
    });
    expect(res.statusCode).toBe(401);
    await app.close();
  });

  it('rejects invalid extension payload', async () => {
    const app = await buildTestApp();
    const { extensionAuthService } = await import('../src/services/intake.service.js');
    const { code } = extensionAuthService.createPairingCode();
    const paired = extensionAuthService.redeemPairingCode(code)!;

    const res = await app.inject({
      method: 'POST',
      url: '/api/extension/ingest',
      headers: { authorization: `Bearer ${paired.token}` },
      payload: { source_type: 'monday_chrome', source_external_id: 'x', title: '' },
    });
    expect(res.statusCode).toBe(400);
    await app.close();
  });

  it('full maj-wp flow via HTTP', async () => {
    const app = await buildTestApp();
    const { intakeService } = await import('../src/services/intake.service.js');

    const { item } = intakeService.ingest({
      source_type: 'demo',
      source_external_id: 'http-flow-1',
      title: 'HTTP flow',
    });
    intakeService.approve(item.id);

    const ready = await app.inject({
      method: 'GET',
      url: '/api/v1/tickets/ready',
      headers: { authorization: 'Bearer test-api-key' },
    });
    expect(ready.statusCode).toBe(200);
    expect(ready.json().count).toBeGreaterThan(0);

    const claim = await app.inject({
      method: 'POST',
      url: `/api/v1/intake/${item.id}/claim`,
      headers: { authorization: 'Bearer test-api-key' },
      payload: { consumer_id: 'maj-wp-test' },
    });
    expect(claim.statusCode).toBe(200);
    const claimToken = claim.json().claim_token;

    const created = await app.inject({
      method: 'POST',
      url: `/api/v1/intake/${item.id}/created`,
      headers: { authorization: 'Bearer test-api-key' },
      payload: {
        claim_token: claimToken,
        maj_wp_ticket_id: 'WP-HTTP-1',
        remote_status: 'new',
      },
    });
    expect(created.statusCode).toBe(200);

    const again = await app.inject({
      method: 'POST',
      url: `/api/v1/intake/${item.id}/created`,
      headers: { authorization: 'Bearer test-api-key' },
      payload: { maj_wp_ticket_id: 'WP-HTTP-1' },
    });
    expect(again.statusCode).toBe(200);
    expect(again.json().idempotent).toBe(true);

    await app.close();
  });
});
