import { randomUUID } from 'node:crypto';
import { createToken } from './auth';
import { pool } from './db';

const apiUrl = process.env.SMOKE_API_URL ?? 'http://127.0.0.1:4000/api';
const firstId = randomUUID();
const secondId = randomUUID();
const requestId = randomUUID();
const journeyId = randomUUID();
const suffix = randomUUID().slice(0, 8);

const assert: (condition: unknown, message: string) => asserts condition = (condition, message) => {
  if (!condition) throw new Error(message);
};

const run = async (): Promise<void> => {
  try {
    await pool.query(
      `INSERT INTO users (id,email,password_hash,display_name,role,account_type)
       VALUES ($1,$2,'test','أحمد منصور','user','candidate'),
              ($3,$4,'test','مريم خالد','user','candidate')`,
      [firstId, `certificate-groom-${suffix}@test.invalid`, secondId,
        `certificate-bride-${suffix}@test.invalid`],
    );
    await pool.query(
      `INSERT INTO profiles (user_id,display_name,gender) VALUES
         ($1,'أحمد منصور','man'),($2,'مريم خالد','woman')`, [firstId, secondId],
    );
    await pool.query(
      `INSERT INTO engagement_requests (id,sender_user_id,recipient_user_id,status)
       VALUES ($1,$2,$3,'accepted')`, [requestId, firstId, secondId],
    );
    await pool.query(
      `INSERT INTO journeys (id,request_id,first_user_id,second_user_id)
       VALUES ($1,$2,$3,$4)`, [journeyId, requestId, firstId, secondId],
    );
    const token = createToken({ id: firstId, email: null, username: null,
      displayName: 'أحمد منصور', role: 'user', accountType: 'candidate' }, 0);
    const completed = await fetch(`${apiUrl}/v1/journeys/${journeyId}/complete`, {
      method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
      body: JSON.stringify({ outcome: 'success' }),
    });
    const payload = await completed.json() as { certificate?: { fileName: string }; error?: string };
    assert(completed.ok && payload.certificate, payload.error ?? 'Certificate completion failed');
    const stored = await pool.query<{ document_encrypted: string }>(
      'SELECT document_encrypted FROM journey_certificates WHERE journey_id=$1', [journeyId],
    );
    assert(stored.rowCount === 1 && !stored.rows[0].document_encrypted.includes('%PDF'),
      'Certificate was not encrypted at rest');
    const downloaded = await fetch(`${apiUrl}/v1/journeys/${journeyId}/certificate/download`, {
      headers: { Authorization: `Bearer ${token}` },
    });
    const pdf = Buffer.from(await downloaded.arrayBuffer());
    assert(downloaded.ok && payload.certificate.fileName.endsWith('.pdf')
      && downloaded.headers.get('content-type')?.includes('application/pdf')
      && pdf.subarray(0, 4).toString() === '%PDF',
      'Certificate download is invalid');
    console.log('Journey certificate smoke test passed.');
  } finally {
    await pool.query('DELETE FROM users WHERE id=ANY($1::uuid[])', [[firstId, secondId]]);
    await pool.end();
  }
};

void run().catch((error: unknown) => {
  console.error('Journey certificate smoke test failed', error);
  process.exitCode = 1;
});
