import { execSync, exec } from "child_process";
import fs from "fs";
import path from "path";
import axios from "axios";
import { storage } from "./storage";

const CHUNK_DURATION = 20; // Duration in seconds
const TEMP_DIR = "uploads/transcription/";

/**
 * Transcribe audio with Deepgram.
 */
async function transcribeWithDeepgram(audioFilePath: string): Promise<string> {
  try {
    console.log("🎙 Starting Deepgram transcription for:", audioFilePath);

    // Verify file exists
    if (!fs.existsSync(audioFilePath)) {
      throw new Error(`Audio file not found: ${audioFilePath}`);
    }

    const audioData = fs.createReadStream(audioFilePath);
    console.log("🎙 Sending audio to Deepgram API...");

    const response = await axios.post(
      "https://api.deepgram.com/v1/listen",
      audioData,
      {
        headers: {
          Authorization: `Token ${process.env.DEEPGRAM_API_KEY}`,
          "Content-Type": "audio/wav",
        },
        params: {
          model: "whisper",
          language: "ar",
          smart_format: true,
          detect_language: false,
        },
      },
    );

    if (response.data && response.data.results) {
      const transcript = response.data.results.channels[0].alternatives[0].transcript;
      console.log("✅ Received transcript from Deepgram:", transcript);
      return transcript;
    }

    console.error("❌ Deepgram response error: No results found in response");
    throw new Error("No transcription results found");
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : "Unknown error";
    const responseData = error.response?.data ? JSON.stringify(error.response.data) : "No response data";
    console.error("❌ Deepgram API Error:", errorMessage, responseData);
    throw new Error(`Deepgram transcription failed: ${errorMessage}`);
  }
}

/**
 * Translate text using OpenAI's API.
 */
async function translateWithOpenAI(text: string): Promise<string> {
  try {
    console.log("🤖 Starting OpenAI translation...");
    const response = await axios.post(
      "https://api.openai.com/v1/chat/completions",
      {
        model: "gpt-4",
        messages: [
          {
            role: "system",
            content:
              "You are a professional translator. Translate the following Arabic text to English, maintaining the original meaning and context.",
          },
          {
            role: "user",
            content: text,
          },
        ],
      },
      {
        headers: {
          Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
          "Content-Type": "application/json",
        },
      }
    );

    const translation = response.data.choices[0]?.message?.content;
    if (!translation) {
      throw new Error("No translation received from OpenAI");
    }
    console.log("✅ Received translation from OpenAI:", translation);
    return translation;
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : "Unknown error";
    const responseData = error.response?.data ? JSON.stringify(error.response.data) : "No response data";
    console.error("❌ OpenAI API Error:", errorMessage, responseData);
    throw new Error(`OpenAI translation failed: ${errorMessage}`);
  }
}

async function processAudioChunk(
  chunkPath: string,
  sessionId: number,
  startTime: Date,
  endTime: Date,
): Promise<void> {
  console.log(`🎙 Processing audio chunk: ${chunkPath}`);

  try {
    // Ensure temp directory exists
    if (!fs.existsSync(TEMP_DIR)) {
      fs.mkdirSync(TEMP_DIR, { recursive: true });
    }

    // Create a unique filename for the WAV conversion
    const uniqueFileName = `${Date.now()}_temp_audio.wav`;
    const wavPath = path.join(TEMP_DIR, uniqueFileName);

    // Convert to WAV with proper parameters
    console.log("🎙 Converting audio to WAV format...");
    const ffmpegCmd = `ffmpeg -i "${chunkPath}" -acodec pcm_s16le -ac 1 -ar 16000 "${wavPath}"`;
    execSync(ffmpegCmd);
    console.log("✅ WAV conversion complete:", wavPath);

    // Get transcript from Deepgram
    const transcript = await transcribeWithDeepgram(wavPath);
    console.log("✅ Transcription received:", transcript);

    if (transcript) {
      // Translate with OpenAI
      const translation = await translateWithOpenAI(transcript);
      console.log("✅ Translation received:", translation);

      // Save transcription and translation to the database
      const savedTranscription = await storage.createTranscription({
        sessionId,
        sourceLanguage: "ar",
        originalText: transcript,
        translatedText: translation,
        clipStartTime: startTime,
        clipEndTime: endTime,
        status: "pending",
      });
      console.log("✅ Transcription saved to database:", savedTranscription);

      // Cleanup temporary files
      fs.unlinkSync(wavPath);
      fs.unlinkSync(chunkPath);
      console.log("✅ Cleaned up temporary files");
    }
  } catch (error) {
    console.error("❌ Error processing audio chunk:", error instanceof Error ? error.message : "Unknown error");
    throw error;
  }
}

export async function processAudioFile(
  sessionId: number,
  filePath: string,
): Promise<void> {
  console.log(`Processing audio file: ${filePath}`);

  try {
    // Verify the audio file exists
    if (!fs.existsSync(filePath)) {
      throw new Error(`Audio file not found: ${filePath}`);
    }

    // Get duration of audio file using ffprobe
    console.log("📊 Getting audio duration...");
    const durationCmd = `ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "${filePath}"`;
    const duration = parseFloat(execSync(durationCmd).toString());
    console.log(`✅ Audio duration: ${duration} seconds`);

    // Split the audio into chunks
    console.log(`🔄 Processing audio in ${CHUNK_DURATION}-second chunks...`);
    for (let i = 0; i * CHUNK_DURATION < duration; i++) {
      const startTime = i * CHUNK_DURATION;
      const uniqueFileName = `${Date.now()}_chunk_${i}.mp3`;
      const chunkPath = path.join(TEMP_DIR, uniqueFileName);
      console.log(
        `📝 Creating chunk ${i + 1}: ${startTime} to ${startTime + CHUNK_DURATION} seconds`,
      );

      // Extract chunk using ffmpeg
      const cmd = `ffmpeg -i "${filePath}" -ss ${startTime} -t ${CHUNK_DURATION} -c copy "${chunkPath}"`;
      execSync(cmd);
      console.log(`✅ Created chunk: ${chunkPath}`);

      // Process the extracted chunk
      await processAudioChunk(
        chunkPath,
        sessionId,
        new Date(startTime * 1000),
        new Date((startTime + CHUNK_DURATION) * 1000),
      );
    }
    console.log("✅ Audio processing completed successfully");
  } catch (error) {
    console.error("❌ Error processing audio file:", error instanceof Error ? error.message : "Unknown error");
    throw error;
  }
}