package com.qqchen.deploy.backend.deploy.repository;

import com.qqchen.deploy.backend.deploy.entity.TeamApplication;
import com.qqchen.deploy.backend.deploy.enums.BuildTypeEnum;
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.List;
import java.util.Optional;

/**
 * 团队应用关联Repository
 *
 * @author qqchen
 * @since 2025-10-31
 */
@Repository
public interface ITeamApplicationRepository extends IBaseRepository<TeamApplication, Long> {

    /**
     * 统计团队的应用配置数量（不去重，物理删除无需deleted条件）
     */
    Long countByTeamId(Long teamId);

    /**
     * 统计应用被哪些团队关联
     */
    Long countByApplicationIdAndDeletedFalse(Long applicationId);

    /**
     * 检查团队应用环境组合是否已存在
     */
    boolean existsByTeamIdAndApplicationIdAndEnvironmentIdAndDeletedFalse(Long teamId, Long applicationId, Long environmentId);

    /**
     * 根据团队ID、应用ID和环境ID查询
     */
    Optional<TeamApplication> findByTeamIdAndApplicationIdAndEnvironmentIdAndDeletedFalse(Long teamId, Long applicationId, Long environmentId);

    /**
     * 统计使用指定环境的不同团队数量（去重 team_id）
     * 使用原生查询：SELECT COUNT(DISTINCT team_id) FROM deploy_team_application WHERE environment_id = ?
     */
    @Query("SELECT COUNT(DISTINCT ta.teamId) FROM TeamApplication ta WHERE ta.environmentId = :environmentId")
    Long countDistinctTeamIdByEnvironmentId(@Param("environmentId") Long environmentId);

    /**
     * 统计指定环境关联的不同应用数量（去重 application_id）
     * 使用原生查询：SELECT COUNT(DISTINCT application_id) FROM deploy_team_application WHERE environment_id = ?
     */
    @Query("SELECT COUNT(DISTINCT ta.applicationId) FROM TeamApplication ta WHERE ta.environmentId = :environmentId")
    Long countDistinctApplicationIdByEnvironmentId(@Param("environmentId") Long environmentId);

    /**
     * 统计指定团队可访问的不同环境数量（去重 environment_id）
     */
    @Query("SELECT COUNT(DISTINCT ta.environmentId) FROM TeamApplication ta WHERE ta.teamId = :teamId")
    Long countDistinctEnvironmentIdByTeamId(@Param("teamId") Long teamId);

    /**
     * 统计指定团队关联的不同应用数量（去重 application_id）
     */
    @Query("SELECT COUNT(DISTINCT ta.applicationId) FROM TeamApplication ta WHERE ta.teamId = :teamId")
    Long countDistinctApplicationIdByTeamId(@Param("teamId") Long teamId);

    /**
     * 统计指定应用被多少个不同团队使用（去重 team_id）
     */
    @Query("SELECT COUNT(DISTINCT ta.teamId) FROM TeamApplication ta WHERE ta.applicationId = :applicationId")
    Long countDistinctTeamIdByApplicationId(@Param("applicationId") Long applicationId);

    /**
     * 批量统计应用被多少个不同团队使用（用于解决N+1查询问题）
     * @param applicationIds 应用ID集合
     * @return Object数组列表，[0]=applicationId, [1]=teamCount
     */
    @Query("SELECT ta.applicationId as applicationId, COUNT(DISTINCT ta.teamId) as teamCount " +
           "FROM TeamApplication ta " +
           "WHERE ta.applicationId IN :applicationIds " +
           "GROUP BY ta.applicationId")
    List<Object[]> countDistinctTeamIdByApplicationIds(@Param("applicationIds") Collection<Long> applicationIds);

    /**
     * 批量根据团队ID查询应用配置
     *
     * @param teamIds 团队ID集合
     * @return 团队应用配置列表
     */
    List<TeamApplication> findByTeamIdIn(Collection<Long> teamIds);

    /**
     * 统计指定团队在指定环境下的应用数量
     *
     * @param teamId 团队ID
     * @param environmentId 环境ID
     * @return 应用数量
     */
    Long countByTeamIdAndEnvironmentId(Long teamId, Long environmentId);

    /**
     * 统计指定团队列表在指定环境下的不同应用数量（去重 application_id）
     *
     * @param teamIds 团队ID列表
     * @param environmentId 环境ID
     * @return 应用数量
     */
    @Query("SELECT COUNT(DISTINCT ta.applicationId) FROM TeamApplication ta WHERE ta.teamId IN :teamIds AND ta.environmentId = :environmentId")
    Long countDistinctApplicationIdByTeamIdsAndEnvironmentId(@Param("teamIds") Collection<Long> teamIds, @Param("environmentId") Long environmentId);
    
    /**
     * 根据部署系统ID查询所有团队应用（用于构建通知）
     *
     * @param deploySystemId 部署系统ID（Jenkins系统）
     * @return 团队应用列表
     */
    List<TeamApplication> findByDeploySystemId(Long deploySystemId);

    /**
     * 根据部署系统ID和构建类型查询团队应用（用于Jenkins构建通知）
     *
     * @param deploySystemId 部署系统ID（Jenkins系统）
     * @param buildType 构建类型
     * @return 团队应用列表
     */
    List<TeamApplication> findByDeploySystemIdAndBuildType(Long deploySystemId, BuildTypeEnum buildType);

    /**
     * 检查指定团队和环境下是否已存在使用该 Jenkins Job 的配置
     *
     * @param teamId 团队ID
     * @param environmentId 环境ID
     * @param deployJob Jenkins Job 名称
     * @return 是否存在
     */
    boolean existsByTeamIdAndEnvironmentIdAndDeployJobAndDeletedFalse(Long teamId, Long environmentId, String deployJob);
}

