const MINIMAX_API_KEY = process.env.MINIMAX_API_KEY;
if (!MINIMAX_API_KEY) {
  throw new Error("MINIMAX_API_KEY environment variable is required");
}

interface VoiceSetting {
  voice_id: string;
  speed: number;
  vol: number;
  pitch: number;
  emotion?: string;
}

interface AudioSetting {
  sample_rate: number;
  bitrate: number;
  format: "mp3" | "wav" | "ogg" | "aac";
  channel: number;
}

interface PronunciationDictEntry {
  text: string;
  pronunciation: string;
}

interface MiniMaxTTSRequest {
  model: string;
  text: string;
  stream?: boolean;
  voice_setting: VoiceSetting;
  audio_setting: AudioSetting;
  pronunciation_dict?: {
    tone: PronunciationDictEntry[];
  };
  subtitle_enable?: boolean;
}

interface MiniMaxTTSResponse {
  code: number;
  desc: string;
  data?: {
    audio?: string;
    audio_file?: string;
    subtitle_info?: string;
  };
}

const BASE_URL = "https://api.minimaxi.com/v1/t2a_v2";

export async function textToSpeech(
  request: MiniMaxTTSRequest
): Promise<Buffer> {
  const response = await fetch(BASE_URL, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${MINIMAX_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(request),
  });

  if (!response.ok) {
    const body = await response.text();
    throw new Error(`MiniMax API error: ${response.status} ${response.statusText} - ${body}`);
  }

  const result = (await response.json()) as MiniMaxTTSResponse;

  if (result.code && result.code !== 0) {
    throw new Error(`MiniMax API error: ${result.code} - ${result.desc}`);
  }

  if (!result.data?.audio && !result.data?.audio_file) {
    throw new Error("No audio data returned");
  }

  const audioHex = result.data.audio || result.data.audio_file!;
  const audioBuffer = Buffer.from(audioHex, "hex");
  return audioBuffer;
}

export async function textToSpeechStream(
  request: MiniMaxTTSRequest,
  onChunk: (chunk: Buffer) => void
): Promise<void> {
  const response = await fetch(BASE_URL, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${MINIMAX_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ ...request, stream: true }),
  });

  if (!response.ok) {
    throw new Error(`MiniMax API error: ${response.status} ${response.statusText}`);
  }

  if (!response.body) {
    throw new Error("No response body");
  }

  const reader = response.body.getReader();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    onChunk(Buffer.from(value));
  }
}

export const VOICE_IDS = {
  male_qn_qingse: "male-qn-qingse",
  female_tianmei: "female-tianmei",
  male_baixian: "male-baixian",
  female_aicheng: "female-aicheng",
  male_yunyang: "male-yunyang",
  female_xiaomo: "female-xiaomo",
} as const;

export type VoiceId = (typeof VOICE_IDS)[keyof typeof VOICE_IDS];

export const EMOTIONS = {
  neutral: "neutral",
  happy: "happy",
  sad: "sad",
  angry: "angry",
  fearful: "fearful",
  disgust: "disgust",
  surprised: "surprised",
} as const;

export type Emotion = (typeof EMOTIONS)[keyof typeof EMOTIONS];

// Usage example:
// async function example() {
//   const audio = await textToSpeech({
//     model: "speech-2.8-hd",
//     text: "今天是不是很开心呀(laughs)，当然了！",
//     stream: false,
//     voice_setting: {
//       voice_id: VOICE_IDS.male_qn_qingse,
//       speed: 1,
//       vol: 1,
//       pitch: 0,
//       emotion: EMOTIONS.happy,
//     },
//     audio_setting: {
//       sample_rate: 32000,
//       bitrate: 128000,
//       format: "mp3",
//       channel: 1,
//     },
//   });
//
//   // Save audio to file (Node.js)
//   await import("fs/promises").then(fs => fs.writeFile("output.mp3", audio));
// }
