import { createHash, randomBytes, randomUUID } from 'node:crypto';
import { pool } from './db';

const apiUrl = process.env.SMOKE_API_URL ?? 'http://127.0.0.1:4000/api';
const userId = randomUUID();
const email = `google-auth-${randomUUID().slice(0, 8)}@test.invalid`;
const code = randomBytes(32).toString('base64url');
const codeHash = createHash('sha256').update(code).digest('hex');

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,username,role)
       VALUES ($1,$2,'not-a-login-password','Google Test',$3,'user')`,
      [userId, email, `google${randomUUID().replaceAll('-', '').slice(0, 10)}`],
    );
    await pool.query(
      `INSERT INTO google_auth_tickets (ticket_hash,user_id,expires_at)
       VALUES ($1,$2,NOW()+INTERVAL '2 minutes')`,
      [codeHash, userId],
    );
    const status = await fetch(`${apiUrl}/auth/google/status`);
    const statusBody = await status.json() as { configured?: boolean };
    assert(status.ok && typeof statusBody.configured === 'boolean', 'Google status endpoint failed');
    const first = await fetch(`${apiUrl}/auth/google/exchange`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ code }),
    });
    const session = await first.json() as { token?: string; user?: { id?: string } };
    assert(first.ok && session.token && session.user?.id === userId, 'Google ticket exchange failed');
    const replay = await fetch(`${apiUrl}/auth/google/exchange`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ code }),
    });
    assert(replay.status === 401, 'Google ticket replay was not rejected');
    console.log('Google authentication smoke test passed.');
  } finally {
    await pool.query('DELETE FROM users WHERE id=$1', [userId]);
    await pool.end();
  }
};

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