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

import com.pcloud.appcenter.assist.dto.AssistTempletDTO;
import com.pcloud.book.applet.biz.AppletBookClassifyBiz;
import com.pcloud.book.applet.biz.AppletBooklistBiz;
import com.pcloud.book.applet.biz.AppletNewsBiz;
import com.pcloud.book.applet.dao.AppletBookClassifyAgentDao;
import com.pcloud.book.applet.dao.AppletBookClassifyDao;
import com.pcloud.book.applet.dto.AppletBookClassifyDTO;
import com.pcloud.book.applet.dto.AppletBookClassifyRelationDTO;
import com.pcloud.book.applet.dto.AppletBooklistClassifyDTO;
import com.pcloud.book.applet.dto.AppletLabelDTO;
import com.pcloud.book.applet.dto.AppletNewsClassifyDTO;
import com.pcloud.book.applet.dto.AppletUserLabelDTO;
import com.pcloud.book.applet.entity.AppletBookClassify;
import com.pcloud.book.applet.entity.AppletBookClassifyAgent;
import com.pcloud.book.applet.entity.AppletNewsClassify;
import com.pcloud.book.applet.entity.AppletUserLabel;
import com.pcloud.book.applet.entity.AppletUserLabelRelation;
import com.pcloud.book.applet.enums.LabelTypeEnum;
import com.pcloud.book.applet.mapper.AppletUserLabelMapper;
import com.pcloud.book.applet.mapper.AppletUserLabelRelationMapper;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.dao.BookLabelDao;
import com.pcloud.book.book.entity.BookLabel;
import com.pcloud.book.consumer.app.AssistTempletConsr;
import com.pcloud.book.consumer.user.ChannelConsr;
import com.pcloud.book.util.common.YesOrNoEnums;
import com.pcloud.book.util.properties.BookProps;
import com.pcloud.channelcenter.wechat.entity.AccountSetting;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.utils.ListUtils;

import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName com.pcloud.book.applet.biz.impl.AppletBookClassifyBizImpl
 * @Author zhuyajie
 * @Description 小程序书刊分类
 * @Date 2020/5/15 16:29
 * @Version 1.0
 **/
@Slf4j
@Component
public class AppletBookClassifyBizImpl implements AppletBookClassifyBiz {

    @Autowired
    private AppletBookClassifyDao appletBookClassifyDao;
    @Autowired
    private AppletUserLabelMapper appletUserLabelMapper;
    @Autowired
    private AppletUserLabelRelationMapper relationMapper;
    @Autowired
    private AssistTempletConsr assistTempletConsr;
    @Autowired
    private BookLabelDao bookLabelDao;
    @Autowired
    private AppletBookClassifyAgentDao appletBookClassifyAgentDao;
    @Autowired
    private AppletNewsBiz appletNewsBiz;
    @Autowired
    private AppletBooklistBiz appletBooklistBiz;


    @Override
    public List<AppletBookClassifyDTO> getAppletBookClassifyList(Boolean showState) {
        return appletBookClassifyDao.queryAll(showState);
    }

    @Override
    public AppletBookClassifyDTO getById(Long id) {
        AppletBookClassifyDTO bookClassifyDTO = new AppletBookClassifyDTO();
        AppletBookClassify bookClassify = appletBookClassifyDao.queryById(id);
        if (null != bookClassify) {
            BeanUtils.copyProperties(bookClassify, bookClassifyDTO);
        }
        return bookClassifyDTO;
    }

