package com.ruoyi.info.collection.utils;

import org.slf4j.Logger;

/**
 * 导入日志工具类
 * 提供统一的日志格式和进度计算
 *
 * @author ruoyi
 * @date 2026-02-11
 */
public class ImportLogUtils {

    /**
     * 记录导入开始
     *
     * @param log        日志记录器
     * @param taskId     任务ID
     * @param moduleName 模块名称
     * @param totalCount 总数据量
     * @param userName   操作人
     */
    public static void logImportStart(Logger log, String taskId, String moduleName,
                                       int totalCount, String userName) {
        log.info("[任务ID: {}] 开始异步导入{}，数据量: {}条，操作人: {}",
                taskId, moduleName, totalCount, userName);
    }

    /**
     * 记录批量查询开始
     *
     * @param log          日志记录器
     * @param taskId       任务ID
     * @param queryDesc    查询描述
     * @param queryCount   查询数量
     */
    public static void logBatchQueryStart(Logger log, String taskId, String queryDesc, int queryCount) {
        log.info("[任务ID: {}] 批量查询{}，查询数量: {}个", taskId, queryDesc, queryCount);
    }

    /**
     * 记录批量查询完成
     *
     * @param log          日志记录器
     * @param taskId       任务ID
     * @param queryDesc    查询描述
     * @param existingCount 已存在数量
     */
    public static void logBatchQueryComplete(Logger log, String taskId, String queryDesc, int existingCount) {
        log.info("[任务ID: {}] 查询完成，已存在{}条", taskId, queryDesc, existingCount);
    }

    /**
     * 记录进度（智能判断是否需要输出）
     * 每100条或每10%输出一次
     *
     * @param log     日志记录器
     * @param taskId  任务ID
     * @param current 当前处理数
     * @param total   总数
     * @param success 成功数
     * @param failure 失败数
     */
    public static void logProgress(Logger log, String taskId, int current, int total,
                                   int success, int failure) {
        if (current <= 0) {
            return;
        }

        // 每100条或每10%输出一次进度
        boolean shouldLog = (current % 100 == 0) ||
                (current * 10 / total > (current - 1) * 10 / total) ||
                (current == total);

        if (shouldLog) {
            int progress = current * 100 / total;
            log.info("[任务ID: {}] 数据处理进度: {}/{} ({}%), 成功: {}条, 失败: {}条",
                    taskId, current, total, progress, success, failure);
        }
    }

    /**
     * 记录数据验证失败
     *
     * @param log       日志记录器
     * @param taskId    任务ID
     * @param rowNum    行号
     * @param errorMsg  错误消息
     * @param keyData   关键数据（可为null）
     */
    public static void logValidationError(Logger log, String taskId, int rowNum,
                                         String errorMsg, String keyData) {
        log.warn("[任务ID: {}] [第{}行] 数据验证失败: {}", taskId, rowNum, errorMsg);
        if (keyData != null && !keyData.isEmpty()) {
            log.warn("[任务ID: {}] 失败数据详情: {}", taskId, keyData);
        }
    }

    /**
     * 记录批量操作开始
     *
     * @param log       日志记录器
     * @param taskId    任务ID
     * @param operation 操作描述
     * @param totalBatch 总批次数
     * @param batchSize 每批大小
     */
    public static void logBatchOperationStart(Logger log, String taskId, String operation,
                                              int totalBatch, int batchSize) {
        log.info("[任务ID: {}] 开始批量{}，总批次: {}, 每批: {}条",
                taskId, operation, totalBatch, batchSize);
    }

    /**
     * 记录单个批次操作
     *
     * @param log       日志记录器
     * @param taskId    任务ID
     * @param operation 操作描述
     * @param batchNum  当前批次号
     * @param totalBatch 总批次数
     * @param batchSize 本批数量
     */
    public static void logBatchOperation(Logger log, String taskId, String operation,
                                        int batchNum, int totalBatch, int batchSize) {
        log.info("[任务ID: {}] 执行批次 {}/{}, 本批数量: {}条",
                taskId, batchNum, totalBatch, batchSize);
    }

