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

import com.qqchen.deploy.backend.deploy.converter.EnvironmentConverter;
import com.qqchen.deploy.backend.deploy.dto.EnvironmentDTO;
import com.qqchen.deploy.backend.deploy.entity.Environment;
import com.qqchen.deploy.backend.deploy.entity.QEnvironment;
import com.qqchen.deploy.backend.deploy.entity.TeamEnvironmentConfig;
import com.qqchen.deploy.backend.deploy.query.EnvironmentQuery;
import com.qqchen.deploy.backend.deploy.repository.IEnvironmentRepository;
import com.qqchen.deploy.backend.deploy.repository.ITeamApplicationRepository;
import com.qqchen.deploy.backend.deploy.repository.ITeamEnvironmentConfigRepository;
import com.qqchen.deploy.backend.deploy.service.IEnvironmentService;
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 com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import jakarta.persistence.EntityManager;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 环境服务实现类
 */
@Slf4j
@Service
public class EnvironmentServiceImpl extends BaseServiceImpl<Environment, EnvironmentDTO, EnvironmentQuery, Long> implements IEnvironmentService {

    @Resource
    private IEnvironmentRepository environmentRepository;

    @Resource
    private EnvironmentConverter environmentConverter;

    @Resource
    private EntityManager entityManager;

    @Resource
    private ITeamApplicationRepository teamApplicationRepository;

    @Resource
    private ITeamEnvironmentConfigRepository teamEnvironmentConfigRepository;

    @Override
    public Page<EnvironmentDTO> page(EnvironmentQuery query) {
        Page<EnvironmentDTO> page = super.page(query);
        
        // 填充统计数据
        List<EnvironmentDTO> content = page.getContent().stream()
                .peek(env -> fillEnvironmentStatistics(env))
                .collect(Collectors.toList());
        
        return new PageImpl<>(content, page.getPageable(), page.getTotalElements());
    }

    @Override
    public List<EnvironmentDTO> findAll(EnvironmentQuery query) {
        List<EnvironmentDTO> list = super.findAll(query);
        
        // 填充统计数据
        return list.stream()
                .peek(env -> fillEnvironmentStatistics(env))
                .collect(Collectors.toList());
    }

    /**
     * 填充环境统计数据
     * <p>统计逻辑基于 deploy_team_environment_config 表，只统计已配置该环境的团队</p>
     */
    private void fillEnvironmentStatistics(EnvironmentDTO env) {
        // 1. 统计配置了该环境的团队数量
        Long teamCount = teamEnvironmentConfigRepository.countByEnvironmentId(env.getId());
        env.setTeamCount(teamCount != null ? teamCount : 0L);
        
        // 2. 统计这些团队在该环境下的应用数量（去重）
        if (teamCount != null && teamCount > 0) {
            // 查询配置了该环境的所有团队ID
            List<Long> teamIds = teamEnvironmentConfigRepository.findByEnvironmentId(env.getId())
                    .stream()
                    .map(config -> config.getTeamId())
                    .collect(Collectors.toList());
            
            if (!teamIds.isEmpty()) {
                Long appCount = teamApplicationRepository.countDistinctApplicationIdByTeamIdsAndEnvironmentId(teamIds, env.getId());
                env.setApplicationCount(appCount != null ? appCount : 0L);
            } else {
                env.setApplicationCount(0L);
            }
        } else {
            env.setApplicationCount(0L);
        }
    }

    @Override
    public List<EnvironmentDTO> getProjectEnvironments(Long projectGroupId) {
        QEnvironment environment = QEnvironment.environment;

        JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);

        List<Environment> environments = queryFactory
            .select(environment)
            .from(environment)
            .on(environment.id.eq(environment.id))
            .orderBy(environment.sort.asc())
            .fetch();

        return environments.stream()
            .map(environmentConverter::toDto)
            .collect(Collectors.toList());
    }

    @Override
    public void updateProjectEnvironments(Long projectId, List<Long> environmentIds) {
        // TODO: 实现更新逻辑
    }

    /**
     * 重写删除方法，删除前校验该环境是否被团队配置
     * 
     * @param id 环境ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        // 1. 查询环境是否存在
        Environment environment = environmentRepository.findById(id)
            .orElseThrow(() -> new BusinessException(ResponseCode.ENVIRONMENT_NOT_FOUND, new Object[]{id}));
        
        // 2. 校验该环境是否被团队配置（通过 TeamEnvironmentConfig）
        Long teamCount = teamEnvironmentConfigRepository.countByEnvironmentId(id);
        
        if (teamCount != null && teamCount > 0) {
            log.warn("删除环境失败: 环境 {} ({}) 已被 {} 个团队配置", 
                environment.getEnvName(), id, teamCount);
            throw new BusinessException(ResponseCode.ENVIRONMENT_HAS_TEAMS, new Object[]{teamCount});
        }
        
        // 3. 执行删除（逻辑删除）
        super.delete(id);
        log.info("成功删除环境: id={}, name={}", id, environment.getEnvName());
    }
}