package com.datai.integration.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.stereotype.Service;

import com.datai.integration.model.domain.SyncProgress;
import com.datai.integration.service.ISyncProgressService;

import lombok.extern.slf4j.Slf4j;

/**
 * 同步进度Service业务层处理
 * 
 * 使用 ConcurrentHashMap 存储进度信息，支持并发访问
 * 同步任务完成后立即清除进度信息，不保留历史记录
 * 
 * @author datai
 * @date 2026-01-16
 */
@Service
@Slf4j
public class SyncProgressServiceImpl implements ISyncProgressService
{
    private final Map<Integer, SyncProgress> progressMap = new ConcurrentHashMap<>();

    @Override
    public void startProgressTracking(Integer objectId, Integer totalBatches, String syncType)
    {
        SyncProgress progress = SyncProgress.builder()
            .objectId(objectId)
            .syncType(syncType)
            .totalBatches(totalBatches)
            .processedBatches(0)
            .currentBatch(0)
            .progressPercentage(0)
            .startTime(LocalDateTime.now())
            .status("RUNNING")
            .errorMessage(null)
            .build();

        progressMap.put(objectId, progress);
        log.info("开始跟踪同步进度，objectId: {}, totalBatches: {}, syncType: {}", objectId, totalBatches, syncType);
    }

    @Override
    public void updateProgress(Integer objectId, Integer processedBatches, Integer currentBatch)
    {
        SyncProgress progress = progressMap.get(objectId);
        if (progress != null)
        {
            progress.setProcessedBatches(processedBatches);
            progress.setCurrentBatch(currentBatch);

            if (progress.getTotalBatches() > 0)
            {
                int percentage = (int) ((processedBatches * 100) / progress.getTotalBatches());
                progress.setProgressPercentage(percentage);
            }

            log.debug("更新同步进度，objectId: {}, processedBatches: {}, currentBatch: {}, progressPercentage: {}%",
                objectId, processedBatches, currentBatch, progress.getProgressPercentage());
        }
        else
        {
            log.warn("未找到进度信息，objectId: {}", objectId);
        }
    }

    @Override
    public void completeProgress(Integer objectId)
    {
        SyncProgress progress = progressMap.get(objectId);
        if (progress != null)
        {
            progress.setEndTime(LocalDateTime.now());
            progress.setStatus("COMPLETED");
            progress.setProgressPercentage(100);

            log.info("同步完成，objectId: {}, progressPercentage: 100%", objectId);

            progressMap.remove(objectId);
            log.info("已清除同步进度信息，objectId: {}", objectId);
        }
        else
        {
            log.warn("未找到进度信息，objectId: {}", objectId);
        }
    }

    @Override
    public void failProgress(Integer objectId, String errorMessage)
    {
        SyncProgress progress = progressMap.get(objectId);
        if (progress != null)
        {
            progress.setEndTime(LocalDateTime.now());
            progress.setStatus("FAILED");
            progress.setErrorMessage(errorMessage);

            log.error("同步失败，objectId: {}, errorMessage: {}", objectId, errorMessage);

            progressMap.remove(objectId);
            log.info("已清除同步进度信息，objectId: {}", objectId);
        }
        else
        {
            log.warn("未找到进度信息，objectId: {}", objectId);
        }
    }

    @Override
    public SyncProgress getProgress(Integer objectId)
    {
        return progressMap.get(objectId);
    }

    @Override
    public Map<Integer, SyncProgress> getAllProgress()
    {
        return progressMap;
    }

    @Override
    public List<SyncProgress> getAllRunningProgress()
    {
        List<SyncProgress> runningProgressList = new ArrayList<>();
        for (SyncProgress progress : progressMap.values())
        {
            if ("RUNNING".equals(progress.getStatus()))
            {
                runningProgressList.add(progress);
            }
        }
        return runningProgressList;
    }
}
