import * as fs from "node:fs/promises";
import { constants as fsConstants } from "node:fs";
import { execFile } from "node:child_process";
import { promisify } from "node:util";

// --- Konfigurasi ---
const TEMP_DIR = "./temp-tts";
const LIST_FILE_NAME = "wav-list.txt";

const exec = promisify(execFile);

/**
 * Menggabungkan daftar file WAV menggunakan ffmpeg concat demuxer.
 * @param relativeFileNames Array NAMA file WAV yang berada di TEMP_DIR (misal: ['a.wav', 'b.wav']).
 * @param output Path lengkap untuk menyimpan file WAV hasil gabungan.
 */
async function merge(relativeFileNames: string[], output: string): Promise<void> {
    if (relativeFileNames.length === 0) {
        console.warn("⚠️ Tidak ada file untuk digabungkan. Melewati proses.");
        return;
    }

    console.log(`\n🔧 Menggabungkan ${relativeFileNames.length} file WAV menggunakan ffmpeg...`);

    const listFilePath = `${TEMP_DIR}/${LIST_FILE_NAME}`;

    // Perbaikan: Tulis nama file saja tanpa prefix TEMP_DIR agar path valid saat concat
    const listContent = relativeFileNames
        .map((f) => `file '${f.replace(/'/g, "'\\''")}'`)
        .join("\n");

    try {
        await fs.writeFile(listFilePath, listContent, "utf-8");
    } catch (err) {
        console.error(`❌ Gagal menulis file list ${listFilePath}:`, err);
        throw new Error(`Gagal menyiapkan file list untuk ffmpeg.`);
    }

    try {
        await exec("ffmpeg", [
            "-f", "concat",
            "-safe", "0",
            "-i", listFilePath,
            "-c", "copy", // Menggabungkan tanpa re-encoding
            output,
        ]);

        console.log(`✅ File berhasil digabungkan dan disimpan di: ${output}\n`);
    } catch (err) {
        console.error("❌ Kesalahan saat menjalankan ffmpeg:", err);
        if (err instanceof Error && 'stdout' in err) {
            console.error('ffmpeg stderr output:', (err as any).stderr);
        }
        throw new Error(`Penggabungan ffmpeg gagal.`);
    } finally {
        try {
            await fs.unlink(listFilePath);
        } catch {
            console.warn(`⚠️ Gagal menghapus file list ${listFilePath}.`);
        }
    }
}

// --- Fungsi Utama ---
export async function merge_wav() {

    await fs.mkdir(`./output`, { recursive: true }).catch(() => {});
    const output = `./output/merged.wav`;

    try {
        await fs.access(output, fsConstants.F_OK);
        await fs.unlink(output);
    } catch (error) {}
        

    try {
        // Cek apakah direktori TEMP_DIR ada
        await fs.access(TEMP_DIR, fsConstants.F_OK);
    } catch {
        console.error(`❌ Direktori sementara ${TEMP_DIR} tidak ditemukan. Pastikan sudah membuat folder tersebut.`);
        return;
    }

    // Baca daftar file WAV dalam TEMP_DIR
    const allFiles = await fs.readdir(TEMP_DIR);

    const wavFileNames = allFiles
        .filter((f) => f.endsWith(".wav"))
        .sort((a, b) => {
            const aNum = parseInt(a?.split("_")[2] || "0");
            const bNum = parseInt(b?.split("_")[2] || "0");
            return aNum - bNum;
        });

    try {
        await merge(wavFileNames, output);
    } catch (err) {
        console.error("⛔ Proses penggabungan utama gagal.");
        process.exit(1);
    }
}


if (import.meta.main) {
    merge_wav();
}