
import fs from "fs";
import path from "path";
import { FAILED_LOG, HOST, JOBS_DIR, PART } from "./chatterbox.env";
import randomstring from "randomstring";
// const sub_name = randomstring.generate({ length: 5, charset: "alphanumeric" });

/* ============================================================
   DOWNLOAD
============================================================ */

// tidur
const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));

// cek apakah file sudah ada
function fileExists(path: string) {
    return fs.existsSync(path) && fs.statSync(path).size > 44;
}

// tulis log gagal
function logFail(msg: string) {
    fs.appendFileSync(FAILED_LOG, msg + "\n");
}

async function downloadWithRetry(jobId: string, outFile: string) {
    const MAX_RETRY = 5;

    // jika sebelumnya sudah ada → skip
    if (fileExists(outFile)) {
        console.log(`   🔁 Resume: file sudah ada → ${outFile}`);
        return true;
    }

    for (let attempt = 1; attempt <= MAX_RETRY; attempt++) {
        try {
            console.log(`   ⏳ Download ${jobId} (try ${attempt}/${MAX_RETRY})...`);
            const res = await fetch(`${HOST}/file/${jobId}`);

            if (!res.ok) {
                throw new Error(`Status ${res.status}`);
            }

            const buf = Buffer.from(await res.arrayBuffer());

            // pastikan ukurannya wajar
            if (buf.length < 44) {
                throw new Error("File terlalu kecil (korup?)");
            }

            fs.writeFileSync(outFile, buf);
            console.log(`   ✓ Success → ${outFile}`);
            return true;
        } catch (err: any) {
            console.error(`   ❌ Error: ${err.message}`);
            if (attempt < MAX_RETRY) {
                console.log("   🔄 Retry dalam 2s...");
                await sleep(2000);
            }
        }
    }

    console.error(`   ❌ Gagal total untuk ${jobId}`);
    logFail(jobId);
    return false;
}


/**
 * Download all jobs
 * @returns 
 */
export async function download(jobs_name: string) {
    const JOBS_FILE = path.join(JOBS_DIR, `${jobs_name}.json`); 
    if (!fs.existsSync(JOBS_FILE)) {
        console.error("❌ jobs.json not found");
        process.exit(1);
    }

    const jobs = JSON.parse(fs.readFileSync(JOBS_FILE, "utf-8"));
    console.log(`📦 Total jobs: ${jobs.length}`);

    const lastJobIndex = jobs.length - 1;
    const lastJobId = jobs[lastJobIndex];

    const resLastJob = await fetch(`${HOST}/file/${lastJobId}`);
    if (!resLastJob.ok) {
        return {
            success: false,
            message: `Failed to download last job: ${lastJobId} or on generate`,
            data: null
        }
    }
    
    const resultFiles: string[] = [];

    await fs.promises.rm(PART, { recursive: true }).catch(() => {});
    await fs.promises.mkdir(PART, { recursive: true }).catch(() => {});
    
    for (let i = 0; i < jobs.length; i++) {
        const jobId = jobs[i];
        const outFile = `${PART}/${jobId}_${jobs_name}_${(i + 1)
            .toString()
            .padStart(4, "0")}.wav`;

        console.log(`\n▶️ Job ${i + 1}/${jobs.length} → ${jobId}`);

        const success = await downloadWithRetry(jobId, outFile);

        if (success) {
            resultFiles.push(outFile);
        }
    }

    console.log("\n🎉 DONE!");
    console.log("Result files:", resultFiles);
    return {
        success: true,
        message: "Download completed",
        data: resultFiles
    };
}