package com.pcloud.book.custom.biz.impl;

import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.custom.biz.CustomReadPlanBiz;
import com.pcloud.book.custom.dao.CustomReadPlanDao;
import com.pcloud.book.custom.dao.CustomReadPlanPeriodDao;
import com.pcloud.book.custom.dto.PeriodCountAndReadPlanDTO;
import com.pcloud.book.custom.entity.CustomReadPlan;
import com.pcloud.book.custom.entity.CustomReadPlanPeriod;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.string.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class CustomReadPlanBizImpl implements CustomReadPlanBiz {

    @Autowired
    private CustomReadPlanDao customReadPlanDao;
    @Autowired
    private CustomReadPlanPeriodDao customReadPlanPeriodDao;


    @Transactional(rollbackFor = Exception.class)
    @ParamLog("新增阅读计划")
    @Override
    public Long addCustomReadPlan(CustomReadPlan customReadPlan) {
        checkAddCustomReadPlan(customReadPlan);
        customReadPlanDao.insert(customReadPlan);
        buildAndAddPeriods(customReadPlan);
        return customReadPlan.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("修改阅读计划")
    @Override
    public void updateCustomReadPlan(CustomReadPlan customReadPlan) {
        checkUpdateCustomReadPlan(customReadPlan);
        customReadPlanDao.update(customReadPlan);
        customReadPlanPeriodDao.deleteByCustomReadPlanId(customReadPlan.getId());
        buildAndAddPeriods(customReadPlan);
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("删除阅读计划")
    @Override
    public void deleteCustomReadPlan(Long customReadPlanId) {
        if (customReadPlanId==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"id为空");
        }
        customReadPlanDao.deleteById(customReadPlanId);
        customReadPlanPeriodDao.deleteByCustomReadPlanId(customReadPlanId);
    }

    @ParamLog("获取阅读计划列表")
    @Override
    public PageBeanNew<CustomReadPlan> getCustomReadPlanList(Integer currentPage, Integer numPerPage, Integer robotType) {
        if (currentPage==null||currentPage<0||numPerPage==null||numPerPage<=0){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"分页参数有误！");
        }
        Map<String,Object> map=new HashMap<>();
        map.put("robotType",robotType);
        PageBeanNew<CustomReadPlan> pageNew = customReadPlanDao.listPageNew(new PageParam(currentPage, numPerPage), map , "getCustomReadPlanList");
        if (ListUtils.isEmpty(pageNew.getRecordList())){
            return pageNew;
        }
        fillPeriodCount(pageNew.getRecordList());
        return pageNew;
    }

    @ParamLog("填充周期数")
    private void fillPeriodCount(List<CustomReadPlan> list) {
        if (ListUtils.isEmpty(list)){
            return;
        }
        List<Long> readPlanIds=list.stream().map(CustomReadPlan::getId).collect(Collectors.toList());
        List<PeriodCountAndReadPlanDTO> group = customReadPlanPeriodDao.getPeriodCountGroupByReadPlanId(readPlanIds);
        Map<Long,Integer> map=new HashMap<>();
        if (!ListUtils.isEmpty(group)){
            for (PeriodCountAndReadPlanDTO dto:group){
                map.put(dto.getCustomReadPlanId(),dto.getPeriodCount());
            }
        }
        for (CustomReadPlan customReadPlan:list){
            if (map.get(customReadPlan.getId())!=null){
                customReadPlan.setPeriodCount(map.get(customReadPlan.getId()));
            }else {
                customReadPlan.setPeriodCount(0);
            }
        }
    }

    @ParamLog("根据id获取阅读计划")
    @Override
    public CustomReadPlan getCustomReadPlanById(Long customReadPlanId) {
        if (customReadPlanId==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"id为空");
        }
        CustomReadPlan customReadPlan = customReadPlanDao.getById(customReadPlanId);
        List<CustomReadPlanPeriod> customReadPlanPeriods=customReadPlanPeriodDao.getListByCustomReadPlanId(customReadPlanId);
        customReadPlan.setCustomReadPlanPeriods(customReadPlanPeriods);
        return customReadPlan;
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog("复制阅读计划")
    @Override
    public Long copyCustomReadPlanById(Long customReadPlanId) {
        if (customReadPlanId==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"id为空");
        }
        CustomReadPlan customReadPlan = getCustomReadPlanById(customReadPlanId);
        if (customReadPlan==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"没有该计划");
        }
        CustomReadPlan newCus=new CustomReadPlan();
        newCus.setRobotType(customReadPlan.getRobotType());
        newCus.setDetail(customReadPlan.getDetail());
        newCus.setName(customReadPlan.getName());
        newCus.setCustomReadPlanPeriods(customReadPlan.getCustomReadPlanPeriods());
        addCustomReadPlan(newCus);
        return customReadPlan.getId();
    }

    @ParamLog("修改阅读计划参数校验")
    private void checkUpdateCustomReadPlan(CustomReadPlan customReadPlan) {
        if (customReadPlan==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"参数为空");
        }
        if (customReadPlan.getId()==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"id参数为空");
        }
        checkAddCustomReadPlan(customReadPlan);
    }

    @ParamLog("构建周期列表")
    private void buildAndAddPeriods(CustomReadPlan customReadPlan) {
        if (ListUtils.isEmpty(customReadPlan.getCustomReadPlanPeriods())){
            return;
        }
        Long customReadPlanId=customReadPlan.getId();
        int i=1;
        for (CustomReadPlanPeriod period:customReadPlan.getCustomReadPlanPeriods()){
            period.setCustomReadPlanId(customReadPlanId);
            period.setSeqNum(i++);
        }
        customReadPlanPeriodDao.batchInsert(customReadPlan.getCustomReadPlanPeriods());
    }

    @ParamLog("新增阅读计划参数校验")
    private void checkAddCustomReadPlan(CustomReadPlan customReadPlan) {
        if (customReadPlan==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"参数为空");
        }
        if (customReadPlan.getRobotType()==null){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"机器人类型参数为空");
        }
        if (StringUtil.isEmpty(customReadPlan.getName())){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"名称参数为空");
        }
        if (StringUtil.isEmpty(customReadPlan.getDetail())){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"阅读计划介绍参数为空");
        }
        if (ListUtils.isEmpty(customReadPlan.getCustomReadPlanPeriods())){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"周期集合为空");
        }
        if (customReadPlan.getCustomReadPlanPeriods().size()>52){
            throw new BookBizException(BookBizException.PARAM_IS_ERROR,"周期不能超过52");
        }
        for (CustomReadPlanPeriod period:customReadPlan.getCustomReadPlanPeriods()){
            if (StringUtil.isEmpty(period.getName())){
                throw new BookBizException(BookBizException.PARAM_IS_ERROR,"周期名称参数为空");
            }
        }
    }
}
