import ffmpeg, { FfprobeStream } from 'fluent-ffmpeg';
import fs from 'fs';
import { LogWrapper } from '@/common/log';

export const defaultVideoThumbB64 =
    '[encoded data, 5192 characters]';

interface VideoInfo {
    width: number;
    height: number;
    time: number;
    format: string;
    size: number;
    filePath: string;
}

async function getFileSize(filePath: string): Promise<number> {
    const stats = await fs.promises.stat(filePath);
    return stats.size;
}

function setFfmpegPath() {
    const ffmpegPath = process.env.FFMPEG_PATH;
    if (ffmpegPath) {
        ffmpeg.setFfmpegPath(ffmpegPath);
    }
}

function extractVideoStream(metadata: ffmpeg.FfprobeData): FfprobeStream | undefined {
    return metadata.streams.find((s: FfprobeStream) => s.codec_type === 'video');
}

async function probeVideo(filePath: string): Promise<ffmpeg.FfprobeData> {
    return new Promise((resolve, reject) => {
        ffmpeg(filePath).ffprobe((err: any, metadata: ffmpeg.FfprobeData) => {
            if (err) {
                reject(new Error('无法获取视频信息。'));
            } else {
                resolve(metadata);
            }
        });
    });
}

export async function getVideoInfo(filePath: string, logger: LogWrapper): Promise<VideoInfo> {
    try {
        const size = await getFileSize(filePath);
        setFfmpegPath();
        const metadata = await probeVideo(filePath);
        const videoStream = extractVideoStream(metadata);

        if (!videoStream) {
            throw new Error('未找到视频流信息。');
        }

        logger.log(`视频尺寸: ${videoStream.width}x${videoStream.height}`);
        if (!videoStream.width || !metadata.format.format_name || !videoStream.height) {
            throw new Error('获取基础信息失败');
        }
        return {
            width: videoStream.width,
            height: videoStream.height,
            time: +(videoStream.duration ?? 10),
            format: metadata.format.format_name,
            size,
            filePath,
        };
    } catch (error) {
        throw new Error('无法获取视频信息。');
    }
}