import { promises as fs } from 'fs';
import os from 'os';
import path from 'path';
import { execFile } from 'child_process';
import { promisify } from 'util';

const execFileAsync = promisify(execFile);

export function pickBestPlayAddr(variants: PlayVariant[] | undefined | null) {
    if (!variants?.length) return null;

    const best = variants.reduce((best, cur) => {
        const b1 = best?.bit_rate ?? -1;
        const b2 = cur?.bit_rate ?? -1;
        return b2 > b1 ? cur : best;
    });

    return best?.play_addr ?? null;
}

/**
 * 使用 ffmpeg 从视频二进制中提取第一帧，返回 JPEG buffer
 */
export async function extractFirstFrame(videoBuffer: Buffer): Promise<{ buffer: Buffer; contentType: string; ext: string } | null> {
    const ffmpegCmd = process.env.FFMPEG_PATH || 'ffmpeg';
    const tmpDir = os.tmpdir();
    const base = `dy_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
    const inPath = path.join(tmpDir, `${base}.mp4`);
    const outPath = path.join(tmpDir, `${base}.jpg`);

    try {
        await fs.writeFile(inPath, videoBuffer);
        const args = [
            '-hide_banner',
            '-loglevel', 'error',
            '-ss', '0',
            '-i', inPath,
            '-frames:v', '1',
            '-q:v', '2',
            '-f', 'image2',
            '-y',
            outPath,
        ];
        await execFileAsync(ffmpegCmd, args, { windowsHide: true });
        const img = await fs.readFile(outPath);
        return { buffer: img, contentType: 'image/jpeg', ext: 'jpg' };
    } catch (e: any) {
        if (e && (e.code === 'ENOENT' || /not found|is not recognized/i.test(String(e.message)))) {
            console.warn('系统未检测到 ffmpeg，可安装并配置 PATH 或设置 FFMPEG_PATH 后启用封面提取。');
            return null;
        }
        throw e;
    } finally {
        try { await fs.unlink(inPath); } catch { }
        try { await fs.unlink(outPath); } catch { }
    }
}

/**
 * 使用 ffprobe 获取视频时长（毫秒）
 */
export async function getVideoDuration(videoBuffer: Buffer): Promise<number | null> {
    const ffprobeCmd = process.env.FFPROBE_PATH || 'ffprobe';
    const tmpDir = os.tmpdir();
    const base = `dy_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
    const inPath = path.join(tmpDir, `${base}.mp4`);

    try {
        await fs.writeFile(inPath, videoBuffer);
        const args = [
            '-v', 'error',
            '-show_entries', 'format=duration',
            '-of', 'default=noprint_wrappers=1:nokey=1',
            inPath,
        ];
        const { stdout } = await execFileAsync(ffprobeCmd, args, { windowsHide: true });
        const durationSeconds = parseFloat(stdout.trim());
        if (isNaN(durationSeconds)) return null;
        return Math.round(durationSeconds * 1000); // 转换为毫秒
    } catch (e: any) {
        if (e && (e.code === 'ENOENT' || /not found|is not recognized/i.test(String(e.message)))) {
            console.warn('系统未检测到 ffprobe，可安装并配置 PATH 或设置 FFPROBE_PATH 后启用时长提取。');
            return null;
        }
        console.warn(`获取视频时长失败: ${e?.message || e}`);
        return null;
    } finally {
        try { await fs.unlink(inPath); } catch { }
    }
}
