package com.ozs.kpim.service.topic.impl;

import com.ozs.kpim.dto.topic.TopicDTO;
import com.ozs.kpim.dto.topic.TopicTreeDTO;
import com.ozs.kpim.dto.topic.TopicZtreeDTO;
import com.ozs.kpim.mapper.topic.TopicMapper;
import com.ozs.kpim.service.topic.TopicManagerService;
import com.ozs.kpim.util.CodeUtils;
import com.ozs.kpim.util.ParamUtil;
import com.ozs.kpim.util.R;
import com.ozs.kpim.util.S;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName TopicManagerServiceImpl
 * @Desc 主题管理Service实现类
 * @Author jade
 * @Date 2019/2/20
 * @Version 1.0
 */
@Service
public class TopicManagerServiceImpl implements TopicManagerService{

    public static final int CODE_MIN_SIZE = 3;

    @Resource
    private TopicMapper topicMapper;
    
    /* *
     * @Author jade
     * @Description 新建主题，判断topic_code不允许有重复
     * @Date 2019/2/20
     * @Param [topicDTO]
     * @return R<TopicDTO>
    **/
    @Override
    public R<TopicDTO> save(TopicDTO topicDTO) throws Exception{
        //1.生成主题编码
        String topicCode = generateTopicCode(topicDTO.getParentTopicCode());
        //2.计算级别
        Integer level = computeLevel(topicDTO.getParentTopicCode());
        //3.级别、主题编码赋值
        topicDTO.setLevel(level);
        topicDTO.setTopicCode(topicCode);
        //4.插入到数据库
        topicMapper.insert(topicDTO);
        return new R<>(S.OK,S.getMsg(S.OK));
    }

    /* *
     * @Author jade
     * @Description 生成主题编码
     * @Date 2019/2/20
     * @Param [parentCode]
     * @return java.lang.String
    **/
    private String generateTopicCode(String parentCode){
        String topicCode = (StringUtils.isEmpty(parentCode) || "0".equalsIgnoreCase(parentCode)) ? CodeUtils.getCode(CODE_MIN_SIZE) : (parentCode.trim() + CodeUtils.getCode(CODE_MIN_SIZE));
        int count = topicMapper.getCountByTopicCode(topicCode);
        if(count > 0){
            //递归调用，直到不重复为止
            return generateTopicCode(parentCode);
        }else{
            return topicCode;
        }
    }

    /* *
     * @Author jade
     * @Description 根据ParentCode计算级别
     * @Date 2019/2/20
     * @Param [parentCode]
     * @return java.lang.Integer
    **/
    private Integer computeLevel(String parentCode){
        return (StringUtils.isEmpty(parentCode) || "0".equalsIgnoreCase(parentCode)) ? 1 : (parentCode.trim().length()/CODE_MIN_SIZE + 1);
    }

    /* *ssss
     * @Author jade
     * @Description 修改主题，正在使用的主题不允许修改
     * @Date 2019/2/20
     * @Param [topicDTO]
     * @return R<TopicDTO>
    **/
    @Override
    public R<TopicDTO> update(TopicDTO topicDTO) throws Exception{
        int count = topicMapper.ifTopicInfoUse(topicDTO.getId());
        if(count > 0){
            return new R<>(S.UPDATE_IN_USE,S.getMsg(S.UPDATE_IN_USE));
        }

        topicMapper.update(topicDTO);
        return new R<>(S.OK,S.getMsg(S.OK));
    }

    /* *
     * @Author jade
     * @Description 删除没被使用的主题，使用中不允许删除
     * @Date 2019/2/20
     * @Param [id]
     * @return R<TopicDTO>
    **/
    @Override
    public R<TopicDTO> delete(String id) throws Exception{
        int count = topicMapper.ifTopicInfoUse(id);
        if(count > 0){
            return new R<>(S.DELETE_IN_USE,S.getMsg(S.DELETE_IN_USE));
        }

        topicMapper.delete(id);
        return new R<>(S.OK,S.getMsg(S.OK));
    }

    /* *
     * @Author jade
     * @Description 删除没被使用的主题，使用中不允许删除
     * @Date 2019/2/20
     * @Param [topicCode]
     * @return R<TopicDTO>
     **/
    @Override
    public R<TopicDTO> deleteByTopicCode(String topicCode) {
        TopicDTO record = topicMapper.getByTopicCode(topicCode);
        // 查询所有子主题
        List<TopicDTO> list = topicMapper.listAllSubTopics(topicCode);
        List<String> topicIds = new ArrayList<>();
        if(list != null && list.size() >0){
            topicIds = list.stream().map(e -> {return e.getId();}).collect(Collectors.toList());
        }
        // 当前主题也要添加到主题ID列表中
        topicIds.add(record.getId());
        // 根据主题以及主题查询是否被使用
        int count = topicMapper.ifTopicOrSubTopicsInUse(topicIds);
        if(count > 0){
            return new R<>(S.DELETE_IN_USE,S.getMsg(S.DELETE_IN_USE));
        }

        // 删除主题，有子主题子主题也会被删除
        topicMapper.deleteByTopicCode(topicCode);
        return new R<>(S.OK,S.getMsg(S.OK));
    }

