package com.test.musichouduan.repository;

import com.test.musichouduan.entity.Music;
import com.test.musichouduan.entity.MusicType;
import com.test.musichouduan.entity.Singer;
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;

/**
 * 音乐数据访问层
 */
@Repository
public interface MusicRepository extends JpaRepository<Music, Long>, JpaSpecificationExecutor<Music> {

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

    /**
     * 根据类型查询音乐
     *
     * @param type 类型
     * @param pageable 分页
     * @return 音乐列表
     */
    @Query("SELECT m FROM Music m JOIN m.types t WHERE t = :type")
    Page<Music> findByType(MusicType type, Pageable pageable);

    /**
     * 根据歌手查询音乐
     *
     * @param singer 歌手
     * @param pageable 分页
     * @return 音乐列表
     */
    @Query("SELECT m FROM Music m JOIN m.singers s WHERE s = :singer")
    Page<Music> findBySinger(Singer singer, Pageable pageable);

    /**
     * 根据歌手查询音乐
     *
     * @param singer 歌手
     * @param pageable 分页
     * @return 音乐列表
     */
    Page<Music> findBySingersContaining(Singer singer, Pageable pageable);

    /**
     * 统计歌手的音乐数量
     *
     * @param singer 歌手
     * @return 音乐数量
     */
    Long countBySingersContaining(Singer singer);

    /**
     * 检查是否存在指定类型的音乐
     *
     * @param type 音乐类型
     * @return 是否存在
     */
    boolean existsByTypesContaining(MusicType type);

    /**
     * 查询最新的音乐
     *
     * @param pageable 分页
     * @return 音乐列表
     */
    @Query("SELECT m FROM Music m ORDER BY m.createTime DESC")
    List<Music> findLatest(Pageable pageable);

    /**
     * 查询播放次数最多的音乐
     *
     * @param pageable 分页
     * @return 音乐列表
     */
    @Query("SELECT m FROM Music m ORDER BY m.playCount DESC")
    List<Music> findMostPlayed(Pageable pageable);

    /**
     * 统计包含指定类型的音乐数量
     *
     * @param type 音乐类型
     * @return 音乐数量
     */
    long countByTypesContaining(MusicType type);

    /**
     * 统计所有音乐的总播放量
     *
     * @return 总播放量
     */
    @Query("SELECT COALESCE(SUM(m.playCount), 0) FROM Music m")
    long sumPlayCount();

    /**
     * 统计各个音乐类型的音乐数量
     *
     * @return 音乐类型及其对应的音乐数量
     */
    @Query("SELECT t.name, COUNT(m) FROM Music m JOIN m.types t GROUP BY t.name ORDER BY COUNT(m) DESC")
    List<Object[]> countByMusicType();

    /**
     * 查询所有音乐，并立即加载关联的歌手信息
     *
     * @return 音乐列表
     */
    @Query("SELECT DISTINCT m FROM Music m LEFT JOIN FETCH m.singers")
    List<Music> findAllWithSingers();
}
