package com.ym.mec.biz.service.impl;


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

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ym.mec.auth.api.dto.MusicScoreQueryInfo;
import com.ym.mec.biz.dal.dao.SysMusicScoreCategoriesDao;
import com.ym.mec.biz.dal.dao.SysMusicScoreDao;
import com.ym.mec.biz.dal.entity.SysMusicScoreCategories;
import com.ym.mec.biz.service.SysMusicScoreCategoriesService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.service.impl.BaseServiceImpl;

@Service
public class SysMusicScoreCategoriesServiceImpl extends BaseServiceImpl<Integer, SysMusicScoreCategories> implements SysMusicScoreCategoriesService {

	@Autowired
	private SysMusicScoreCategoriesDao sysMusicScoreCategoriesDao;
	@Autowired
	private SysMusicScoreDao sysMusicScoreDao;

	@Override
	public BaseDAO<Integer, SysMusicScoreCategories> getDAO() {
		return sysMusicScoreCategoriesDao;
	}


	@Override
	public List<SysMusicScoreCategories> queryTree(MusicScoreQueryInfo menuQueryInfo) {
		List<SysMusicScoreCategories> scoreCategories = sysMusicScoreCategoriesDao.findByParentId(menuQueryInfo.getParentId(),menuQueryInfo.getSearch(),menuQueryInfo.getEnable());
		List<SysMusicScoreCategories> scoreCategoriesAllList = sysMusicScoreCategoriesDao.findByParentId(null,menuQueryInfo.getSearch(),menuQueryInfo.getEnable());
		for (SysMusicScoreCategories categories : scoreCategories) {
			int sum = getTree(categories, scoreCategoriesAllList);
			categories.setMusicScoreNum(sum + categories.getMusicScoreNumSum());
		}
		return scoreCategories;
	}

