package com.usky.issue.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.usky.issue.domain.IssueCloudConfig;
import com.usky.issue.domain.IssueSyncData;
import com.usky.issue.mapper.IssueSyncDataMapper;
import com.usky.issue.service.CloudConfigService;
import com.usky.issue.service.CloudSyncReceiveService;
import com.usky.issue.service.LocalPullService;
import com.usky.issue.service.LocalPushService;
import com.usky.issue.service.LocalSyncAgent;
import com.usky.issue.service.enums.SyncDirection;
import com.usky.issue.service.enums.SyncTypeEnum;
import com.usky.issue.service.vo.SyncResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 本地同步 Agent 实现
 *
 * @author fyc
 * @date 2026-06-08
 */
@Slf4j
@Component
public class LocalSyncAgentImpl implements LocalSyncAgent {

    @Autowired
    private LocalPushService pushService;
    @Autowired
    private LocalPullService pullService;
    @Autowired
    private IssueSyncDataMapper syncDataMapper;
    @Autowired
    private CloudSyncReceiveService cloudSyncReceiveService;
    @Autowired
    private CloudConfigService cloudConfigService;

    @Scheduled(fixedDelayString = "${sync.push.fixed-delay-ms:5000}")
    public void autoPush() {
        try {
            IssueCloudConfig config = cloudConfigService.requireActiveConfig();
            for (SyncTypeEnum type : SyncTypeEnum.values()) {
                pushService.pushAllPending(type.getCode(), config);
            }
        } catch (Exception e) {
            log.debug("自动推送跳过: {}", e.getMessage());
        }
    }

    @Override
    public SyncResult executeSync(SyncTypeEnum syncType, IssueCloudConfig config,
                                  SyncDirection direction, boolean fullSync) {
        String tableName = syncType.getCode();
        SyncResult result = SyncResult.empty();

        if (direction == SyncDirection.UP || direction == SyncDirection.BOTH) {
            if (fullSync) {
                pushService.resetCursor(config.getTenantId(), tableName);
            }
            result.merge(pushService.pushByTenant(config.getTenantId(), tableName, config));
        }
        if (direction == SyncDirection.DOWN || direction == SyncDirection.BOTH) {
            if (fullSync) {
                pullService.resetDownCursor(config.getTenantId(), tableName);
            }
            result.merge(pullService.pullByTenant(config.getTenantId(), tableName, config, fullSync));
        }
        return result;
    }

    @Override
    public int countPending(SyncTypeEnum syncType, IssueCloudConfig config, SyncDirection direction) {
        if (config == null || config.getTenantId() == null) {
            return 0;
        }
        String tableName = syncType.getCode();
        int count = 0;
        if (direction == SyncDirection.UP || direction == SyncDirection.BOTH) {
            Integer upCount = syncDataMapper.selectCount(new LambdaQueryWrapper<IssueSyncData>()
                    .eq(IssueSyncData::getTenantId, config.getTenantId())
                    .eq(IssueSyncData::getTableName, tableName)
                    .in(IssueSyncData::getSyncStatus, 0, 2)
                    .eq(IssueSyncData::getIsDeleted, 0));
            count += upCount == null ? 0 : upCount;
        }
        if (direction == SyncDirection.DOWN || direction == SyncDirection.BOTH) {
            count += cloudSyncReceiveService.countPendingDownQueue(config.getTenantId(), tableName);
        }
        return count;
    }
}
