/**
 * luxtts skill
 * 文字轉語音：透過本機 LuxTTS API 進行 voice clone
 */

import { existsSync, readFileSync } from 'fs';
import { execFileSync } from 'child_process';

const LUXTTS_API = process.env.LUXTTS_API || 'http://127.0.0.1:7861/luxtts/api/tts';
const DEFAULT_REF_AUDIO = process.env.LUXTTS_REF_AUDIO || '/home/selig/.openclaw/workspace/media/refs/ref_from_762.wav';
const OUTPUT_DIR = '/home/selig/.openclaw/workspace/media';

const TRIGGER_WORDS = [
  'luxtts', 'lux', '文字轉語音', '語音合成', '唸出來', '說出來', '轉語音', 'voice',
];

const SPEED_MODIFIERS: Record<string, number> = {
  '慢速': 0.85,
  'slow': 0.85,
  '快速': 1.15,
  'fast': 1.15,
};

function parseMessage(message: string): { text: string; speed: number } {
  let cleaned = message;
  let speed = 1.0;

  for (const trigger of TRIGGER_WORDS) {
    const re = new RegExp(trigger, 'gi');
    cleaned = cleaned.replace(re, '');
  }

  for (const [modifier, value] of Object.entries(SPEED_MODIFIERS)) {
    const re = new RegExp(modifier, 'gi');
    if (re.test(cleaned)) {
      cleaned = cleaned.replace(re, '');
      speed = value;
    }
  }

  cleaned = cleaned.replace(/^[\s：:，,、]+/, '').replace(/[\s：:，,、]+$/, '').trim();
  return { text: cleaned, speed };
}

function ensureDependencies() {
  if (!existsSync(DEFAULT_REF_AUDIO)) {
    throw new Error(`找不到預設參考音檔：${DEFAULT_REF_AUDIO}`);
  }
}

function generateSpeech(text: string, speed: number): string {
  const timestamp = Date.now();
  const outputPath = `${OUTPUT_DIR}/luxtts_clone_${timestamp}.wav`;
  const curlCmd = [
    'curl', '-sS', '-o', outputPath,
    '-F', `ref_audio=@${DEFAULT_REF_AUDIO}`,
    '-F', `text=${text}`,
    '-F', 'num_steps=4',
    '-F', 't_shift=0.9',
    '-F', `speed=${speed}`,
    '-F', 'duration=5',
    '-F', 'rms=0.01',
    LUXTTS_API,
  ];

  execFileSync(curlCmd[0], curlCmd.slice(1), {
    timeout: 600000,
    stdio: 'pipe',
    encoding: 'utf8',
  });

  if (!existsSync(outputPath)) {
    throw new Error('LuxTTS 未產生輸出音檔');
  }

  const header = readFileSync(outputPath).subarray(0, 16).toString('ascii');
  if (!header.includes('RIFF') && !header.includes('WAVE')) {
    throw new Error(`LuxTTS 回傳非 WAV 音訊，檔頭：${JSON.stringify(header)}`);
  }

  return outputPath;
}

export async function handler(ctx: any) {
  const message = ctx.message?.text || ctx.message?.content || '';

  if (!message.trim()) {
    return { reply: '請提供要合成的文字，例如：「luxtts 这个世界已经改变了」' };
  }

  const { text, speed } = parseMessage(message);

  if (!text) {
    return { reply: '請提供要合成的文字，例如：「luxtts 这个世界已经改变了」' };
  }

  try {
    ensureDependencies();
    const outputPath = generateSpeech(text, speed);

    return {
      reply:
        '🔊 luxtts 語音合成完成' +
        `\n\n📝 文字：${text}` +
        `\n⏩ 語速：${speed}` +
        `\n🎙️ 參考音檔：\`${DEFAULT_REF_AUDIO}\`` +
        `\n🌐 API：\`${LUXTTS_API}\`` +
        `\n📂 檔案：\`${outputPath}\``,
      metadata: {
        text,
        speed,
        refAudio: DEFAULT_REF_AUDIO,
        output: outputPath,
        engine: 'luxtts',
        backend: 'luxtts-api',
      },
      files: [outputPath],
    };
  } catch (error: any) {
    return {
      reply:
        '❌ luxtts 語音合成失敗，請檢查 luxtts 服務、API 與預設參考音檔是否正常。' +
        (error?.message ? `\n\n錯誤：${error.message}` : ''),
      metadata: {
        text,
        speed,
        refAudio: DEFAULT_REF_AUDIO,
        engine: 'luxtts',
        backend: 'luxtts-api',
        error: error?.message || String(error),
      },
    };
  }
}
