package com.magistr.app.repository;

import com.magistr.app.model.Subgroup;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

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

public interface SubgroupRepository extends JpaRepository<Subgroup, Long> {

    interface SubgroupGroupReference {
        Long getSubgroupId();

        Long getGroupId();
    }

    @Query("""
            select subgroup
            from Subgroup subgroup
            join fetch subgroup.studentGroup studentGroup
            where subgroup.status <> 'ARCHIVED'
            order by studentGroup.name, subgroup.name
            """)
    List<Subgroup> findAllWithGroupsOrderByGroupNameAndName();

    @Query("""
            select subgroup
            from Subgroup subgroup
            join fetch subgroup.studentGroup
            where subgroup.studentGroup.id = :groupId
              and subgroup.status <> 'ARCHIVED'
            order by subgroup.name
            """)
    List<Subgroup> findByStudentGroupIdOrderByNameAsc(@Param("groupId") Long groupId);

    @Query("""
            select subgroup
            from Subgroup subgroup
            join fetch subgroup.studentGroup
            where subgroup.id = :id
              and subgroup.studentGroup.id = :groupId
            """)
    Optional<Subgroup> findByIdAndStudentGroupId(@Param("id") Long id, @Param("groupId") Long groupId);

    @Query("""
            select case when count(subgroup) > 0 then true else false end
            from Subgroup subgroup
            where subgroup.studentGroup.id = :groupId
              and lower(subgroup.name) = lower(:name)
              and subgroup.status <> 'ARCHIVED'
            """)
    boolean existsByStudentGroupIdAndNameIgnoreCase(@Param("groupId") Long groupId, @Param("name") String name);

    @Query("""
            select coalesce(sum(subgroup.studentCapacity), 0)
            from Subgroup subgroup
            where subgroup.studentGroup.id = :groupId
              and subgroup.status <> 'ARCHIVED'
            """)
    Long sumActiveStudentCapacityByGroupId(@Param("groupId") Long groupId);

    @Query("""
            select coalesce(sum(subgroup.studentCapacity), 0)
            from Subgroup subgroup
            where subgroup.studentGroup.id = :groupId
              and subgroup.status <> 'ARCHIVED'
              and subgroup.id <> :excludedId
            """)
    Long sumActiveStudentCapacityByGroupIdExcludingId(@Param("groupId") Long groupId,
                                                      @Param("excludedId") Long excludedId);

    @Query("""
            select count(subgroup)
            from Subgroup subgroup
            where subgroup.studentGroup.id = :groupId
              and subgroup.status <> 'ARCHIVED'
              and subgroup.id <> :excludedId
            """)
    long countActiveByGroupIdExcludingId(@Param("groupId") Long groupId,
                                         @Param("excludedId") Long excludedId);

    @Query("""
            select subgroup.id as subgroupId, subgroup.studentGroup.id as groupId
            from Subgroup subgroup
            where subgroup.id in :subgroupIds
            """)
    List<SubgroupGroupReference> findGroupReferencesByIdIn(@Param("subgroupIds") List<Long> subgroupIds);
}
