package com.test.musichouduan.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaIgnore;
import com.test.musichouduan.dto.PageResult;
import com.test.musichouduan.dto.PlaylistDTO;
import com.test.musichouduan.dto.Result;
import com.test.musichouduan.service.PlaylistService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * 歌单控制器
 */
@RestController
@RequestMapping("/api/playlist")
public class PlaylistController {
    private static final String HOT_PLAYLIST_CACHE_KEY = "playlist:hot_list";
    @Autowired
    private PlaylistService playlistService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 根据ID获取歌单
     *
     * @param id 歌单ID
     * @return 响应结果
     */
    @SaIgnore
    @GetMapping("/{id}")
    public Result<PlaylistDTO> getPlaylistById(@PathVariable Long id) {
        PlaylistDTO playlistDTO = playlistService.getPlaylistById(id);
        return Result.success(playlistDTO);
    }

    /**
     * 分页获取歌单列表
     *
     * @param page 页码
     * @param size 每页大小
     * @param keyword 关键字
     * @param typeId 类型ID
     * @return 响应结果
     */
    @SaIgnore
    @GetMapping("/list")
    public Result<PageResult<PlaylistDTO>> getPlaylistList(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) Long typeId) {
        PageResult<PlaylistDTO> pageResult = playlistService.getPlaylistList(page, size, keyword, typeId);
        return Result.success(pageResult);
    }

    /**
     * 获取最新歌单列表
     *
     * @param limit 限制数量
     * @return 响应结果
     */
    @SaIgnore
    @GetMapping("/latest")
    public Result<List<PlaylistDTO>> getLatestPlaylist(@RequestParam(defaultValue = "10") Integer limit) {
        List<PlaylistDTO> playlistList = playlistService.getLatestPlaylist(limit);
        return Result.success(playlistList);
    }

    /**
     * 获取热门歌单列表
     *
     * @param limit 限制数量
     * @return 响应结果
     */
    @SaIgnore
    @GetMapping("/hot")
    public Result<List<PlaylistDTO>> getHotPlaylist(@RequestParam(defaultValue = "10") Integer limit) {
        List<PlaylistDTO> playlistList = playlistService.getHotPlaylist(limit);
        return Result.success(playlistList);
    }

    /**
     * 搜索歌单
     *
     * @param keyword 关键字
     * @param page 页码
     * @param size 每页大小
     * @return 响应结果
     */
    @SaIgnore
    @GetMapping("/search")
    public Result<PageResult<PlaylistDTO>> searchPlaylist(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size) {
        PageResult<PlaylistDTO> pageResult = playlistService.getPlaylistList(page, size, keyword, null);
        return Result.success(pageResult);
    }

    /**
     * 获取官方歌单列表
     *
     * @param page 页码
     * @param size 每页大小
     * @return 响应结果
     */
    @SaIgnore
    @GetMapping("/official")
    public Result<PageResult<PlaylistDTO>> getOfficialPlaylist(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size) {
        PageResult<PlaylistDTO> pageResult = playlistService.getOfficialPlaylist(page, size);
        return Result.success(pageResult);
    }

    /**
     * 添加歌单
     *
     * @param playlistDTO 歌单DTO
     * @param cover 封面文件
     * @return 响应结果
     */
    @SaCheckLogin
    @PostMapping("/add")
    public Result<PlaylistDTO> addPlaylist(
            @RequestPart("playlist") PlaylistDTO playlistDTO,
            @RequestPart(value = "cover", required = false) MultipartFile cover) {
        PlaylistDTO result = playlistService.addPlaylist(playlistDTO, cover);
        redisTemplate.delete(HOT_PLAYLIST_CACHE_KEY);
        playlistService.getHotPlaylist(50);
        return Result.success("添加成功", result);
    }

    /**
     * 更新歌单
     *
     * @param id 歌单ID
     * @param playlistDTO 歌单DTO
     * @param cover 封面文件
     * @return 响应结果
     */
    @SaCheckLogin
    @PutMapping("/{id}")
    public Result<PlaylistDTO> updatePlaylist(
            @PathVariable Long id,
            @RequestPart("playlist") PlaylistDTO playlistDTO,
            @RequestPart(value = "cover", required = false) MultipartFile cover) {
        PlaylistDTO result = playlistService.updatePlaylist(id, playlistDTO, cover);
        redisTemplate.delete(HOT_PLAYLIST_CACHE_KEY);
        playlistService.getHotPlaylist(50);
        return Result.success("更新成功", result);
    }

    /**
     * 删除歌单
     *
     * @param id 歌单ID
     * @return 响应结果
     */
    @SaCheckLogin
    @DeleteMapping("/{id}")
    public Result<Boolean> deletePlaylist(@PathVariable Long id) {
        boolean result = playlistService.deletePlaylist(id);
        redisTemplate.delete(HOT_PLAYLIST_CACHE_KEY);
        playlistService.getHotPlaylist(50);
        return Result.success("删除成功", result);
    }

    /**
     * 收藏歌单
     *
     * @param id 歌单ID
     * @return 响应结果
     */
    @SaCheckLogin
    @PostMapping("/{id}/collect")
    public Result<Boolean> collectPlaylist(@PathVariable Long id) {
        boolean result = playlistService.collectPlaylist(id);
        return Result.success("收藏成功", result);
    }

    /**
     * 取消收藏歌单
     *
     * @param id 歌单ID
     * @return 响应结果
     */
    @SaCheckLogin
    @DeleteMapping("/{id}/collect")
    public Result<Boolean> uncollectPlaylist(@PathVariable Long id) {
        boolean result = playlistService.uncollectPlaylist(id);
        return Result.success("取消收藏成功", result);
    }

    /**
     * 检查当前用户是否收藏了该歌单
     *
     * @param id 歌单ID
     * @return 响应结果
     */
    @SaCheckLogin
    @GetMapping("/{id}/is-collected")
    public Result<Boolean> isCollected(@PathVariable Long id) {
        boolean result = playlistService.isCollected(id);
        return Result.success(result);
    }

    /**
     * 获取用户收藏的歌单列表
     *
     * @param page 页码
     * @param size 每页大小
     * @return 响应结果
     */
    @SaCheckLogin
    @GetMapping("/collect")
    public Result<PageResult<PlaylistDTO>> getCollectedPlaylist(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size) {
        PageResult<PlaylistDTO> pageResult = playlistService.getCollectedPlaylist(page, size);
        return Result.success(pageResult);
    }

    /**
     * 获取用户创建的歌单列表
     *
     * @param page 页码
     * @param size 每页大小
     * @return 响应结果
     */
    @SaCheckLogin
    @GetMapping("/user")
    public Result<PageResult<PlaylistDTO>> getUserPlaylist(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size) {
        PageResult<PlaylistDTO> pageResult = playlistService.getUserPlaylist(page, size);
        return Result.success(pageResult);
    }

    /**
     * 向歌单添加音乐
     *
     * @param id 歌单ID
     * @param musicId 音乐ID
     * @return 响应结果
     */
    @SaCheckLogin
    @PostMapping("/{id}/music/{musicId}")
    public Result<Boolean> addMusicToPlaylist(@PathVariable Long id, @PathVariable Long musicId) {
        boolean result = playlistService.addMusicToPlaylist(id, musicId);
        return Result.success("添加成功", result);
    }

    /**
     * 从歌单移除音乐
     *
     * @param id 歌单ID
     * @param musicId 音乐ID
     * @return 响应结果
     */
    @SaCheckLogin
    @DeleteMapping("/{id}/music/{musicId}")
    public Result<Boolean> removeMusicFromPlaylist(@PathVariable Long id, @PathVariable Long musicId) {
        boolean result = playlistService.removeMusicFromPlaylist(id, musicId);
        return Result.success("移除成功", result);
    }

    /**
     * 播放歌单
     *
     * @param id 歌单ID
     * @return 响应结果
     */
    @PostMapping("/{id}/play")
    public Result<PlaylistDTO> playPlaylist(@PathVariable Long id) {
        PlaylistDTO playlistDTO = playlistService.playPlaylist(id);
        return Result.success(playlistDTO);
    }
}