	@Override
	public List<SysMusicScoreCategories> queryCategoriesTreeList(String categoryIds, Boolean isQueryEnable) {
		
		categoryIds = categoryIds.endsWith(",") ? categoryIds.substring(0, categoryIds.length() - 1) : categoryIds;

		List<SysMusicScoreCategories> rows = new ArrayList<SysMusicScoreCategories>();
		
		List<SysMusicScoreCategories> categoryList = sysMusicScoreCategoriesDao.queryByIds(categoryIds);
		
		SysMusicScoreCategories parentCategory = null;
		SysMusicScoreCategories subCategory = null;
		for(SysMusicScoreCategories smsc : categoryList){
			
			if(smsc == null){
				continue;
			}
			if(isQueryEnable == null){
				isQueryEnable = true;
			}
			if(isQueryEnable == true && smsc.getEnable() != true){
				continue;
			}
			parentCategory = getParentTree(smsc);
			subCategory = getChildTree(smsc);
			
			if(parentCategory == null){
				insertSubToParent(rows, subCategory);
			}else{
				parentCategory.getSysMusicScoreCategoriesList().add(subCategory);
				insertSubToParent(rows, parentCategory);
			}
			
			
		}
		
		return rows;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void save(SysMusicScoreCategories musicScoreCategories) {
		String organId = musicScoreCategories.getOrganId();
		Boolean enable = musicScoreCategories.getEnable();
		if(musicScoreCategories.getParentId() == null){
			musicScoreCategories.setParentId(0);
		}
		if(musicScoreCategories.getOrder() == null){
			musicScoreCategories.setOrder(0);
		}
		sysMusicScoreCategoriesDao.insert(musicScoreCategories);
		List<SysMusicScoreCategories> sysMusicScoreCategoriesList = musicScoreCategories.getSysMusicScoreCategoriesList();
		if(sysMusicScoreCategoriesList != null && sysMusicScoreCategoriesList.size() > 0){
			int order = 0;
			for (SysMusicScoreCategories categories : sysMusicScoreCategoriesList) {
				categories.setOrder(order);
				categories.setOrganId(organId);
				categories.setEnable(enable);
				categories.setParentId(musicScoreCategories.getId());
				sysMusicScoreCategoriesDao.insert(categories);
				order++;
				List<SysMusicScoreCategories> categoriesList = categories.getSysMusicScoreCategoriesList();
				if(categoriesList != null && categoriesList.size() > 0){
					int order1 = 0;
					for (SysMusicScoreCategories e : categoriesList) {
						e.setOrder(order1);
						e.setOrganId(organId);
						e.setEnable(enable);
						e.setParentId(categories.getId());
						order1++;
					}
					sysMusicScoreCategoriesDao.batchInsert(categoriesList,organId,enable);
				}
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateCategories(SysMusicScoreCategories musicScoreCategories) {
		String organId = musicScoreCategories.getOrganId();
		Boolean enable = musicScoreCategories.getEnable();
		sysMusicScoreCategoriesDao.update(musicScoreCategories);
		String delCategoriesIds = musicScoreCategories.getDelCategoriesIds();
		if(StringUtils.isNotEmpty(delCategoriesIds)){
			//获取当前节点以及子节点
			delCategoriesIds = sysMusicScoreCategoriesDao.findByCategoriesIds(delCategoriesIds);
			//是否有在使用的分类
			int count = sysMusicScoreDao.countBuyCategoriesIds(delCategoriesIds);
			if(count > 0){
				throw new BizException("操作失败：当前分类已使用");
			}
			sysMusicScoreCategoriesDao.batchDel(delCategoriesIds);
		}
		List<SysMusicScoreCategories> sysMusicScoreCategoriesList = musicScoreCategories.getSysMusicScoreCategoriesList();
		if(sysMusicScoreCategoriesList != null && sysMusicScoreCategoriesList.size() > 0){
			int order = 0;
			for (SysMusicScoreCategories categories : sysMusicScoreCategoriesList) {
				categories.setOrder(order);
				order++;
				List<SysMusicScoreCategories> categoriesList = categories.getSysMusicScoreCategoriesList();
				if(categoriesList != null && categoriesList.size() > 0){
					int order1 = 0;
					for (SysMusicScoreCategories e : categoriesList) {
						e.setOrder(order1);
						order1++;
					}
				}
			}
			List<SysMusicScoreCategories> insertCategoriesList = sysMusicScoreCategoriesList.stream().filter(e -> e.getId() == null).collect(Collectors.toList());
			List<SysMusicScoreCategories> updateCategoriesList = sysMusicScoreCategoriesList.stream().filter(e -> e.getId() != null).collect(Collectors.toList());

			if(insertCategoriesList != null && insertCategoriesList.size() > 0){
				for (SysMusicScoreCategories categories : insertCategoriesList) {
					categories.setOrganId(organId);
					categories.setEnable(enable);
					categories.setParentId(musicScoreCategories.getId());
					sysMusicScoreCategoriesDao.insert(categories);
					List<SysMusicScoreCategories> categoriesList = categories.getSysMusicScoreCategoriesList();
					if(categoriesList != null && categoriesList.size() > 0){
						categoriesList.forEach(e->{
							e.setOrganId(organId);
							e.setEnable(enable);
							e.setParentId(categories.getId());
						});
						sysMusicScoreCategoriesDao.batchInsert(categoriesList,organId,enable);
					}
				}
			}
			if(updateCategoriesList != null && updateCategoriesList.size() > 0){
				for (SysMusicScoreCategories categories : updateCategoriesList) {
					List<SysMusicScoreCategories> categoriesList = categories.getSysMusicScoreCategoriesList();
					if(categoriesList != null && categoriesList.size() > 0){
						List<SysMusicScoreCategories> insertCategories = categoriesList.stream().filter(e -> e.getId() == null).collect(Collectors.toList());
						if(insertCategories != null && insertCategories.size() > 0){
							for (SysMusicScoreCategories insertCategory : insertCategories) {
								insertCategory.setOrganId(organId);
								insertCategory.setEnable(enable);
								insertCategory.setParentId(categories.getId());
							}
							sysMusicScoreCategoriesDao.batchInsert(insertCategories,organId,enable);
						}
						List<SysMusicScoreCategories> updateCategories = categoriesList.stream().filter(e -> e.getId() != null).collect(Collectors.toList());
						if(updateCategories != null && updateCategories.size() > 0){
							sysMusicScoreCategoriesDao.batchUpdate(updateCategories,organId,enable);
						}
					}
				}
				sysMusicScoreCategoriesDao.batchUpdate(updateCategoriesList,organId,enable);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void del(Integer id) {
		
		List<Integer> categoriesIdList = new ArrayList<>();
		Integer categoriesId = id;
		
		SysMusicScoreCategories sysMusicScoreCategories = get(categoriesId);
		
		if(sysMusicScoreCategories == null){
			throw new BizException("分类找不到");
		}
		categoriesIdList.add(categoriesId);
		sysMusicScoreCategories = getChildTree(sysMusicScoreCategories);
		getAllCategoryIdList(categoriesIdList, sysMusicScoreCategories.getSysMusicScoreCategoriesList());
		
		String byCategoriesIds = categoriesIdList.stream().map(Objects :: toString).collect(Collectors.joining(","));
		//是否有在使用的分类
		int count = sysMusicScoreDao.countBuyCategoriesIds(byCategoriesIds);
		if(count > 0){
			throw new BizException("操作失败：当前分类已使用");
		}
		sysMusicScoreCategoriesDao.batchDel(byCategoriesIds);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void enable(Integer categoriesId) {
		SysMusicScoreCategories categories = sysMusicScoreCategoriesDao.get(categoriesId);
		if(categories == null){
			throw new BizException("分类不存在");
		}
		String byCategoriesIds = sysMusicScoreCategoriesDao.findByCategoriesIds(categoriesId.toString());
		byCategoriesIds = sysMusicScoreCategoriesDao.findByCategoriesIds(byCategoriesIds);
		sysMusicScoreCategoriesDao.enable(byCategoriesIds,!categories.getEnable());
	}

    @Override
    public SysMusicScoreCategories getDetail(Integer categoriesId) {
		SysMusicScoreCategories categories = sysMusicScoreCategoriesDao.get(categoriesId);
		MusicScoreQueryInfo musicScoreQueryInfo = new MusicScoreQueryInfo();
		musicScoreQueryInfo.setParentId(categories.getId());
		categories.setSysMusicScoreCategoriesList(queryTree(musicScoreQueryInfo));
		return categories;
    }

    private int getTree(SysMusicScoreCategories categories,List<SysMusicScoreCategories> scoreCategoriesAllList){
		//得到根节点对象
		//获取子节点list
		List<SysMusicScoreCategories> scoreCategories = scoreCategoriesAllList.stream().filter(e->e.getParentId().equals(categories.getId())).collect(Collectors.toList());
		//如果存在子节点
		int item = 0;
		if(scoreCategories != null && scoreCategories.size() > 0) {
			//将子节点list放入父节点对象
			categories.setSysMusicScoreCategoriesList(scoreCategories);
			//遍历子节点....
			for (SysMusicScoreCategories score : scoreCategories) {
				int sum = getTree(score, scoreCategoriesAllList);
				score.setMusicScoreNum(sum + score.getMusicScoreNumSum());
				item += score.getMusicScoreNum();
			}
		}
		return item;
	}
    
    public SysMusicScoreCategories getChildTree(SysMusicScoreCategories sysMusicScoreCategories){
    	
    	List<SysMusicScoreCategories> subCategoryList = sysMusicScoreCategoriesDao.findByParentId(sysMusicScoreCategories.getId(), null, null);
    	
    	if(subCategoryList != null && subCategoryList.size() > 0){
    		sysMusicScoreCategories.setSysMusicScoreCategoriesList(subCategoryList);
    		for(SysMusicScoreCategories sc : subCategoryList){
    			getChildTree(sc);
    		}
    	}
    	
    	return sysMusicScoreCategories;
    }
    
    public SysMusicScoreCategories getParentTree(SysMusicScoreCategories sysMusicScoreCategories) {
		if (sysMusicScoreCategories != null && sysMusicScoreCategories.getParentId() > 0) {
			SysMusicScoreCategories parentCategories = sysMusicScoreCategoriesDao.queryByParentId(sysMusicScoreCategories.getParentId());
			if (parentCategories != null) {
				if(parentCategories.getParentId() > 0){
					return getParentTree(parentCategories);
				}
				return parentCategories;
			}
		}

		return null;
	}
	
	private void insertSubToParent(List<SysMusicScoreCategories> parentTree, SysMusicScoreCategories targetCategory) {
		for (SysMusicScoreCategories target : parentTree) {
			if (targetCategory.getId().intValue() == target.getId()) {
				insertSubToParent(target.getSysMusicScoreCategoriesList(),targetCategory.getSysMusicScoreCategoriesList().get(0));
				return;
			}
		}
		parentTree.add(targetCategory);
	}
    
    private void getAllCategoryIdList(List<Integer> categoryIdList, List<SysMusicScoreCategories> sysMusicScoreCategoriesList){
    	
    	if(sysMusicScoreCategoriesList != null && sysMusicScoreCategoriesList.size() > 0){
    		for(SysMusicScoreCategories sysMusicScoreCategories : sysMusicScoreCategoriesList){
    			categoryIdList.add(sysMusicScoreCategories.getId());
    			getAllCategoryIdList(categoryIdList, sysMusicScoreCategories.getSysMusicScoreCategoriesList());
    		}
    	}
    	
    }
}