    /* *
     * @Author jade
     * @Description 查询详情
     * @Date 2019/2/20
     * @Param [id]
     * @return R<TopicDTO>
    **/
    @Override
    public R<TopicDTO> getById(String id) throws Exception{
        return new R<>(S.OK,S.getMsg(S.OK),topicMapper.getById(id));
    }


    /* *
     * @Author jade
     * @Description 查询详情
     * @Date 2019/3/6
     * @Param [topicCode]
     * @return R<TopicDTO>
    **/
    @Override
    public R<TopicDTO> getByTopicCode(String topicCode) {
        return new R<>(S.OK,S.getMsg(S.OK),topicMapper.getByTopicCode(topicCode));
    }



    /* *
     * @Author jade
     * @Description 主题列表查询
     * @Date 2019/2/20
     * @Param [name, sort, order, page, pageSize]
     * @return R<java.util.List<TopicDTO>>
    **/
    @Override
    public R<List<TopicDTO>> listTopics(String name, String sort, String order, Integer page, Integer pageSize) {
        R<TopicDTO> r = new R<>();
        if (sort != null && order != null) {
            sort = ParamUtil.camelToUnderline(sort);
            order = ParamUtil.getDefaultOrder(order);
            PageHelper.startPage(page, pageSize, "A."+sort + " " + order);
        } else {
            PageHelper.startPage(page, pageSize);
        }
        List<TopicDTO> list = topicMapper.listTopics(name);
        return r.page(list);
    }

    /* *
     * @Author jade
     * @Description 查询主题的下级主题
     * @Date 2019/2/21
     * @Param [parentTopicCode]
     * @return R<java.util.List<TopicDTO>>
    **/
    @Override
    public R<List<TopicDTO>> listSubTopics(String parentTopicCode) {
        return new R(S.OK,S.getMsg(S.OK),topicMapper.listSubTopics(parentTopicCode));
    }

    /* *
     * @Author jade
     * @Description  主题树形展示
     * @Date 2019/2/21
     * @Param []
     * @return R<java.util.List<TopicTreeDTO>>
    **/
    @Override
    public R<List<TopicTreeDTO>> topicTree() throws Exception {
        PageHelper.orderBy("A.level ASC");
        List<TopicDTO> topicList = topicMapper.listTopics(null);
        List<TopicTreeDTO> list  = createTreeList(topicList);
        return new R(S.OK,S.getMsg(S.OK),list);
    }

    /* *
     * @Author jade
     * @Description 主题树 For Ztree
     * @Date 2019/3/6
     * @Param [name]
     * @return R<java.util.List<TopicTreeDTO>>
    **/
    @Override
    public R<List<TopicZtreeDTO>> topicForZtree(String name) {
        List<TopicZtreeDTO> list = topicMapper.topicForZtree(name);
        return new R(S.OK,S.getMsg(S.OK),list);
    }

   
    /* *
     * @Author jade
     * @Description 转换成树形结构
     * @Date 2019/2/21
     * @Param [topicList]
     * @return java.util.List<TopicTreeDTO>
    **/
    private List<TopicTreeDTO> createTreeList(List<TopicDTO> topicList) {
        List<TopicTreeDTO> tree = new ArrayList<>();
        if(topicList == null || topicList.isEmpty()){
            return tree;
        }

        for (TopicDTO topicDTO : topicList) {
            if( 1==topicDTO.getLevel()){
                TopicTreeDTO record = copyNode(topicDTO);
                recursiveNode(topicList,record);
                tree.add(record);
            }
        }

        return tree;

    }
    
    /* *
     * @Author jade
     * @Description 递归执行
     * @Date 2019/2/21
     * @Param [topicCode, topicList, record]
     * @return void
    **/
    private void recursiveNode(List<TopicDTO> topicList, TopicTreeDTO record) {
        String parentTopicCode = record.getTopicCode();
        List<TopicTreeDTO> nodes = new ArrayList<>();
        for (TopicDTO po: topicList) {
            String topicCode = po.getTopicCode();
            if(StringUtils.isEmpty(topicCode) || topicCode.length()<=3){
                continue;
            }

            String pCode = topicCode.substring(0,topicCode.length()-3);
            if(parentTopicCode.equalsIgnoreCase(pCode)){
                TopicTreeDTO copy = copyNode(po);
                recursiveNode(topicList, copy);
                nodes.add(copy);
            }
        }
        record.setChildren(nodes);
    }

    /* *
     * @Author jade
     * @Description 内容拷贝
     * @Date 2019/2/21
     * @Param [topicDTO]
     * @return TopicTreeDTO
    **/
    private TopicTreeDTO copyNode(TopicDTO topicDTO) {
        TopicTreeDTO node = new TopicTreeDTO();
        BeanUtils.copyProperties(topicDTO,node);
        return node;
    }



}
