package com.test.musichouduan.repository;

import com.test.musichouduan.entity.Singer;
import com.test.musichouduan.entity.SingerType;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

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

/**
 * 歌手数据访问层
 */
@Repository
public interface SingerRepository extends JpaRepository<Singer, Long>, JpaSpecificationExecutor<Singer> {

    @Query("SELECT st.name, COUNT(s) FROM Singer s JOIN s.type st GROUP BY st.name")
    List<Object[]> countBySingerType();

    /**
     * 根据类型统计歌手数量
     *
     * @param type 歌手类型
     * @return 歌手数量
     */
    long countByType(SingerType type);

    /**
     * 根据名称查找歌手
     *
     * @param name 名称
     * @return 歌手
     */
    Optional<Singer> findByName(String name);

    /**
     * 根据类型查找歌手
     *
     * @param type 类型
     * @param pageable 分页
     * @return 歌手列表
     */
    Page<Singer> findByType(SingerType type, Pageable pageable);

    /**
     * 根据名称模糊查询歌手
     *
     * @param name 名称
     * @param pageable 分页
     * @return 歌手列表
     */
    Page<Singer> findByNameContaining(String name, Pageable pageable);

    /**
     * 查询最新的歌手
     *
     * @param limit 限制数量
     * @return 歌手列表
     */
    @Query(value = "SELECT s FROM Singer s ORDER BY s.createTime DESC")
    List<Singer> findLatest(Pageable pageable);

    /**
     * 查询热门歌手（按照音乐数量排序）
     *
     * @param pageable 分页
     * @return 歌手列表
     */
    @Query(value = "SELECT s.* FROM singer s LEFT JOIN (SELECT singer_id, COUNT(*) as music_count FROM music_singer GROUP BY singer_id) ms ON s.id = ms.singer_id ORDER BY COALESCE(ms.music_count, 0) DESC", nativeQuery = true)
    List<Singer> findHotSingers(Pageable pageable);

    /**
     * 检查是否存在指定类型的歌手
     *
     * @param type 歌手类型
     * @return 是否存在
     */
    boolean existsByType(SingerType type);
}