    /**
     * 记录单个批次完成
     *
     * @param log       日志记录器
     * @param taskId    任务ID
     * @param operation 操作描述
     * @param batchNum  当前批次号
     * @param totalBatch 总批次数
     * @param success   成功数量
     */
    public static void logBatchComplete(Logger log, String taskId, String operation,
                                       int batchNum, int totalBatch, int success) {
        log.info("[任务ID: {}] 批次 {}/{} {}完成，成功: {}条",
                taskId, batchNum, totalBatch, operation, success);
    }

    /**
     * 记录Redis缓存操作
     *
     * @param log       日志记录器
     * @param taskId    任务ID
     * @param operation 操作描述（如"保存失败记录"）
     * @param count     数量
     */
    public static void logRedisOperation(Logger log, String taskId, String operation, int count) {
        log.debug("[任务ID: {}] {}到Redis，数量: {}条", taskId, operation, count);
    }

    /**
     * 记录Redis缓存异常
     *
     * @param log       日志记录器
     * @param taskId    任务ID
     * @param operation 操作描述
     * @param e         异常
     */
    public static void logRedisError(Logger log, String taskId, String operation, Exception e) {
        log.error("[任务ID: {}] {}到Redis失败，不影响导入结果", taskId, operation, e);
    }

    /**
     * 记录导入完成
     *
     * @param log       日志记录器
     * @param taskId    任务ID
     * @param moduleName 模块名称
     * @param total     总数
     * @param success   成功数
     * @param failure   失败数
     * @param duration  耗时（毫秒）
     */
    public static void logImportComplete(Logger log, String taskId, String moduleName,
                                         int total, int success, int failure, long duration) {
        log.info("[任务ID: {}] {}导入完成！总数: {}条, 成功: {}条, 失败: {}条, 耗时: {}ms",
                taskId, moduleName, total, success, failure, duration);

        // 如果有失败，记录失败汇总
        if (failure > 0) {
            log.warn("[任务ID: {}] 导入完成，但有{}条数据失败，请查看失败记录详情", taskId, failure);
        }
    }

    /**
     * 记录异常
     *
     * @param log       日志记录器
     * @param taskId    任务ID
     * @param errorMsg  错误描述
     * @param e         异常
     */
    public static void logException(Logger log, String taskId, String errorMsg, Exception e) {
        log.error("[任务ID: {}] {}", taskId, errorMsg, e);
    }

    /**
     * 记录事务回滚
     *
     * @param log       日志记录器
     * @param taskId    任务ID
     * @param processed 已处理数量
     * @param total     总数量
     * @param success   成功数量
     * @param failure   失败数量
     * @param e         异常
     */
    public static void logTransactionRollback(Logger log, String taskId, int processed,
                                             int total, int success, int failure, Exception e) {
        log.error("[任务ID: {}] 导入失败，事务已回滚。已处理: {}/{}条", taskId, processed, total, e);
        log.error("[任务ID: {}] 回滚前统计 - 新增: {}条, 失败: {}条", taskId, success, failure);
    }

    /**
     * 记录唯一性冲突
     *
     * @param log       日志记录器
     * @param taskId    任务ID
     * @param rowNum    行号
     * @param conflictDesc 冲突描述
     */
    public static void logUniqueConflict(Logger log, String taskId, int rowNum, String conflictDesc) {
        log.warn("[任务ID: {}] [第{}行] {}", taskId, rowNum, conflictDesc);
    }

    /**
     * 记录失败原因统计
     *
     * @param log       日志记录器
     * @param taskId    任务ID
     * @param errorStats 错误统计Map
     */
    public static void logErrorStatistics(Logger log, String taskId, java.util.Map<String, Long> errorStats) {
        if (errorStats != null && !errorStats.isEmpty()) {
            String statsStr = errorStats.entrySet().stream()
                    .map(entry -> entry.getKey() + "=" + entry.getValue() + "条")
                    .collect(java.util.stream.Collectors.joining(", "));
            log.warn("[任务ID: {}] 失败原因统计: {}", taskId, statsStr);
        }
    }
}
