import 'dotenv/config';
import { test, expect } from '@playwright/test';
import { promises as fs } from 'fs';

import { login, apiHeaders, getPortId } from '../smoke/helpers';

/**
 * Real-API receipt OCR coverage. Two-step:
 *
 *   1. Admin save + test-connection round-trip: writes a real OpenAI key
 *      to the global OCR config, calls /admin/ocr-settings/test (which
 *      sends a 1×1 pixel PNG - essentially free in tokens), and asserts
 *      the provider responds 2xx. Validates the auth + key-storage path.
 *
 *   2. Real receipt parse: when REALAPI_RECEIPT_FIXTURE is set to an
 *      image on disk, POSTs it to /api/v1/expenses/scan-receipt and
 *      asserts the parsed payload looks plausible (numeric amount >= 0,
 *      non-empty parsed.confidence).
 *
 * Both tests skip when OPENAI_API_KEY isn't set so the suite remains
 * CI-safe by default.
 */

const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
const RECEIPT_FIXTURE = process.env.REALAPI_RECEIPT_FIXTURE;

test.describe('Receipt OCR - real provider', () => {
  test.skip(!OPENAI_API_KEY, 'OPENAI_API_KEY not configured');

  test('admin can save an OpenAI key and the test endpoint passes', async ({ page }) => {
    await login(page, 'super_admin');
    const headers = await apiHeaders(page);

    // Save a global OCR config with the real key. Super-admin only.
    const saveRes = await page.request.put('/api/v1/admin/ocr-settings', {
      headers,
      data: {
        scope: 'global',
        provider: 'openai',
        model: 'gpt-4o-mini',
        apiKey: OPENAI_API_KEY,
      },
    });
    expect(saveRes.ok()).toBeTruthy();

    const testRes = await page.request.post('/api/v1/admin/ocr-settings/test', {
      headers,
      data: {
        provider: 'openai',
        model: 'gpt-4o-mini',
        apiKey: OPENAI_API_KEY,
      },
    });
    expect(testRes.ok()).toBeTruthy();
    const body = (await testRes.json()) as { ok: boolean; reason?: string };
    expect(body.ok).toBe(true);

    // Cleanup: clear the global key so subsequent test runs don't accidentally
    // bill the same OpenAI account if someone forgets to unset it.
    const cleanupRes = await page.request.put('/api/v1/admin/ocr-settings', {
      headers,
      data: {
        scope: 'global',
        provider: 'openai',
        model: 'gpt-4o-mini',
        clearApiKey: true,
      },
    });
    expect(cleanupRes.ok()).toBeTruthy();
  });

  test('scan-receipt endpoint returns a parsed payload for a real image', async ({ page }) => {
    test.skip(!RECEIPT_FIXTURE, 'REALAPI_RECEIPT_FIXTURE not set');

    await login(page, 'super_admin');
    const portId = await getPortId(page);

    // Configure the per-port OCR with the test key for the duration of this run.
    await page.request.put('/api/v1/admin/ocr-settings', {
      headers: { 'Content-Type': 'application/json', 'X-Port-Id': portId },
      data: {
        scope: 'port',
        provider: 'openai',
        model: 'gpt-4o-mini',
        apiKey: OPENAI_API_KEY,
      },
    });

    const buffer = await fs.readFile(RECEIPT_FIXTURE!);
    const res = await page.request.post('/api/v1/expenses/scan-receipt', {
      headers: { 'X-Port-Id': portId },
      multipart: {
        file: {
          name: 'receipt.jpg',
          mimeType: 'image/jpeg',
          buffer,
        },
      },
    });
    expect(res.ok()).toBeTruthy();
    const body = (await res.json()) as {
      data: {
        parsed: {
          amount: number | null;
          confidence: number;
          establishment: string | null;
          date: string | null;
        };
        source: 'ai' | 'manual';
      };
    };
    expect(body.data.source).toBe('ai');
    // Confidence must be a valid number 0..1 - provider should always emit it.
    expect(body.data.parsed.confidence).toBeGreaterThanOrEqual(0);
    expect(body.data.parsed.confidence).toBeLessThanOrEqual(1);
    // Amount, if present, should be non-negative.
    if (body.data.parsed.amount !== null) {
      expect(body.data.parsed.amount).toBeGreaterThanOrEqual(0);
    }

    // Cleanup
    await page.request.put('/api/v1/admin/ocr-settings', {
      headers: { 'Content-Type': 'application/json', 'X-Port-Id': portId },
      data: {
        scope: 'port',
        provider: 'openai',
        model: 'gpt-4o-mini',
        clearApiKey: true,
      },
    });
  });
});
