import * as fs from 'fs';
import { resolve } from 'path';
import { execSync } from 'child_process';
import * as path from 'path';
import consola from 'consola';
import axios from 'axios';
import { URL } from 'url';

// 错误信息常量
const ErrorMessages = {
    NO_SOURCE: '请提供源文件路径或URL',
    INVALID_FILE_TYPE: '无效的文件类型，仅支持 PNG、JPG、JPEG 和 GIF',
    FILE_NOT_EXIST: '源文件不存在',
    DOWNLOAD_FAILED: '文件下载失败:',
    COPY_FAILED: '文件复制失败:',
    CONVERT_FAILED: '文件转换失败:',
    UNEXPECTED_ERROR: '发生意外错误:',
};

// 配置常量
const CONFIG = {
    ALLOWED_EXTENSIONS: ['.png', '.jpg', '.jpeg', '.gif'],
    OUTPUT_FILENAME: 'logo.png',
    TEMP_PREFIX: 'temp-logo-'
};

/**
 * 从URL下载文件到指定目录
 * @param url 文件的URL地址
 * @param destination 目标保存路径
 */
async function downloadFile(url: string, destination: string): Promise<void> {
    try {
        const response = await axios({
            url,
            method: 'GET',
            responseType: 'stream',
            timeout: 10000 // 10秒超时
        });
        
        const writer = fs.createWriteStream(destination);
        
        response.data.pipe(writer);
        
        return new Promise((resolve, reject) => {
            writer.on('finish', resolve);
            writer.on('error', reject);
        });
    } catch (error) {
        throw new Error(`${ErrorMessages.DOWNLOAD_FAILED} ${error.message}`);
    }
}

/**
 * 转换图片为PNG格式
 * @param source 源文件路径
 * @param destination 目标文件路径
 */
function convertToPng(source: string, destination: string): void {
    try {
        // 使用 ImageMagick 转换图片格式
        execSync(`convert "${source}" "${destination}"`);
    } catch (error) {
        throw new Error(`${ErrorMessages.CONVERT_FAILED} ${error.message}`);
    }
}

/**
 * 验证字符串是否为有效URL
 * @param string 待验证的字符串
 */
function isValidUrl(string: string): boolean {
    try {
        new URL(string);
        return true;
    } catch {
        return false;
    }
}

/**
 * 验证文件是否为支持的图片类型
 * @param filePath 文件路径
 */
function isValidImageFile(filePath: string): boolean {
    const ext = path.extname(filePath).toLowerCase();
    return CONFIG.ALLOWED_EXTENSIONS.includes(ext);
}

/**
 * 清理临时文件
 * @param filePath 文件路径
 */
function cleanupTempFile(filePath: string): void {
    if (fs.existsSync(filePath)) {
        try {
            fs.unlinkSync(filePath);
        } catch (error) {
            consola.warn('清理临时文件失败:', error.message);
        }
    }
}

/**
 * 主函数 - 处理Logo替换逻辑
 */
async function main(): Promise<void> {
    const tempFiles: string[] = [];
    
    try {
        // 获取命令行参数中的源文件路径
        const sourcePath = process.argv[2];
        
        if (!sourcePath) {
            throw new Error(ErrorMessages.NO_SOURCE);
        }

        const baseDir: string = resolve('./');
        const finalDestination = path.join(baseDir, CONFIG.OUTPUT_FILENAME);
        
        // 打印初始信息
        consola.info('开始处理Logo');
        consola.info('源文件:', sourcePath);
        consola.info('目标位置:', finalDestination);

        // 验证文件类型
        if (!isValidImageFile(sourcePath)) {
            throw new Error(ErrorMessages.INVALID_FILE_TYPE);
        }

        // 处理URL或本地文件
        if (isValidUrl(sourcePath)) {
            consola.info('正在从URL下载文件...');
            const tempFile = path.join(baseDir, CONFIG.TEMP_PREFIX + Date.now() + path.extname(sourcePath));
            tempFiles.push(tempFile);
            
            // 下载文件
            await downloadFile(sourcePath, tempFile);
            consola.success('文件下载完成');
            
            // 转换为PNG（如果需要）
            if (path.extname(tempFile).toLowerCase() !== '.png') {
                consola.info('正在转换为PNG格式...');
                convertToPng(tempFile, finalDestination);
            } else {
                fs.copyFileSync(tempFile, finalDestination);
            }
        } else {
            // 处理本地文件
            const localPath = path.resolve(sourcePath);
            if (!fs.existsSync(localPath)) {
                throw new Error(ErrorMessages.FILE_NOT_EXIST);
            }
            
            // 转换为PNG（如果需要）
            if (path.extname(localPath).toLowerCase() !== '.png') {
                consola.info('正在转换为PNG格式...');
                convertToPng(localPath, finalDestination);
            } else {
                fs.copyFileSync(localPath, finalDestination);
            }
        }
        
        consola.success('Logo处理完成');
        consola.info(`文件已保存至: ${finalDestination}`);
        
    } catch (error) {
        consola.error('Logo处理失败:', error.message);
        process.exit(1);
    } finally {
        // 清理所有临时文件
        tempFiles.forEach(cleanupTempFile);
    }
}

// 执行主函数
main().catch(error => {
    consola.error(ErrorMessages.UNEXPECTED_ERROR, error);
    process.exit(1);
});