import { NextResponse } from 'next/server';
import { getSql } from '../../../lib/db.js';
import { findActiveKeyByHash } from '../../../lib/repositories/apiKeys.repository.js';
import { createLiveVerificationProofToken } from '../../../lib/liveVerificationProof.mjs';

export const dynamic = 'force-dynamic';

async function hashKey(key) {
  const data = new TextEncoder().encode(key);
  const hashBuffer = await crypto.subtle.digest('SHA-256', data);
  return Array.from(new Uint8Array(hashBuffer))
    .map((b) => b.toString(16).padStart(2, '0'))
    .join('');
}

function timingSafeEqual(a, b) {
  if (typeof a !== 'string' || typeof b !== 'string') return false;
  const encoder = new TextEncoder();
  const aBuf = encoder.encode(a);
  const bBuf = encoder.encode(b);
  const maxLen = Math.max(aBuf.length, bBuf.length);
  let result = aBuf.length ^ bBuf.length;
  for (let i = 0; i < maxLen; i++) {
    result |= (aBuf[i] || 0) ^ (bBuf[i] || 0);
  }
  return result === 0;
}

async function buildSuccessResponse(start, request) {
  const latencyMs = Date.now() - start;
  const url = new URL(request.url);

  // Mint a live verification proof so the setup page upgrades to "verified"
  let proofToken = null;
  try {
    const { token } = await createLiveVerificationProofToken(
      {
        validator: 'setup-ping',
        tool: 'node',
        mode: 'read_only',
        summary: { passed: 1, failed: 0, skipped: 0, score: 100 },
        checks: [{ name: 'Authenticated ping', status: 'pass' }],
      },
      { env: process.env, host: url.host }
    );
    proofToken = token;
  } catch {
    // Proof minting is best-effort (needs NEXTAUTH_SECRET)
  }

  return NextResponse.json({
    ok: true,
    latencyMs,
    message: 'Instance is accepting authenticated requests.',
    proof_token: proofToken,
  });
}

export async function POST(request) {
  const start = Date.now();

  if (process.env.DASHCLAW_MODE === 'demo') {
    return NextResponse.json(
      { ok: false, message: 'Live ping is not available in demo mode.' },
      { status: 403 }
    );
  }

  const apiKey = request.headers.get('x-api-key');
  if (!apiKey) {
    return NextResponse.json(
      { ok: false, message: 'API key did not match.' },
      { status: 401 }
    );
  }

  // Fast path: check against environment variable
  const expectedKey = process.env.DASHCLAW_API_KEY;
  if (expectedKey && timingSafeEqual(apiKey, expectedKey)) {
    return buildSuccessResponse(start, request);
  }

  // Slow path: check against workspace API keys in database
  try {
    const sql = getSql();
    const keyHash = await hashKey(apiKey);
    const rows = await findActiveKeyByHash(sql, keyHash);
    if (rows.length > 0) {
      return buildSuccessResponse(start, request);
    }
  } catch {
    // DB unavailable — fall through to rejection
  }

  return NextResponse.json(
    { ok: false, message: 'API key did not match.' },
    { status: 401 }
  );
}
