package com.yonge.cooleshow.admin.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Sets;
import com.microsvc.toolkit.common.response.paging.QueryInfo;
import com.yonge.cooleshow.admin.io.request.TenantAlbumVo;
import com.yonge.cooleshow.api.feign.dto.TenantWrapper;
import com.yonge.cooleshow.biz.dal.dto.search.StudentMusicSheetSearch;
import com.yonge.cooleshow.biz.dal.entity.*;
import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
import com.yonge.cooleshow.biz.dal.service.*;
import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.toolset.base.exception.BizException;
import com.yonge.toolset.base.page.PageInfo;
import com.yonge.toolset.mybatis.support.PageUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author：haonan
 * @Date：2023/7/27 18:26
 * @Filename：TenantAlbumController
 */

@RestController
@RequestMapping("/tenantAlbum")
@Api(value = "机构专辑管理", tags = "机构专辑管理")
public class TenantAlbumController {
    @Autowired
    TenantAlbumService tenantAlbumService;

    @Autowired
    private TenantAlbumMusicService tenantAlbumMusicService;

    @Autowired
    private TenantAlbumRefService tenantAlbumRefService;

    @Autowired
    private TenantInfoService tenantInfoService;

    @Autowired
    private MusicSheetService musicSheetService;

    @Autowired
    private SubjectService subjectService;

    @Autowired
    private MusicTagService musicTagService;

    /**
     * 查询分页
     *
     * @param query
     */
    @PostMapping("/page")
    @ApiOperation(value = "查询分页", notes = "tenantAlbum")
    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/page')")
    public HttpResponseResult<PageInfo<TenantAlbumWrapper.TenantAlbum>> page(@RequestBody TenantAlbumWrapper.TenantAlbumQuery query) {
        IPage<TenantAlbumWrapper.TenantAlbum> pages = tenantAlbumService.selectPage(QueryInfo.getPage(query), query);
        return HttpResponseResult.succeed(PageUtil.pageInfo(pages));
    }


    /**
     * 查询详情
     *
     * @param id 详情ID
     * @return TenantAlbum
     */
    @PostMapping("/detail")
    @ApiOperation(value = "查询详情", notes = "detail")
    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/detail')")
    public HttpResponseResult<TenantAlbumWrapper.TenantAlbum> detail(@RequestParam("id") Long id) {
        TenantAlbum tenantAlbum = tenantAlbumService.detail(id);
        if (tenantAlbum == null) {
            throw new BizException("专辑信息不存在");
        }

        TenantAlbumWrapper.TenantAlbum vo = JSON.parseObject(JSON.toJSONString(tenantAlbum),
                TenantAlbumWrapper.TenantAlbum.class);

        //查关联表
        TenantAlbumRef one = tenantAlbumRefService.lambdaQuery().eq(TenantAlbumRef::getTenantAlbumId, id)
                .last("limit 1").one();
        vo.setTenantId(one.getTenantId().toString());
        //查询曲目表

        TenantInfo tenantInfo = tenantInfoService.getById(one.getTenantId());
        vo.setTenantName(tenantInfo.getName());
        List<TenantAlbumMusic> tenantAlbumMusics = tenantAlbumMusicService.lambdaQuery()
                .eq(TenantAlbumMusic::getTenantAlbumId, id)
                .eq(TenantAlbumMusic::getDelFlag, false)
                .list();

        Map<SubjectTypeEnum, List<TenantAlbumMusic>> groupByType =
                tenantAlbumMusics.stream().collect(Collectors.groupingBy(TenantAlbumMusic::getSubjectType));


        List<Long> musicSheetIdlist = tenantAlbumMusics.stream().map(next -> next.getMusicSheetId()).distinct().collect(Collectors.toList());


        StudentMusicSheetSearch search = new StudentMusicSheetSearch();
        search.setMusicSheetIdlist(musicSheetIdlist);
        search.setPage(1);
        search.setRows(9999);
        IPage<MusicSheetVo> records = musicSheetService.selectStudentPage(PageUtil.getPage(search), search, null);
        Map<Long, MusicSheetVo> idMsMap = records.getRecords().stream()
                .collect(Collectors.toMap(MusicSheet::getId, Function.identity()));
        List<TenantAlbumWrapper.MusicSheetData> musicSheetData = vo.getMusicSheetData();
        groupByType.forEach((key, value) -> {
            value.sort(Comparator.comparing(TenantAlbumMusic::getSortNumber));
            TenantAlbumWrapper.MusicSheetData sheetData = new TenantAlbumWrapper.MusicSheetData();
            sheetData.setSubjectType(key);
            List<TenantAlbumWrapper.TenantAlbumSheet> tenantAlbumSheets = value.stream().map(next -> {

                TenantAlbumWrapper.TenantAlbumSheet tenantAlbumSheet = new TenantAlbumWrapper.TenantAlbumSheet();
                BeanUtils.copyProperties(next, tenantAlbumSheet);
                Long musicSheetId = tenantAlbumSheet.getMusicSheetId();
                MusicSheetVo musicSheet = idMsMap.getOrDefault(musicSheetId, new MusicSheetVo());
                tenantAlbumSheet.setMusicSheetName(musicSheet.getMusicSheetName());
                tenantAlbumSheet.setMusicTag(musicSheet.getMusicTag());
                tenantAlbumSheet.setComposer(musicSheet.getComposer());
                tenantAlbumSheet.setMusicSubject(musicSheet.getMusicSubject());
                return tenantAlbumSheet;
            }).collect(Collectors.toList());
            tenantAlbumSheets.stream().forEach(t->{
                String musicSubject = t.getMusicSubject();

                if (StringUtils.isNotBlank(musicSubject)){
                    //设置对应声部名称
                    List<Subject> subject = subjectService.findBySubjectByIdList(musicSubject);
                    if (CollectionUtils.isNotEmpty(subject)) {
                        t.setMusicSubjectName(subject.get(0).getName());
                    }
                }


                //设置对应标签名称
                String musicTag = t.getMusicTag();
                if (StringUtils.isNotBlank(musicTag)){
                    String[] split = musicTag.split(",");
                    for (String s : split) {
                        List<Long> list = new ArrayList<>();
                        list.add(Long.parseLong(s));
                        String tagName = musicTagService.getMusicTagNames(list);
                        t.setMusicTagName(tagName);
                    }
                }

            });


            sheetData.setTenantAlbumSheetList(tenantAlbumSheets);
            musicSheetData.add(sheetData);
            vo.setMusicSheetData(musicSheetData);
        });

        return HttpResponseResult.succeed(vo);
    }


