import { config } from '../config.js';
import { prisma } from '../prisma.js';

type DeepgramResponse = {
  results?: {
    channels?: Array<{
      alternatives?: Array<{
        transcript?: string;
        paragraphs?: {
          transcript?: string;
        };
      }>;
    }>;
  };
};

export async function transcribeVoiceExperience(experienceId: string) {
  const experience = await prisma.voiceExperience.findUnique({
    where: { id: experienceId },
  });

  if (!experience) {
    throw new Error(`Voice experience ${experienceId} was not found.`);
  }

  await prisma.voiceExperience.update({
    where: { id: experienceId },
    data: { status: 'TRANSCRIBING' },
  });

  const transcript = await transcribeAudioObject(experience.id);

  await prisma.voiceExperience.update({
    where: { id: experienceId },
    data: {
      audioContentBase64: null,
      audioAccessToken: null,
      transcript,
      status: 'TRANSCRIBED',
    },
  });

  return { transcript };
}

async function transcribeAudioObject(experienceId: string): Promise<string> {
  if (!config.deepgramApiKey) {
    throw new Error('DEEPGRAM_API_KEY is required for transcription.');
  }

  const experience = await prisma.voiceExperience.findUnique({
    where: { id: experienceId },
    select: {
      id: true,
      audioObjectKey: true,
      audioAccessToken: true,
      audioContentBase64: true,
      audioMimeType: true,
    },
  });

  if (!experience) {
    throw new Error(`Voice experience ${experienceId} was not found.`);
  }
  if (!experience.audioAccessToken) {
    throw new Error(
      `Voice audio ${experience.audioObjectKey} has no access token.`,
    );
  }
  if (!experience.audioContentBase64 || !experience.audioMimeType) {
    throw new Error(
      `Voice audio ${experience.audioObjectKey} has no stored content.`,
    );
  }

  const params = new URLSearchParams({
    model: config.deepgramModel,
    language: config.deepgramLanguage,
    smart_format: 'true',
    punctuate: 'true',
  });
  const audioUrl = `${config.publicApiUrl.replace(/\/$/, '')}/audio/voice-experiences/${experience.id}?token=${encodeURIComponent(experience.audioAccessToken)}`;
  const response = await fetch(
    `https://api.deepgram.com/v1/listen?${params.toString()}`,
    {
      method: 'POST',
      headers: {
        authorization: `Token ${config.deepgramApiKey}`,
        'content-type': 'application/json',
      },
      body: JSON.stringify({ url: audioUrl }),
    },
  );

  if (!response.ok) {
    throw new Error(`Deepgram transcription failed with ${response.status}.`);
  }

  const payload = (await response.json()) as DeepgramResponse;
  const alternative = payload.results?.channels?.[0]?.alternatives?.[0];
  const transcript =
    alternative?.paragraphs?.transcript?.trim() ??
    alternative?.transcript?.trim() ??
    '';
  if (!transcript) {
    throw new Error('Deepgram returned an empty transcript.');
  }

  return transcript;
}
