import fs from 'fs-extra';
import path from 'path';
// import { format as dateFormat } from 'date-fns';
const timeZone = 'Asia/Shanghai'; // Beijing Time
import { formatInTimeZone } from 'date-fns-tz';
import TOSService from '@/lib/tos/tos-service.js';
import logger from '@/lib/logger.js';

// 环境变量控制新旧方法切换
const USE_DATABASE_MODE = process.env.USE_DATABASE_MODE === 'true';

const LOG_PATH = path.resolve("./logs/images_task_cache.log");

function cacheLog(value: string, color?: string) {
    try {
        const head = `[ImagesTaskCache][${formatInTimeZone(new Date(),timeZone, "yyyy-MM-dd HH:mm:ss.SSS")}] `;
        value = head + value;
        // console.log(color ? value[color] : value);
        fs.ensureDirSync(path.dirname(LOG_PATH));
        fs.appendFileSync(LOG_PATH, value + "\n");
    }
    catch(err) {
        console.error("ImagesTaskCache log write error:", err);
    }
}

// 定义任务结果接口
interface TaskResult {
    status: -1 | -2 | -3 | number;
    url?: string;
    errorMessage?: string;
    timestamp: number;
}

export class ImagesTaskCache {
    private static instance: ImagesTaskCache;
    private taskCache: Map<string, TaskResult>;
    private tosProcessedTasks: Set<string>; // 记录已处理TOS上传的任务
    private cleanupInterval: NodeJS.Timeout | null = null;

    private constructor() {
        this.taskCache = new Map();
        this.tosProcessedTasks = new Set();
        this.startPeriodicCleanup();
        cacheLog("ImagesTaskCache initialized");
    }

    public static getInstance(): ImagesTaskCache {
        if (!ImagesTaskCache.instance) {
            ImagesTaskCache.instance = new ImagesTaskCache();
        }
        return ImagesTaskCache.instance;
    }

    /**
     * 启动定期清理
     */
    private startPeriodicCleanup(): void {
        // 每30分钟清理一次过期任务
        this.cleanupInterval = setInterval(() => {
            this.clearExpiredTasks();
        }, 30 * 60 * 1000); // 30分钟
        
        cacheLog("Periodic cleanup started for ImagesTaskCache");
    }

    /**
     * 停止定期清理
     */
    public stopPeriodicCleanup(): void {
        if (this.cleanupInterval) {
            clearInterval(this.cleanupInterval);
            this.cleanupInterval = null;
            cacheLog("Periodic cleanup stopped for ImagesTaskCache");
        }
    }

    public startTask(taskId: string): void {
        const startTime = Math.floor(Date.now() / 1000); // Current time in seconds
        this.taskCache.set(taskId, {
            status: startTime,
            timestamp: Date.now()
        });
        cacheLog(`Task started: ${taskId} at ${startTime}`);
    }

    /**
     * 处理图片URL上传到TOS
     * @param imageUrls 图片URL数组
     * @returns TOS URL数组
     */
    private async uploadImagesToTOS(imageUrls: string[], task_id: string): Promise<string[]> {
        const tosUrls: string[] = [];
        
        for (const imageUrl of imageUrls) {
            try {
                // 从URL获取文件名
                const fileName = `image-${Date.now()}-${Math.random().toString(36).substr(2, 9)}.png`;
                // 上传到TOS
                const tosUrl = await TOSService.uploadFromUrl(imageUrl, `jimeng_free/images/${task_id}/${fileName}`);
                tosUrls.push(tosUrl);
                logger.info(`图片上传到TOS成功: ${imageUrl} -> ${tosUrl}`);
            } catch (error) {
                logger.error(`图片上传到TOS失败: ${imageUrl}`, error);
                // 如果上传失败，保留原URL
                tosUrls.push(imageUrl);
            }
        }
        
        return tosUrls;
    }

