package com.yonge.cooleshow.biz.dal.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yonge.cooleshow.biz.dal.entity.TenantAlbum;
import com.yonge.cooleshow.biz.dal.entity.TenantAlbumCategory;
import com.yonge.cooleshow.biz.dal.entity.TenantAlbumCategoryDetail;
import com.yonge.cooleshow.biz.dal.entity.TenantAlbumMusic;
import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumCategoryMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMusicMapper;
import com.yonge.cooleshow.biz.dal.service.TenantAlbumCategoryDetailService;
import com.yonge.cooleshow.biz.dal.service.TenantAlbumCategoryService;
import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumCategoryWrapper;
import com.yonge.cooleshow.common.enums.ETenantAlbumCategoryType;
import com.yonge.toolset.base.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 机构专辑分类
 * 2023-10-10 09:48:46
 */
@Slf4j
@Service
public class TenantAlbumCategoryServiceImpl extends ServiceImpl<TenantAlbumCategoryMapper, TenantAlbumCategory> implements TenantAlbumCategoryService {

    @Autowired
    private TenantAlbumCategoryDetailService tenantAlbumCategoryDetailService;
    @Autowired
    private TenantAlbumMusicMapper tenantAlbumMusicMapper;
    @Autowired
    private TenantAlbumMapper tenantAlbumMapper;

    /**
     * 查询详情
     *
     * @param id 详情ID
     * @return TenantAlbumCategory
     */
    @Override
    public TenantAlbumCategoryWrapper.TenantAlbumCategory detail(Long id) {
        TenantAlbumCategory albumCategory = baseMapper.selectById(id);
        if (albumCategory == null) {
            throw new BizException("专辑分类不存在");
        }
        TenantAlbumCategoryWrapper.TenantAlbumCategory tenantAlbumCategory =
                TenantAlbumCategoryWrapper.TenantAlbumCategory.from(JSON.toJSONString(albumCategory));

        List<TenantAlbumCategoryDetail> list = tenantAlbumCategoryDetailService.lambdaQuery()
                .eq(TenantAlbumCategoryDetail::getTenantAlbumCategoryId, id)
                .list();
        tenantAlbumCategory.setValues(list);
        return tenantAlbumCategory;
    }

    /**
     * 分页查询
     *
     * @param page  IPage<TenantAlbumCategory>
     * @param query TenantAlbumCategoryWrapper.TenantAlbumCategoryQuery
     * @return IPage<TenantAlbumCategory>
     */
    @Override
    public IPage<TenantAlbumCategoryWrapper.TenantAlbumCategory> selectPage(
            IPage<TenantAlbumCategoryWrapper.TenantAlbumCategory> page,
            TenantAlbumCategoryWrapper.TenantAlbumCategoryQuery query) {

        List<TenantAlbumCategory> tenantAlbumCategories = baseMapper.selectPage(page, query);

        List<TenantAlbumCategoryWrapper.TenantAlbumCategory> result = tenantAlbumCategories.stream().map(next -> {
            TenantAlbumCategoryWrapper.TenantAlbumCategory tenantAlbumCategory =
                    new TenantAlbumCategoryWrapper.TenantAlbumCategory();
            BeanUtils.copyProperties(next, tenantAlbumCategory);
            return tenantAlbumCategory;
        }).collect(Collectors.toList());

        List<Long> idList = tenantAlbumCategories.stream().map(TenantAlbumCategory::getId).collect(Collectors.toList());
        if (!idList.isEmpty()) {
            List<TenantAlbumCategoryDetail> detailList = tenantAlbumCategoryDetailService.lambdaQuery()
                    .in(TenantAlbumCategoryDetail::getTenantAlbumCategoryId, idList)
                    .list();
            Map<Long, List<TenantAlbumCategoryDetail>> groupById = detailList.stream()
                    .collect(Collectors.groupingBy(TenantAlbumCategoryDetail::getTenantAlbumCategoryId));
            result.forEach(next -> next.setValues(groupById.getOrDefault(next.getId(), new ArrayList<>())));
        }
        return page.setRecords(result);
    }

