package com.qqchen.deploy.backend.deploy.service.impl;

import com.qqchen.deploy.backend.deploy.dto.GitInstanceDTO;
import com.qqchen.deploy.backend.deploy.dto.RepositoryGroupDTO;
import com.qqchen.deploy.backend.deploy.dto.RepositoryProjectDTO;
import com.qqchen.deploy.backend.deploy.dto.RepositorySyncHistoryDTO;
import com.qqchen.deploy.backend.deploy.entity.RepositorySyncHistory;
import com.qqchen.deploy.backend.deploy.enums.ExternalSystemSyncStatus;
import com.qqchen.deploy.backend.deploy.enums.RepositorySyncType;
import com.qqchen.deploy.backend.deploy.repository.IRepositorySyncHistoryRepository;
import com.qqchen.deploy.backend.deploy.service.*;
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
import com.qqchen.deploy.backend.framework.exception.BusinessException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static com.qqchen.deploy.backend.framework.enums.ResponseCode.REPOSITORY_BRANCH_SYNC_FAILED;
import static com.qqchen.deploy.backend.framework.enums.ResponseCode.REPOSITORY_PROJECT_SYNC_FAILED;

/**
 * Git管理服务实现
 */
@Slf4j
@Service
public class RepositoryManagerServiceImpl implements IRepositoryManagerService {

    @Resource
    private IRepositoryGroupService repositoryGroupService;

    @Resource
    private IRepositoryProjectService repositoryProjectService;

    @Resource
    private IRepositoryBranchService repositoryBranchService;

    @Resource
    private IRepositorySyncHistoryService repositorySyncHistoryService;

    @Resource
    private IRepositorySyncHistoryRepository repositorySyncHistoryRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncGroups(Long externalSystemId) {
        try {
            // 1. 创建同步历史记录
            RepositorySyncHistoryDTO groupHistory = repositorySyncHistoryService.createSyncHistory(externalSystemId, RepositorySyncType.GROUP);

            try {
                // 2. 同步组
                Integer groupCount = repositoryGroupService.syncGroups(externalSystemId);

                // 3. 更新同步历史记录为成功
                repositorySyncHistoryService.updateSyncHistory(groupHistory.getId(), ExternalSystemSyncStatus.SUCCESS, null);
                log.info("Successfully synchronized {} groups for external system: {}", groupCount, externalSystemId);
            } catch (Exception e) {
                // 4. 更新同步历史记录为失败
                repositorySyncHistoryService.updateSyncHistory(groupHistory.getId(), ExternalSystemSyncStatus.FAILED, e.getMessage());
                log.error("Failed to synchronize groups for external system: {}", externalSystemId, e);
                throw e;
            }
        } catch (Exception e) {
            log.error("Failed to create sync history for external system: {}", externalSystemId, e);
            throw new BusinessException(ResponseCode.REPOSITORY_GROUP_SYNC_FAILED);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncProjects(Long externalSystemId) {
        try {
            // 1. 创建同步历史记录
            RepositorySyncHistoryDTO projectHistory = repositorySyncHistoryService.createSyncHistory(externalSystemId, RepositorySyncType.PROJECT);

            try {
                // 2. 同步项目
                Integer projectCount = repositoryProjectService.syncProjects(externalSystemId);

                // 3. 更新同步历史记录为成功
                repositorySyncHistoryService.updateSyncHistory(projectHistory.getId(), ExternalSystemSyncStatus.SUCCESS, null);
                log.info("Successfully synchronized {} projects in external system: {}", projectCount, externalSystemId);
            } catch (Exception e) {
                // 4. 更新同步历史记录为失败
                repositorySyncHistoryService.updateSyncHistory(projectHistory.getId(), ExternalSystemSyncStatus.FAILED, e.getMessage());
                log.error("Failed to synchronize projects in external system: {}", externalSystemId, e);
                throw e;
            }
        } catch (Exception e) {
            log.error("Failed to create sync history for external system: {}", externalSystemId, e);
            throw new BusinessException(REPOSITORY_PROJECT_SYNC_FAILED);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncBranches(Long externalSystemId) {
        try {
            // 1. 创建同步历史记录
            RepositorySyncHistoryDTO branchHistory = repositorySyncHistoryService.createSyncHistory(externalSystemId, RepositorySyncType.BRANCH);

            try {
                // 2. 同步分支
                Integer branchCount = repositoryBranchService.syncBranches(externalSystemId);

                // 3. 更新同步历史记录为成功
                repositorySyncHistoryService.updateSyncHistory(branchHistory.getId(), ExternalSystemSyncStatus.SUCCESS, null);
                log.info("Successfully synchronized {} branches for external system: {}", branchCount, externalSystemId);
            } catch (Exception e) {
                // 4. 更新同步历史记录为失败
                repositorySyncHistoryService.updateSyncHistory(branchHistory.getId(), ExternalSystemSyncStatus.FAILED, e.getMessage());
                log.error("Failed to synchronize branches for external system: {}", externalSystemId, e);
                throw e;
            }
        } catch (Exception e) {
            log.error("Failed to create sync history for external system: {}", externalSystemId, e);
            throw new BusinessException(REPOSITORY_BRANCH_SYNC_FAILED);
        }
    }

    @Override
    public GitInstanceDTO instance(Long externalSystemId) {
        // 1. 创建返回对象
        GitInstanceDTO instanceDTO = new GitInstanceDTO();

        // 2. 获取组列表
        List<RepositoryGroupDTO> groups = repositoryGroupService.findByExternalSystemId(externalSystemId);
        instanceDTO.setRepositoryGroupList(groups);
        instanceDTO.setTotalGroups(groups.size());

        // 3. 获取项目列表
        List<RepositoryProjectDTO> projects = repositoryProjectService.findByExternalSystemId(externalSystemId);
        instanceDTO.setRepositoryProjectList(projects);
        instanceDTO.setTotalProjects(projects.size());

        // 4. 获取分支总数
        Long totalBranches = repositoryBranchService.countByExternalSystemId(externalSystemId);
        instanceDTO.setTotalBranches(totalBranches.intValue());

        // 5. 获取最后同步时间
        RepositorySyncHistory lastGroupSync = repositorySyncHistoryRepository.findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc(
            externalSystemId, RepositorySyncType.GROUP, ExternalSystemSyncStatus.SUCCESS);
        if (lastGroupSync != null) {
            instanceDTO.setLastSyncGroupsTime(lastGroupSync.getEndTime());
        }

        RepositorySyncHistory lastProjectSync = repositorySyncHistoryRepository.findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc(
            externalSystemId, RepositorySyncType.PROJECT, ExternalSystemSyncStatus.SUCCESS);
        if (lastProjectSync != null) {
            instanceDTO.setLastSyncProjectsTime(lastProjectSync.getEndTime());
        }

        RepositorySyncHistory lastBranchSync = repositorySyncHistoryRepository.findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc(
            externalSystemId, RepositorySyncType.BRANCH, ExternalSystemSyncStatus.SUCCESS);
        if (lastBranchSync != null) {
            instanceDTO.setLastSyncBranchesTime(lastBranchSync.getEndTime());
        }

        return instanceDTO;
    }
} 