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

import com.qqchen.deploy.backend.deploy.entity.DeployRecord;
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

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

/**
 * 部署记录仓库
 *
 * @author qqchen
 * @since 2025-11-02
 */
@Repository
public interface IDeployRecordRepository extends IBaseRepository<DeployRecord, Long> {

    /**
     * 根据工作流实例ID查询部署记录
     */
    Optional<DeployRecord> findByWorkflowInstanceIdAndDeletedFalse(Long workflowInstanceId);

    /**
     * 根据业务标识查询部署记录
     */
    Optional<DeployRecord> findByBusinessKeyAndDeletedFalse(String businessKey);

    /**
     * 根据团队应用ID查询最新部署记录
     */
    Optional<DeployRecord> findFirstByTeamApplicationIdAndDeletedFalseOrderByCreateTimeDesc(Long teamApplicationId);

    /**
     * 根据应用ID和环境ID查询最新部署记录
     */
    Optional<DeployRecord> findFirstByApplicationIdAndEnvironmentIdAndDeletedFalseOrderByCreateTimeDesc(
            Long applicationId, Long environmentId);

    /**
     * 根据团队应用ID分页查询部署记录
     */
    Page<DeployRecord> findByTeamApplicationIdAndDeletedFalseOrderByCreateTimeDesc(
            Long teamApplicationId, Pageable pageable);

    /**
     * 根据应用ID和环境ID查询部署记录列表
     */
    List<DeployRecord> findByApplicationIdAndEnvironmentIdAndDeletedFalseOrderByCreateTimeDesc(
            Long applicationId, Long environmentId);

    /**
     * 批量查询部署统计信息（按团队应用ID分组）
     * 
     * 统计规则：
     * - 成功：SUCCESS状态
     * - 失败：FAILED/REJECTED/CANCELLED/TERMINATED/PARTIAL_SUCCESS状态，或CREATED状态超过30分钟仍未更新（视为启动失败）
     *   （REJECTED=审批被拒绝，PARTIAL_SUCCESS虽然工作流完成，但存在失败节点，视为部署不完整，计入失败）
     * - 运行中：RUNNING状态，或CREATED状态在30分钟内（视为正在启动）
     */
    @Query(value = "SELECT " +
           "  dr.team_application_id as teamApplicationId, " +
           "  COUNT(dr.id) as totalCount, " +
           "  SUM(CASE WHEN dr.status = 'SUCCESS' THEN 1 ELSE 0 END) as successCount, " +
           "  SUM(CASE WHEN dr.status IN ('FAILED', 'REJECTED', 'CANCELLED', 'TERMINATED', 'PARTIAL_SUCCESS') " +
           "    OR (dr.status = 'CREATED' AND TIMESTAMPDIFF(MINUTE, dr.create_time, NOW()) > 30) " +
           "    THEN 1 ELSE 0 END) as failedCount, " +
           "  SUM(CASE WHEN dr.status = 'RUNNING' " +
           "    OR (dr.status = 'CREATED' AND TIMESTAMPDIFF(MINUTE, dr.create_time, NOW()) <= 30) " +
           "    THEN 1 ELSE 0 END) as runningCount, " +
           "  MAX(dr.start_time) as lastDeployTime " +
           "FROM deploy_record dr " +
           "WHERE dr.team_application_id IN (:teamApplicationIds) AND dr.deleted = false " +
           "GROUP BY dr.team_application_id",
           nativeQuery = true)
    List<Object[]> findDeployStatisticsByTeamApplicationIds(
            @Param("teamApplicationIds") List<Long> teamApplicationIds);

    /**
     * 批量查询每个团队应用的最新部署记录（用于获取最新状态和部署人）
     * 使用原生SQL避免JPQL类型问题
     */
    @Query(value = "SELECT dr.* FROM deploy_record dr " +
           "INNER JOIN (" +
           "  SELECT team_application_id, MAX(id) as max_id " +
           "  FROM deploy_record " +
           "  WHERE team_application_id IN (:teamApplicationIds) " +
           "    AND deleted = false " +
           "  GROUP BY team_application_id" +
           ") latest ON dr.id = latest.max_id " +
           "WHERE dr.deleted = false " +
           "ORDER BY dr.create_time DESC",
           nativeQuery = true)
    List<DeployRecord> findLatestDeployRecordsByTeamApplicationIds(
            @Param("teamApplicationIds") List<Long> teamApplicationIds);

    /**
     * 批量查询每个团队应用的最近N条部署记录
     * 使用原生SQL实现（MySQL支持窗口函数）
     */
    @Query(value = "SELECT * FROM (" +
           "  SELECT dr.*, " +
           "    ROW_NUMBER() OVER (PARTITION BY dr.team_application_id ORDER BY dr.create_time DESC) as rn " +
           "  FROM deploy_record dr " +
           "  WHERE dr.team_application_id IN :teamApplicationIds " +
           "    AND dr.deleted = false" +
           ") ranked " +
           "WHERE ranked.rn <= :limit " +
           "ORDER BY ranked.team_application_id, ranked.create_time DESC",
           nativeQuery = true)
    List<DeployRecord> findRecentDeployRecordsByTeamApplicationIds(
            @Param("teamApplicationIds") List<Long> teamApplicationIds,
            @Param("limit") int limit);

    /**
     * 根据团队应用ID查询所有部署记录（包括已删除的）
     * 用于级联删除
     */
    List<DeployRecord> findByTeamApplicationId(Long teamApplicationId);
}