    /**
     * 添加
     *
     * @param tenantAlbumCategory TenantAlbumCategoryWrapper.TenantAlbumCategory
     * @return Boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(TenantAlbumCategoryWrapper.TenantAlbumCategory tenantAlbumCategory) {
        Integer count = this.lambdaQuery()
                .eq(TenantAlbumCategory::getName, tenantAlbumCategory.getName())
                .eq(TenantAlbumCategory::getCategoryType, tenantAlbumCategory.getCategoryType())
                .eq(TenantAlbumCategory::getDelFlag, false)
                .count();
        if (count > 0) {
            throw new BizException("专辑分类名称已存在");
        }

        // 校验子分类值是否存在重复
        List<TenantAlbumCategoryDetail> values = tenantAlbumCategory.getValues();
        Set<String> names = values.stream().map(TenantAlbumCategoryDetail::getValue).collect(Collectors.toSet());
        if (names.size() != values.size()) {
            ETenantAlbumCategoryType categoryType = tenantAlbumCategory.getCategoryType();
            throw new BizException(ETenantAlbumCategoryType.CATEGORY_TYPE.equals(categoryType) ? "类型不能有重复" : "级别不能有重复");
        }

        TenantAlbumCategory albumCategory = JSON.parseObject(tenantAlbumCategory.jsonString(),
                TenantAlbumCategory.class);
        this.save(albumCategory);
        if (!values.isEmpty()) {
            values.forEach(next -> next.setTenantAlbumCategoryId(albumCategory.getId()));
            tenantAlbumCategoryDetailService.saveBatch(values);
        }
        return true;
    }

    /**
     * 更新
     *
     * @param tenantAlbumCategory TenantAlbumCategoryWrapper.TenantAlbumCategory
     * @return Boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean update(TenantAlbumCategoryWrapper.TenantAlbumCategory tenantAlbumCategory) {

        Integer count = this.lambdaQuery()
                .eq(TenantAlbumCategory::getName, tenantAlbumCategory.getName())
                .eq(TenantAlbumCategory::getCategoryType, tenantAlbumCategory.getCategoryType())
                .eq(TenantAlbumCategory::getDelFlag, false)
                .ne(TenantAlbumCategory::getId, tenantAlbumCategory.getId())
                .count();
        if (count > 0) {
            throw new BizException("专辑分类名称已存在");
        }

        // 校验子分类值是否存在重复
        List<TenantAlbumCategoryDetail> values = tenantAlbumCategory.getValues();
        Set<String> names = values.stream().map(TenantAlbumCategoryDetail::getValue).collect(Collectors.toSet());
        if (names.size() != values.size()) {
            TenantAlbumCategory albumCategory = this.getById(tenantAlbumCategory.getId());
            ETenantAlbumCategoryType categoryType = albumCategory.getCategoryType();
            throw new BizException(ETenantAlbumCategoryType.CATEGORY_TYPE.equals(categoryType) ? "类型不允许有重复" :
                    "级别不允许有重复");
        }

        // 校验是否存在引用删除
        List<TenantAlbumCategoryDetail> detailList = tenantAlbumCategoryDetailService.lambdaQuery()
                .eq(TenantAlbumCategoryDetail::getTenantAlbumCategoryId, tenantAlbumCategory.getId())
                .list();

        List<Long> newUpdateIds = values.stream().map(TenantAlbumCategoryDetail::getId).filter(Objects::nonNull)
                .collect(Collectors.toList());

        List<Long> removeDetailIdList = detailList.stream().map(TenantAlbumCategoryDetail::getId)
                .filter(next -> !newUpdateIds.contains(next)).collect(Collectors.toList());
        if (!removeDetailIdList.isEmpty()) {
            // 校验删除的分类值是否被使用，如果有使用，则提示
            TenantAlbumCategory albumCategory = this.getById(tenantAlbumCategory.getId());
            QueryWrapper<TenantAlbum> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(ETenantAlbumCategoryType.CATEGORY_TYPE.equals(albumCategory.getCategoryType()),
                            TenantAlbum::getCategoryTypeId, tenantAlbumCategory.getId())
                    .eq(ETenantAlbumCategoryType.CATEGORY_LEVEL.equals(albumCategory.getCategoryType()),
                            TenantAlbum::getCategoryLevelId, tenantAlbumCategory.getId());
            Integer useCount = tenantAlbumMapper.selectCount(queryWrapper);
            if (useCount > 0) {
                checkTenantAlbumCategoryDetailUsed(albumCategory.getCategoryType(), removeDetailIdList);
            }
            tenantAlbumCategoryDetailService.removeByIds(removeDetailIdList);
        }
        if (!values.isEmpty()) {
            values.forEach(next -> next.setTenantAlbumCategoryId(tenantAlbumCategory.getId()));
            tenantAlbumCategoryDetailService.saveOrUpdateBatch(values);
        }

        this.updateById(JSON.parseObject(tenantAlbumCategory.jsonString(), TenantAlbumCategory.class));
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean delete(Long id) {
        TenantAlbumCategory albumCategory = this.getById(id);
        if (albumCategory == null) {
            throw new BizException("删除的数据不存在");
        }
        QueryWrapper<TenantAlbum> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(TenantAlbum::getCategoryLevelId, id)
                .or()
                .eq(TenantAlbum::getCategoryTypeId, id);
        Integer count = tenantAlbumMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new BizException("专辑分类被使用");
        }

//        List<TenantAlbumCategoryDetail> list = tenantAlbumCategoryDetailService.lambdaQuery()
//                .eq(TenantAlbumCategoryDetail::getTenantAlbumCategoryId, albumCategory.getId())
//                .list();
//        checkTenantAlbumCategoryDetailUsed(albumCategory.getCategoryType(), list);
        albumCategory.setDelFlag(true);
        this.updateById(albumCategory);
        return true;
    }

    /**
     * 校验专辑分类中的值是否有被应用
     */
    private void checkTenantAlbumCategoryDetailUsed(ETenantAlbumCategoryType categoryType,
                                                    List<Long> list) {
        if (list.isEmpty()) {
            return;
        }
        List<String> idStrList = list.stream().map(Object::toString).collect(Collectors.toList());
        QueryWrapper<TenantAlbumMusic> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .in(ETenantAlbumCategoryType.CATEGORY_TYPE.equals(categoryType),
                        TenantAlbumMusic::getType, idStrList)
                .in(ETenantAlbumCategoryType.CATEGORY_LEVEL.equals(categoryType),
                        TenantAlbumMusic::getType, idStrList);
        Integer useCount = tenantAlbumMusicMapper.selectCount(queryWrapper);
        // 删除的ID被应用的数量大于0
        if (useCount > 0) {
            throw new BizException("专辑分类存在" + (ETenantAlbumCategoryType.CATEGORY_TYPE.equals(categoryType) ? "类型" :
                    "级别") + "引用");
        }
    }
}