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

import com.qqchen.deploy.backend.deploy.converter.RepositoryGroupConverter;
import com.qqchen.deploy.backend.deploy.entity.ExternalSystem;
import com.qqchen.deploy.backend.deploy.entity.RepositoryGroup;
import com.qqchen.deploy.backend.deploy.dto.RepositoryGroupDTO;
import com.qqchen.deploy.backend.deploy.integration.IGitServiceIntegration;
import com.qqchen.deploy.backend.deploy.integration.response.GitGroupResponse;
import com.qqchen.deploy.backend.deploy.query.RepositoryGroupQuery;
import com.qqchen.deploy.backend.deploy.repository.IExternalSystemRepository;
import com.qqchen.deploy.backend.deploy.repository.IRepositoryGroupRepository;
import com.qqchen.deploy.backend.deploy.service.IRepositoryGroupService;
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
import com.qqchen.deploy.backend.framework.exception.BusinessException;
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
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 java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * Git仓库组服务实现
 */
@Slf4j
@Service
public class RepositoryGroupServiceImpl extends BaseServiceImpl<RepositoryGroup, RepositoryGroupDTO, RepositoryGroupQuery, Long> implements IRepositoryGroupService {

    @Resource
    private IExternalSystemRepository externalSystemRepository;

    @Resource
    private IRepositoryGroupRepository repositoryGroupRepository;

    @Resource
    private IGitServiceIntegration gitServiceIntegration;

    @Resource
    private RepositoryGroupConverter repositoryGroupConverter;

    @Override
    @Transactional
    public Integer syncGroups(Long externalSystemId) {
        // 1. 获取外部系统信息
        ExternalSystem externalSystem = externalSystemRepository.findById(externalSystemId)
            .orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND));

        // 2. 从Git API获取所有仓库组信息
        List<GitGroupResponse> remoteGroups = gitServiceIntegration.groups(externalSystem);
        if (remoteGroups.isEmpty()) {
            log.info("No groups found in remote git system: {}", externalSystem.getName());
            return 0;
        }

        try {
            // 3. 获取本地已存在的仓库组
            List<RepositoryGroup> existingGroups = repositoryGroupRepository.findByExternalSystemIdAndDeletedFalse(externalSystemId);
            Map<Long, RepositoryGroup> existingGroupMap = existingGroups.stream()
                .collect(Collectors.toMap(RepositoryGroup::getRepoGroupId, Function.identity()));

            // 4. 处理每个远程仓库组
            List<RepositoryGroup> groupsToSave = new ArrayList<>();
            for (GitGroupResponse remoteGroup : remoteGroups) {
                RepositoryGroup group = existingGroupMap.getOrDefault(remoteGroup.getId(), new RepositoryGroup());
                
                // 更新基本信息
                group.setExternalSystemId(externalSystemId);
                group.setRepoGroupId(remoteGroup.getId());
                group.setName(remoteGroup.getName());
                group.setPath(remoteGroup.getPath());
                group.setDescription(remoteGroup.getDescription());
                group.setVisibility(remoteGroup.getVisibility());
                group.setWebUrl(remoteGroup.getWebUrl());
                group.setAvatarUrl(remoteGroup.getAvatarUrl());
                group.setParentId(remoteGroup.getParentId());
                
                // 设置完整名称和路径
                group.setFullName(remoteGroup.getFullName());
                group.setFullPath(remoteGroup.getFullPath());
                
                groupsToSave.add(group);
            }

            // 5. 保存所有仓库组
            List<RepositoryGroup> savedGroups = repositoryGroupRepository.saveAll(groupsToSave);
            
            log.info("Successfully synchronized {} groups for external system: {}", 
                savedGroups.size(), externalSystem.getName());
            return savedGroups.size();
            
        } catch (Exception e) {
            log.error("Failed to sync repository groups for external system: {}", externalSystemId, e);
            throw new BusinessException(ResponseCode.REPOSITORY_SYNC_FAILED);
        }
    }

    @Override
    public Long countByExternalSystemId(Long externalSystemId) {
        return repositoryGroupRepository.countByExternalSystemId(externalSystemId);
    }

    @Override
    public List<RepositoryGroupDTO> findByExternalSystemId(Long externalSystemId) {
        return repositoryGroupConverter.toDtoList(repositoryGroupRepository.findByExternalSystemId(externalSystemId));
    }
} 