    @Override
    public void update(AppletBookClassify appletBookClassify) {
        if (null == appletBookClassify || null == appletBookClassify.getId()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "缺少id");
        }
        appletBookClassifyDao.update(appletBookClassify);
    }

    @Override
    @ParamLog("平台端新增客户端标签")
    public void addUserLabel(AppletUserLabelDTO appletUserLabelDTO) {
        AppletUserLabel appletUserLabel = appletUserLabelDTO.DTOToEntity();
        if (null == appletUserLabel.getAgentId()){
            appletUserLabel.setAgentId(0L);
        }
        appletUserLabelMapper.insert(appletUserLabel);
        List<AppletUserLabelRelation> appletUserLabelRelations = appletUserLabelDTO.getAppletUserLabelRelations();
        if (ListUtils.isEmpty(appletUserLabelRelations)){
            return;
        }
        appletUserLabelRelations.forEach(e -> e.setAppletUserLabelId(appletUserLabel.getId()));
        relationMapper.batchInsert(appletUserLabelRelations);
    }

    @Override
    public void addBookTempletRelation(List<Long> templetIdList, Long bookClassifyId) {
        if (null == bookClassifyId || ListUtils.isEmpty(templetIdList)){
            return;
        }
        List<AppletBookClassifyRelationDTO> list = new ArrayList<>();
        for (Long templetId : templetIdList){
            AppletBookClassifyRelationDTO relation = new AppletBookClassifyRelationDTO();
            relation.setAppletBookClassifyId(bookClassifyId);
            relation.setBookTempletId(templetId);
            list.add(relation);
        }
        appletBookClassifyDao.addBookClassifyRelation(list);
    }

    @Override
    public List<AppletBookClassifyRelationDTO> getRelationBookTempletByBookClassifyId(Long bookClassifyId) {
        List<AppletBookClassifyRelationDTO> relationDTOS = new ArrayList<>();
        List<Long> templetIds = appletBookClassifyDao.getRelationBookTempletByBookClassify(bookClassifyId);
        if (ListUtils.isEmpty(templetIds)) {
            return new ArrayList<>();
        }
        Map<Long, AssistTempletDTO> classifyMap = assistTempletConsr.mapByIds4Classify(templetIds);
        for (Long templetId : templetIds) {
            AppletBookClassifyRelationDTO relationDTO = new AppletBookClassifyRelationDTO();
            relationDTO.setBookTempletId(templetId);
            relationDTO.setAppletBookClassifyId(bookClassifyId);
            if (!MapUtils.isEmpty(classifyMap) && classifyMap.containsKey(templetId)) {
                relationDTO.setBookTempletName(classifyMap.get(templetId).getTempletName());
            }
            relationDTOS.add(relationDTO);
        }
        return relationDTOS;
    }

    @Override
    @ParamLog("更新客户端标签")
    public void updateUserLabel(AppletUserLabelDTO appletUserLabelDTO) {
        if(null == appletUserLabelDTO || null == appletUserLabelDTO.getId()){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"appletUserLabelId为空更新失败");
        }
        AppletUserLabel appletUserLabel = appletUserLabelDTO.DTOToEntity();
        appletUserLabelMapper.updateByPrimaryKey(appletUserLabel);
        relationMapper.deleteByUserLabelId(appletUserLabelDTO.getId());
        List<AppletUserLabelRelation> appletUserLabelRelations = appletUserLabelDTO.getAppletUserLabelRelations();
        if (ListUtils.isEmpty(appletUserLabelRelations)){
            return;
        }
        appletUserLabelRelations.forEach(e -> e.setAppletUserLabelId(appletUserLabel.getId()));
        relationMapper.batchInsert(appletUserLabelRelations);
    }

    @Override
    @ParamLog("删除客户端标签")
    public void deleteUserLabel(Long id) {
        appletUserLabelMapper.deleteByPrimaryKey(id);
        relationMapper.deleteByUserLabelId(id);
    }

    @Override
    @ParamLog("平台端设置的客户端标签列表")
    public List<AppletUserLabelDTO> listUserLabel(Long appletBookClassifyId, Long agentId) {
        List<AppletUserLabelDTO> appletUserLabelDTOS = appletUserLabelMapper.listUserLabel(appletBookClassifyId, agentId);
        if (ListUtils.isEmpty(appletUserLabelDTOS)) {
            return new ArrayList<>();
        }
        List<AppletUserLabelRelation> appletUserLabelRelations = new ArrayList<>();
        Set<Long> labelIds = new HashSet<>();
        appletUserLabelDTOS.forEach(e -> {
            if (!ListUtils.isEmpty(e.getAppletUserLabelRelations())) {
                appletUserLabelRelations.addAll(e.getAppletUserLabelRelations());
            }
        });
        if (ListUtils.isEmpty(appletUserLabelRelations)) {
            return appletUserLabelDTOS;
        }
        List<Long> templetIds = new ArrayList<>();
        for (AppletUserLabelRelation labelRelation : appletUserLabelRelations) {
            Integer labelType = labelRelation.getLabelType();
            if (labelType.equals(LabelTypeEnum.grade_label.code) || labelType.equals(LabelTypeEnum.subject_label.code)) {
                labelIds.add(labelRelation.getBookLabelId());
            } else if (labelType.equals(LabelTypeEnum.sceond_templet.code) && !templetIds.contains(labelRelation.getBookLabelId())) {
                templetIds.add(labelRelation.getBookLabelId());
            }
        }
        //填充标签名称
        fillLabelName(appletUserLabelDTOS, labelIds);
        fillTempletName(appletUserLabelDTOS, templetIds);
        return appletUserLabelDTOS;
    }

    private void fillLabelName(List<AppletUserLabelDTO> appletUserLabelDTOS, Set<Long> labelIds) {
        log.info("填充标签名称");
        if (null==labelIds ||labelIds.size()<=0){
            return;
        }
        Map<Long, BookLabel> bookLabelMap = bookLabelDao.getMapByIds(new ArrayList<>(labelIds));
        appletUserLabelDTOS.forEach(e -> {
            if (ListUtils.isEmpty(e.getAppletUserLabelRelations())) {
                return;
            }
            e.getAppletUserLabelRelations().forEach(m -> {
                if (!bookLabelMap.containsKey(m.getBookLabelId())) {
                    return;
                }
                if (m.getLabelType().equals(LabelTypeEnum.grade_label.code) || m.getLabelType().equals(LabelTypeEnum.subject_label.code)) {
                    m.setBookLabelName(bookLabelMap.get(m.getBookLabelId()).getName());
                }
            });
        });
    }

    private void fillTempletName(List<AppletUserLabelDTO> appletUserLabelDTOS, List<Long> templetIds){
        if (ListUtils.isEmpty(templetIds)){
            return;
        }
        Map<Long, AssistTempletDTO> classifyMap = assistTempletConsr.mapByIds4Classify(templetIds);
        appletUserLabelDTOS.forEach(e -> {
            if (ListUtils.isEmpty(e.getAppletUserLabelRelations())) {
                return;
            }
            e.getAppletUserLabelRelations().forEach(m -> {
                if (classifyMap.containsKey(m.getBookLabelId()) && m.getLabelType().equals(LabelTypeEnum.sceond_templet.code)) {
                    m.setBookLabelName(classifyMap.get(m.getBookLabelId()).getTempletName());
                }
            });
        });
    }



    @Override
    public List<AppletBookClassifyDTO> getAllBookClassifyAndLabel4Wechat(String grayStatus, Long officialAccountsId) {
        List<AppletBookClassifyDTO> classifyAndLabelDTOS = getAppletBookClassifyList4Wechat(officialAccountsId, true);
        if (ListUtils.isEmpty(classifyAndLabelDTOS)) {
            return new ArrayList<>();
        }
        //过滤测试分类
        if (YesOrNoEnums.YES.getCode().equals(grayStatus)) {
            for (int i = 0; i < classifyAndLabelDTOS.size(); i++) {
                if ("质检测试".equals(classifyAndLabelDTOS.get(i).getClassify())){
                    classifyAndLabelDTOS.remove(i);
                }
            }
        }
        Long agentId = appletNewsBiz.getAgentIdByAccountId(officialAccountsId);
        List<AppletLabelDTO> userLabelDTOS = appletUserLabelMapper.getBookClassifyAndLabel(agentId);
        if (ListUtils.isEmpty(userLabelDTOS)) {
            return classifyAndLabelDTOS;
        }
        Map<Long, List<AppletLabelDTO>> map = userLabelDTOS.stream().collect(Collectors.groupingBy(AppletLabelDTO::getAppletBookClassifyId));
        for (AppletBookClassifyDTO classifyDTO : classifyAndLabelDTOS) {
            if (!MapUtils.isEmpty(map) && map.containsKey(classifyDTO.getId())) {
                List<AppletLabelDTO> list = map.get(classifyDTO.getId());
                classifyDTO.setUserLabelDTOS(list);
            }
        }
        return classifyAndLabelDTOS;
    }

    @Override
    public List<Long> getRelationBookTempletByBookClassify(Long bookClassifyId) {
        return appletBookClassifyDao.getRelationBookTempletByBookClassify(bookClassifyId);
    }

    @Override
    public List<AppletUserLabelRelation> getByAppletUserLabelId(Long appletUserLabelId) {
        return relationMapper.getByAppletUserLabelId(appletUserLabelId);
    }

    @Override
    public List<AssistTempletDTO> getChildTempletList(Long appletBookClassifyId) {
        List<Long> templetIds = getRelationBookTempletByBookClassify(appletBookClassifyId);
        if (ListUtils.isEmpty(templetIds)){
            return new ArrayList<>();
        }
        return assistTempletConsr.getChildTempletList(templetIds);
    }

    @Override
    public Long getAppletBookClassifyId(Long firstClassifyId) {
        return appletBookClassifyDao.getAppletBookClassifyId(firstClassifyId);
    }

    @Override
    public Map<Long, AppletBookClassifyDTO> getBookClassifyByIds(List<Long> bookAdviserIds) {
        return appletBookClassifyDao.getBookClassifyByIds(bookAdviserIds);
    }

    @Override
    public void createBaseClassifysToAgent(Long agentId) {
        //书刊分类
        List<AppletBookClassifyDTO> list = appletBookClassifyDao.queryAll(null);
        if (!ListUtils.isEmpty(list)) {
            List<AppletBookClassifyAgent> agents = appletBookClassifyAgentDao.getByAgent(agentId);
            if (ListUtils.isEmpty(agents)){
                List<AppletBookClassifyAgent> bookClassifyAgents = new ArrayList<>();
                for (AppletBookClassifyDTO classifyDTO : list) {
                    AppletBookClassifyAgent classifyAgent = new AppletBookClassifyAgent();
                    classifyAgent.setAppletBookClassifyId(classifyDTO.getId());
                    classifyAgent.setAgentId(agentId);
                    classifyAgent.setShowState(true);
                    classifyAgent.setClassifyName(classifyDTO.getClassify());
                    classifyAgent.setSeq(classifyDTO.getSeq());
                    classifyAgent.setPic(classifyDTO.getPic());
                    bookClassifyAgents.add(classifyAgent);
                }
                appletBookClassifyAgentDao.insert(bookClassifyAgents);
            }
        }
        //资讯推荐栏目
        List<AppletNewsClassifyDTO> newsClassify = appletNewsBiz.getAllNewsClassify(null, agentId);
        if (ListUtils.isEmpty(newsClassify)){
            appletNewsBiz.addDefaultAppletNewsClassify(agentId);
        }
        //书单推荐栏目
        List<AppletBooklistClassifyDTO> booklistClassify = appletBooklistBiz.getAllBooklistClassify(null, agentId);
        if (ListUtils.isEmpty(booklistClassify)){
            appletBooklistBiz.addDefaultBooklistClassify(agentId);
        }
    }

    @Override
    public void updateBaseInfoByAgent(AppletBookClassifyAgent appletBookClassifyAgent) {
        if (null == appletBookClassifyAgent || null == appletBookClassifyAgent.getAgentId()
                || null == appletBookClassifyAgent.getAppletBookClassifyId()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "参数缺失");
        }
        appletBookClassifyAgentDao.updateBaseInfoByAgent(appletBookClassifyAgent);
    }

    @Override
    public List<AppletBookClassifyDTO> getAppletBookClassifyListByAgent(Long agentId, Boolean showState) {
        return appletBookClassifyAgentDao.listClassifyByAgent(agentId, showState);
    }

    @Override
    public List<AppletBookClassifyDTO> getAppletBookClassifyList4Wechat(Long officialAccountsId, Boolean showState) {
        Long agentId = appletNewsBiz.getAgentIdByAccountId(officialAccountsId);
        if (null == agentId){
            return getAppletBookClassifyList(showState);
        }else {
            return getAppletBookClassifyListByAgent(agentId, showState);
        }
    }

    @Override
    public List<AppletUserLabelDTO> listUserLabel4Wechat(Long appletBookClassifyId, Long officialAccountsId) {
        Long agentId = appletNewsBiz.getAgentIdByAccountId(officialAccountsId);
        return listUserLabel(appletBookClassifyId, agentId);
    }

}