    /**
     * 新增专辑
     */
    @PostMapping("/save")
    @ApiOperation(value = "新增专辑", notes = "新增专辑")
    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/save')")
    public HttpResponseResult<Boolean> save(@Validated @RequestBody TenantAlbumVo.TenantAlbum album) {

        // 检查曲目重复
        if (CollectionUtils.isNotEmpty(album.getMusicSheetData())) {
            List<Long> musicIds = album.getMusicSheetData().stream().flatMap(o -> o.getMusicSheetList().stream().map(m -> m.getId())).collect(Collectors.toList());
            Set<Long> musicSet = new HashSet<>(musicIds);
            if (musicSet.size() < musicIds.size()) {
                throw new BizException("不能添加相同的曲目");
            }
        }

        TenantAlbum tenantAlbum = JSON.parseObject(album.jsonString(), TenantAlbum.class);
        List<TenantAlbumVo.MusicSheetData> musicSheetData = album.getMusicSheetData();

        List<TenantAlbumWrapper.MusicSheetData> musicSheetDataList = musicSheetData.stream().map(next ->{
                    //TenantAlbumWrapper.MusicSheetData sheetData =new TenantAlbumWrapper.MusicSheetData();
                    TenantAlbumWrapper.MusicSheetData sheetData =new TenantAlbumWrapper.MusicSheetData();

                    List<TenantAlbumVo.MusicObject> musicSheetList = next.getMusicSheetList();
                    sheetData.getTenantAlbumSheetList().addAll( musicSheetList.stream().map(m->{
                        TenantAlbumWrapper.TenantAlbumSheet tenantAlbumSheet = new TenantAlbumWrapper.TenantAlbumSheet();
                        tenantAlbumSheet.setLevel(m.getLevel());
                        tenantAlbumSheet.setType(m.getType());
                        tenantAlbumSheet.setId(m.getId().toString());
                       return tenantAlbumSheet;
                    }).collect(Collectors.toList()));
                    sheetData.setSubjectType(next.getSubjectType());
                    return sheetData;
        }
        ).collect(Collectors.toList());
        tenantAlbumService.insertTenantAlbum(album.getTenantId(), tenantAlbum, musicSheetDataList);
        return HttpResponseResult.succeed();
    }

    @PostMapping("/update")
    @ApiOperation(value = "修改专辑", notes = "修改专辑")
    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/update')")
    public HttpResponseResult<Boolean> update( @RequestBody TenantAlbumVo.TenantAlbum album) {

        // 检查曲目重复
        if (CollectionUtils.isNotEmpty(album.getMusicSheetData())) {
            List<Long> musicIds = album.getMusicSheetData().stream().flatMap(o -> o.getMusicSheetList()
                    .stream().map(TenantAlbumVo.MusicObject::getId)).collect(Collectors.toList());
            Set<Long> musicSet = new HashSet<>(musicIds);
            if (musicSet.size() < musicIds.size()) {
                throw new BizException("不能添加相同的曲目");
            }
        }

        TenantAlbum tenantAlbum = JSON.parseObject(album.jsonString(), TenantAlbum.class);
        List<TenantAlbumVo.MusicSheetData> musicSheetData = album.getMusicSheetData();

        List<TenantAlbumWrapper.MusicSheetData> musicSheetDataList = musicSheetData.stream().map(next ->{
            //TenantAlbumWrapper.MusicSheetData sheetData =new TenantAlbumWrapper.MusicSheetData();
            TenantAlbumWrapper.MusicSheetData sheetData =new TenantAlbumWrapper.MusicSheetData();

            List<TenantAlbumVo.MusicObject> musicSheetList = next.getMusicSheetList();
            sheetData.getTenantAlbumSheetList().addAll( musicSheetList.stream().map(m->{
                TenantAlbumWrapper.TenantAlbumSheet tenantAlbumSheet = new TenantAlbumWrapper.TenantAlbumSheet();
                tenantAlbumSheet.setLevel(m.getLevel());
                tenantAlbumSheet.setType(m.getType());
                tenantAlbumSheet.setId(m.getId().toString());
                return tenantAlbumSheet;
            }).collect(Collectors.toList()));
            sheetData.setSubjectType(next.getSubjectType());
            return sheetData;
        }).collect(Collectors.toList());
        tenantAlbumService.updateAlbum(album.getTenantId(), tenantAlbum, musicSheetDataList);
        return HttpResponseResult.succeed();
    }

    @PostMapping("/updateStatus")
    @ApiOperation(value = "启用/冻结", notes = "启用/冻结")
    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/updateStatus')")
    public HttpResponseResult<Boolean> updateStatus(@Validated @RequestBody TenantAlbumVo.UpdateStatus status) {
        tenantAlbumService.lambdaUpdate()
                .set(TenantAlbum::getStatus, status.getStatus())
                .eq(TenantAlbum::getId, status.getId())
                .update();
        return HttpResponseResult.succeed();
    }

}