    public async finishTask(taskId: string, status: -1 | -2 | -3, url: string = '', errorMessage?: string): Promise<void> {
        if (!this.taskCache.has(taskId)) {
            cacheLog(`Attempted to finish non-existent task: ${taskId}`);
            return;
        }

        let finalUrl = url;
        let statusMessage = '';
        
        switch (status) {
            case -1: {
                statusMessage = 'successfully';
                if (url && !USE_DATABASE_MODE) {
                    // 只在非数据库模式下执行TOS上传，避免与TaskPollingService重复上传
                    try {
                        // 任务成功完成时，自动上传到TOS
                        cacheLog(`开始上传图片到TOS: ${taskId}`);
                        const imageUrls = url.split(',');
                        const tosUrls = await this.uploadImagesToTOS(imageUrls, taskId);
                        finalUrl = tosUrls.join(',');
                        this.tosProcessedTasks.add(taskId);
                        cacheLog(`Task ${taskId} TOS上传完成，存储TOS地址: ${finalUrl}`);
                    } catch (error) {
                        logger.error(`TOS上传失败，使用原始URL: ${taskId}`, error);
                        finalUrl = url; // 保留原始URL
                        cacheLog(`Task ${taskId} TOS上传失败，使用原始URL`);
                    }
                } else if (url) {
                    // 数据库模式下，直接使用原始URL，TOS上传由TaskPollingService处理
                    finalUrl = url;
                    cacheLog(`Task ${taskId} 数据库模式下完成，TOS上传由TaskPollingService处理`);
                }
                break;
            }
            case -2: statusMessage = 'failed'; break;
            case -3: statusMessage = 'timed out'; break;
        }
        
        // 存储任务结果，包括错误信息
        this.taskCache.set(taskId, {
            status,
            url: finalUrl,
            errorMessage: status !== -1 ? errorMessage : undefined,
            timestamp: Date.now()
        });
        cacheLog(`Task ${taskId} finished ${statusMessage} (status: ${status})`);
    }

    public getTaskStatus(taskId: string): TaskResult | undefined {
        return this.taskCache.get(taskId);
    }

    /**
     * 检查任务是否已处理TOS上传（兼容性保持）
     */
    public isTosProcessed(taskId: string): boolean {
        return this.tosProcessedTasks.has(taskId);
    }

    /**
     * 标记任务为已处理TOS上传（兼容性保持）
     */
    public markTosProcessed(taskId: string): void {
        this.tosProcessedTasks.add(taskId);
        cacheLog(`Task ${taskId} marked as TOS processed`);
    }

    /**
     * 获取任务结果并释放缓存
     * @param taskId 任务ID
     * @returns 任务结果，如果不存在返回undefined
     */
    public getTaskResultAndClear(taskId: string): TaskResult | undefined {
        const result = this.taskCache.get(taskId);
        if (!result) {
            return undefined;
        }

        // 如果任务已完成（状态为字符串URL或负数状态码），则清理缓存
        if (typeof result.status === 'number' && result.status < 0) {
            this.taskCache.delete(taskId);
            cacheLog(`Task ${taskId} result retrieved and cache cleared`);
            return result;
        }

        // 任务仍在进行中，不清理缓存
        return result;
    }

    /**
     * 清理过期任务（超过1小时的任务）
     * 防止在低配置服务器上内存泄漏
     */
    public clearExpiredTasks(): void {
        const now = Date.now();
        const expiredTasks: string[] = [];
        
        for (const [taskId, result] of this.taskCache.entries()) {
            // 检查任务是否超过24小时
            if (now - result.timestamp > 24 * 60 * 60 * 1000) {
                expiredTasks.push(taskId);
            }
        }
        
        for (const taskId of expiredTasks) {
            this.taskCache.delete(taskId);
            this.tosProcessedTasks.delete(taskId);
            cacheLog(`Expired task cleared: ${taskId}`);
        }
        
        if (expiredTasks.length > 0) {
            cacheLog(`Cleared ${expiredTasks.length} expired tasks`);
        }
    }

    /**
     * 获取缓存统计信息
     */
    public getCacheStats(): { totalTasks: number, completedTasks: number, pendingTasks: number } {
        let completedTasks = 0;
        let pendingTasks = 0;
        
        for (const result of this.taskCache.values()) {
            if (typeof result.status === 'number' && result.status < 0) {
                completedTasks++;
            } else {
                pendingTasks++;
            }
        }
        
        return {
            totalTasks: this.taskCache.size,
            completedTasks,
            pendingTasks
        };
    }

    public getPendingTasks(): string[] {
        const pendingTasks: string[] = [];
        
        for (const [taskId, result] of this.taskCache.entries()) {
            if (typeof result.status === 'number' && result.status >= 0) {
                pendingTasks.push(taskId);
            }
        }
        
        return pendingTasks;
    }

    public logPendingTasksOnShutdown(): void {
        const pendingTasks = this.getPendingTasks();
        if (pendingTasks.length > 0) {
            cacheLog(`Pending tasks at shutdown: ${pendingTasks.join(', ')}`, 'yellow');
        } else {
            cacheLog("No pending tasks at shutdown.");
        }
        
        // 关闭时停止定时清理并进行最终清理
        this.stopPeriodicCleanup();
        this.clearExpiredTasks();
        
        const stats = this.getCacheStats();
        cacheLog(`Final cache stats - Total: ${stats.totalTasks}, Completed: ${stats.completedTasks}, Pending: ${stats.pendingTasks}`);
    }
}

// Initialize the singleton instance when the module is loaded.
// This ensures it's ready when the service starts.
ImagesTaskCache.getInstance();
