import { NextRequest, NextResponse } from 'next/server';
import { exec } from 'child_process';
import { promisify } from 'util';
import { writeFile, unlink } from 'fs/promises';
import { tmpdir } from 'os';
import { join } from 'path';

const execAsync = promisify(exec);

export async function POST(request: NextRequest) {
  const startTime = Date.now();
  try {
    const formData = await request.formData();
    const file = formData.get('audio') as File | null;
    const model = (formData.get('model') as string) || 'ggml-base.en.bin';

    if (!file) {
      return NextResponse.json({ error: 'No audio file provided' }, { status: 400 });
    }

    // Write uploaded file to temp
    const buffer = Buffer.from(await file.arrayBuffer());
    const tmpPath = join(tmpdir(), `whisper-${Date.now()}.wav`);
    await writeFile(tmpPath, buffer);

    try {
      // Try to find whisper-cli
      const whisperBin = await findWhisperBin();
      if (!whisperBin) {
        return NextResponse.json({ error: 'whisper-cli not found' }, { status: 500 });
      }

      // Find model path
      const modelPaths = [
        `/opt/homebrew/share/whisper-cpp/models/${model}`,
        `${process.env.HOME}/whisper-models/${model}`,
        `${process.env.HOME}/.cache/whisper/${model}`,
      ];

      let modelPath = '';
      for (const p of modelPaths) {
        try {
          await execAsync(`test -f "${p}"`);
          modelPath = p;
          break;
        } catch {
          /* not found */
        }
      }

      if (!modelPath) {
        return NextResponse.json({ error: `Model ${model} not found` }, { status: 404 });
      }

      const { stdout } = await execAsync(
        `"${whisperBin}" -m "${modelPath}" -f "${tmpPath}" --no-timestamps -otxt 2>/dev/null`,
        { timeout: 30000 }
      );

      const latencyMs = Date.now() - startTime;
      return NextResponse.json({
        text: stdout.trim(),
        model,
        latencyMs,
        fileSize: buffer.length,
      });
    } finally {
      await unlink(tmpPath).catch(() => {});
    }
  } catch (err) {
    return NextResponse.json({ error: String(err) }, { status: 500 });
  }
}

async function findWhisperBin(): Promise<string | null> {
  const candidates = ['whisper-cli', 'whisper-cpp', 'main'];
  for (const bin of candidates) {
    try {
      const { stdout } = await execAsync(`which ${bin}`);
      if (stdout.trim()) return stdout.trim();
    } catch {
      /* not found */
    }
  }
  // Check homebrew path
  try {
    const { stdout } = await execAsync('ls /opt/homebrew/bin/whisper-cli 2>/dev/null');
    if (stdout.trim()) return stdout.trim();
  } catch {
    /* not found */
  }
  return null;
}
