import { db } from '@server/db/drizzle';
import { sql } from 'drizzle-orm';
import { initDatabase } from '@server/db/init';
import { NotFoundError } from '@server/errors';
import crypto from 'crypto';

export async function listApiKeys(restaurantId: string) {
  await initDatabase();
  /* raw: SELECT id, restaurant_id, name, key_preview, permissions, calls_this_month, status, last_used_at, created_at FROM api_keys WHERE restaurant_id = $1 ORDER BY created_at DESC */
  const { rows } = await db.execute(sql`
    SELECT id, restaurant_id, name, key_preview, permissions, calls_this_month, status, last_used_at, created_at
    FROM api_keys WHERE restaurant_id = ${restaurantId} ORDER BY created_at DESC
  `);
  return rows;
}

export async function createApiKey(restaurantId: string, data: Record<string, unknown>) {
  await initDatabase();
  const rawKey = `rsk_${crypto.randomBytes(32).toString('hex')}`;
  const keyHash = crypto.createHash('sha256').update(rawKey).digest('hex');
  const keyPreview = `${rawKey.substring(0, 10)}...${rawKey.substring(rawKey.length - 4)}`;

  /* raw: INSERT INTO api_keys (...) VALUES (...) RETURNING * */
  const { rows } = await db.execute(sql`
    INSERT INTO api_keys (restaurant_id, name, key_hash, key_preview, permissions, status)
    VALUES (${restaurantId}, ${data.name as string}, ${keyHash}, ${keyPreview},
            ${JSON.stringify(data.permissions ?? [])}::jsonb, ${'active'})
    RETURNING *
  `);

  return { ...rows[0], key: rawKey };
}

export async function revokeApiKey(id: string, restaurantId: string) {
  await initDatabase();
  /* raw: UPDATE api_keys SET status = 'revoked' WHERE id = $1 AND restaurant_id = $2 RETURNING * */
  const { rows } = await db.execute(sql`UPDATE api_keys SET status = 'revoked' WHERE id = ${id} AND restaurant_id = ${restaurantId} RETURNING *`);
  if (!rows[0]) throw new NotFoundError('API key');
  return rows[0];
}
