package com.diagbot.facade;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.diagbot.client.UserServiceClient;
import com.diagbot.dto.IntroducePageDTO;
import com.diagbot.dto.QuestionShortDTO;
import com.diagbot.dto.RespDTO;
import com.diagbot.entity.IntroduceDetail;
import com.diagbot.entity.IntroduceInfo;
import com.diagbot.entity.IntroduceMap;
import com.diagbot.entity.QuestionInfo;
import com.diagbot.enums.IsDeleteEnum;
import com.diagbot.exception.CommonErrorCode;
import com.diagbot.exception.CommonException;
import com.diagbot.service.IntroduceDetailService;
import com.diagbot.service.IntroduceMapService;
import com.diagbot.service.impl.IntroduceInfoServiceImpl;
import com.diagbot.util.BeanUtil;
import com.diagbot.util.DateUtil;
import com.diagbot.util.ListUtil;
import com.diagbot.util.UserUtils;
import com.diagbot.vo.IdVO;
import com.diagbot.vo.IntroduceDetailVO;
import com.diagbot.vo.IntroduceMapVO;
import com.diagbot.vo.IntroducePageVO;
import com.diagbot.vo.IntroduceVO;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

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

/**
 * @Description:
 * @Author:zhaops
 * @time: 2018/11/16 14:30
 */
@Component
public class IntroduceInfoFacade extends IntroduceInfoServiceImpl {
    @Autowired
    IntroduceMapFacade introduceMapFacade;
    @Autowired
    IntroduceDetailFacade introduceDetailFacade;
    @Autowired
    @Qualifier("introduceDetailServiceImpl")
    IntroduceDetailService introduceDetailService;
    @Autowired
    @Qualifier("introduceMapServiceImpl")
    IntroduceMapService introduceMapService;
    @Autowired
    UserServiceClient userServiceClient;
    @Autowired
    QuestionFacade questionFacade;

    /**
     * 保存提示信息（新增or修改）
     *
     * @param introduceVO
     * @return
     */
    public Boolean saveIntroduce(IntroduceVO introduceVO) {
        IntroduceInfo introduceInfo = new IntroduceInfo();
        Date now = DateUtil.now();
        String userId = UserUtils.getCurrentPrincipleID();
        if (!(introduceVO.getId() == null || introduceVO.getId().equals(0L))) {
            introduceInfo = this.getById(introduceVO.getId());
            if (introduceInfo == null) {
                throw new CommonException(CommonErrorCode.NOT_EXISTS, "提示信息不存在");
            } else if (introduceInfo.getIsDeleted().equals(IsDeleteEnum.Y.getKey())) {
                throw new CommonException(CommonErrorCode.NOT_EXISTS, "提示信息已删除");
            }
        } else {
            introduceInfo.setCreator(userId);
            introduceInfo.setGmtCreate(now);
        }

        introduceInfo.setModifier(userId);
        introduceInfo.setGmtModified(now);
        introduceInfo.setName(introduceVO.getName());
        introduceInfo.setRemark(introduceVO.getRemark());

        //更新提示信息
        this.saveOrUpdate(introduceInfo);

        //明细信息不更新，每次都删除重新插入
        //删除已有明细，逻辑删除
        UpdateWrapper<IntroduceDetail> detailUpdateWrapper = new UpdateWrapper<>();
        detailUpdateWrapper.eq("introduce_id", introduceInfo.getId()).
                eq("is_deleted", IsDeleteEnum.N.getKey()).
                set("is_deleted", IsDeleteEnum.Y.getKey()).
                set("modifier", userId).
                set("gmt_modified", now);
        introduceDetailFacade.update(new IntroduceDetail(), detailUpdateWrapper);

        List<IntroduceDetail> introduceDetailList = Lists.newArrayList();
        for (IntroduceDetailVO detailVO : introduceVO.getDetailVOList()) {
            IntroduceDetail detail = new IntroduceDetail();
            detail.setIntroduceId(introduceInfo.getId());
            detail.setCreator(userId);
            detail.setGmtCreate(now);
            detail.setModifier(userId);
            detail.setGmtModified(now);
            detail.setContent(detailVO.getContent());
            detail.setText(detailVO.getText());
            detail.setTitle(detailVO.getTitle());
            detail.setOrderNo(detailVO.getOrderNo());
            detail.setPosition(detailVO.getPosition());
            detail.setIsReason(detailVO.getIsReason());
            introduceDetailList.add(detail);
        }
        //插入新的明细记录
        introduceDetailService.saveBatch(introduceDetailList);

        //更新映射关系
        //删除已有映射关系
        List<Long> questionIds = introduceVO.getMapVOList().stream().map(introduceMapVO -> introduceMapVO.getQuestionId()).collect(Collectors.toList());
        Long introudceId = introduceInfo.getId();
        UpdateWrapper<IntroduceMap> introduceMapUpdateWrapper = new UpdateWrapper<>();
        introduceMapUpdateWrapper.and(i -> i.eq("introduce_id", introudceId).or().in("question_id", questionIds)).
                eq("is_deleted", IsDeleteEnum.N.getKey()).
                set("is_deleted", IsDeleteEnum.Y.getKey()).
                set("modifier", UserUtils.getCurrentPrincipleID()).
                set("gmt_modified", DateUtil.now());
        introduceMapFacade.update(new IntroduceMap(), introduceMapUpdateWrapper);
        //插入新的映射关系
        List<IntroduceMap> introduceMapList = Lists.newLinkedList();
        for (IntroduceMapVO introduceMapVO : introduceVO.getMapVOList()) {
            IntroduceMap introduceMap = new IntroduceMap();
            BeanUtil.copyProperties(introduceMapVO, introduceMap);
            introduceMap.setIntroduceId(introduceInfo.getId());
            introduceMap.setCreator(userId);
            introduceMap.setGmtCreate(now);
            introduceMap.setModifier(userId);
            introduceMap.setGmtModified(now);
            introduceMapList.add(introduceMap);
        }
        introduceMapService.saveBatch(introduceMapList);
        return true;
    }

    /**
     * 单条删除提示信息 逻辑删除
     *
     * @param id
     * @return
     */
    public Boolean deleteRecord(Long id) {
        IntroduceInfo introduceInfo = this.getById(id);
        if (introduceInfo == null) {
            throw new CommonException(CommonErrorCode.NOT_EXISTS, "提示信息不存在");
        } else if (introduceInfo.getIsDeleted().equals(IsDeleteEnum.Y.getKey())) {
            throw new CommonException(CommonErrorCode.NOT_EXISTS, "提示信息已删除");
        }
        //删除已有映射关系
        UpdateWrapper<IntroduceMap> introduceMapUpdateWrapper = new UpdateWrapper<>();
        introduceMapUpdateWrapper.eq("introduce_id", id).
                eq("is_deleted", IsDeleteEnum.N.getKey()).
                set("is_deleted", IsDeleteEnum.Y.getKey()).
                set("modifier", UserUtils.getCurrentPrincipleID()).
                set("gmt_modified", DateUtil.now());
        introduceMapFacade.update(new IntroduceMap(), introduceMapUpdateWrapper);
        //删除明细
        UpdateWrapper<IntroduceDetail> introduceDetailUpdateWrapper = new UpdateWrapper<>();
        introduceDetailUpdateWrapper.eq("introduce_id", id).
                eq("is_deleted", IsDeleteEnum.N.getKey()).
                set("is_deleted", IsDeleteEnum.Y.getKey()).
                set("modifier", UserUtils.getCurrentPrincipleID()).
                set("gmt_modified", DateUtil.now());
        introduceDetailFacade.update(new IntroduceDetail(), introduceDetailUpdateWrapper);
        //删除提示信息
        UpdateWrapper<IntroduceInfo> introduceInfoUpdateWrapper = new UpdateWrapper<>();
        introduceInfoUpdateWrapper.eq("id", id).
                eq("is_deleted", IsDeleteEnum.N.getKey()).
                set("is_deleted", IsDeleteEnum.Y.getKey()).
                set("modifier", UserUtils.getCurrentPrincipleID()).
                set("gmt_modified", DateUtil.now());
        this.update(new IntroduceInfo(), introduceInfoUpdateWrapper);
        return true;
    }

    /**
     * 批量删除提示信息 逻辑删除
     *
     * @param idVOList
     * @return
     */
    public Boolean deleteRecords(List<IdVO> idVOList) {
        List<Long> ids = idVOList.stream().map(idVO -> idVO.getId()).collect(Collectors.toList());
        //删除已有映射关系
        UpdateWrapper<IntroduceMap> introduceMapUpdateWrapper = new UpdateWrapper<>();
        introduceMapUpdateWrapper.in("introduce_id", ids).
                eq("is_deleted", IsDeleteEnum.N.getKey()).
                set("is_deleted", IsDeleteEnum.Y.getKey()).
                set("modifier", UserUtils.getCurrentPrincipleID()).
                set("gmt_modified", DateUtil.now());
        introduceMapFacade.update(new IntroduceMap(), introduceMapUpdateWrapper);
        //删除明细
        UpdateWrapper<IntroduceDetail> introduceDetailUpdateWrapper = new UpdateWrapper<>();
        introduceDetailUpdateWrapper.in("introduce_id", ids).
                eq("is_deleted", IsDeleteEnum.N.getKey()).
                set("is_deleted", IsDeleteEnum.Y.getKey()).
                set("modifier", UserUtils.getCurrentPrincipleID()).
                set("gmt_modified", DateUtil.now());
        introduceDetailFacade.update(new IntroduceDetail(), introduceDetailUpdateWrapper);
        //删除提示信息
        UpdateWrapper<IntroduceInfo> introduceInfoUpdateWrapper = new UpdateWrapper<>();
        introduceInfoUpdateWrapper.in("id", ids).
                eq("is_deleted", IsDeleteEnum.N.getKey()).
                set("is_deleted", IsDeleteEnum.Y.getKey()).
                set("modifier", UserUtils.getCurrentPrincipleID()).
                set("gmt_modified", DateUtil.now());
        this.update(new IntroduceInfo(), introduceInfoUpdateWrapper);
        return true;
    }

    /**
     * 获取提示信息分页信息，带条件
     *
     * @param introducePageVO
     * @return
     */
    public IPage<IntroducePageDTO> getIntroducePageByMap(IntroducePageVO introducePageVO) {
        IPage<IntroducePageDTO> introducePageDTOIPage = this.getIntroducePage(introducePageVO);
        List<IntroducePageDTO> records = introducePageDTOIPage.getRecords();
        for (IntroducePageDTO introducePageDTO : records) {
            introducePageDTO.setOperator(introducePageDTO.getModifier());
            introducePageDTO.setGmtOperate(introducePageDTO.getGmtModified());
        }
        List<String> userIds = records.stream().map(introduceList -> introduceList.getOperator()).collect(Collectors.toList());
        RespDTO<Map<String, String>> userInfos = userServiceClient.getUserInfoByIds(userIds);
        if (userInfos != null) {
            Map<String, String> userInfoMap = userInfos.data;
            for (IntroducePageDTO introducePageDTO : records) {
                if (userInfoMap.containsKey(introducePageDTO.getOperator())) {
                    introducePageDTO.setOperatorName(userInfoMap.get(introducePageDTO.getOperator()));
                }
            }
        }
        introducePageDTOIPage.setRecords(records);
        return introducePageDTOIPage;
    }

    /**
     * 带条件查询
     *
     * @param map
     * @return
     */
    public List<IntroduceInfo> getByMap(Map<String, Object> map) {
        QueryWrapper<IntroduceInfo> introduceInfoQueryWrapper = new QueryWrapper<>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            introduceInfoQueryWrapper.eq(entry.getKey(), entry.getValue());
        }
        return this.list(introduceInfoQueryWrapper);
    }

    /**
     * 根据id获取提示信息
     *
     * @param id
     * @return
     */
    public IntroducePageDTO getIntroduceById(Long id) {
        IntroducePageDTO introducePageDTO = new IntroducePageDTO();
        IntroduceInfo introduceInfo = this.getById(id);
        BeanUtil.copyProperties(introduceInfo, introducePageDTO);

        QueryWrapper<IntroduceMap> introduceMapQueryWrapper = new QueryWrapper<>();
        introduceMapQueryWrapper.eq("introduce_id", id).eq("is_deleted", IsDeleteEnum.N.getKey());
        List<IntroduceMap> introduceMapList = introduceMapFacade.list(introduceMapQueryWrapper);

        List<Long> questionIds = introduceMapList.stream().map(introduceMap -> introduceMap.getQuestionId()).collect(Collectors.toList());
        if(ListUtil.isNotEmpty(questionIds)) {
            QueryWrapper<QuestionInfo> questionInfoQueryWrapper = new QueryWrapper<>();
            questionInfoQueryWrapper.in("id", questionIds).eq("is_deleted", IsDeleteEnum.N.getKey());
            List<QuestionInfo> questionInfoList = questionFacade.list(questionInfoQueryWrapper);

            List<QuestionShortDTO> questionShortDTOList = Lists.newLinkedList();
            String tagName = "";
            for (QuestionInfo questionInfo : questionInfoList) {
                QuestionShortDTO questionShortDTO = new QuestionShortDTO();
                BeanUtil.copyProperties(questionInfo, questionShortDTO);
                questionShortDTOList.add(questionShortDTO);
                tagName += questionInfo.getTagName() + ",";
            }
            if (tagName.endsWith(",")) {
                tagName = tagName.substring(0, tagName.length() - 1);
            }
            introducePageDTO.setTagName(tagName);
            introducePageDTO.setQuestionList(questionShortDTOList);
        }

        //未关联的标签
        /*QueryWrapper<QuestionInfo> unRelatedQuestionWrapper = new QueryWrapper<>();
        unRelatedQuestionWrapper.eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("sub_type", 0)
                .notIn("id", questionIds);
        List<QuestionInfo> unRelatedQuestionList = questionFacade.list(unRelatedQuestionWrapper);

        List<QuestionShortDTO> unRelatedQuestionDTOList
                = BeanUtil.listCopyTo(unRelatedQuestionList, QuestionShortDTO.class);
        introducePageDTO.setUnRelatedQuestionList(unRelatedQuestionDTOList);*/

        //提示信息明细
        QueryWrapper<IntroduceDetail> introduceDetailQueryWrapper=new QueryWrapper<>();
        introduceDetailQueryWrapper.eq("is_deleted",IsDeleteEnum.N).eq("introduce_id",id).orderByAsc("order_no");
        List<IntroduceDetail> introduceDetailList=introduceDetailFacade.list(introduceDetailQueryWrapper);
        introducePageDTO.setDetails(introduceDetailList);

        return introducePageDTO;
    }

    /**
     * 获取未关联标签列表
     *
     * @return
     */
    public List<QuestionShortDTO> getAllQuestionList() {
        QueryWrapper<QuestionInfo> unRelatedQuestionWrapper = new QueryWrapper<>();
        unRelatedQuestionWrapper.eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("sub_type", 0);
        List<QuestionInfo> unRelatedQuestionList = questionFacade.list(unRelatedQuestionWrapper);

        List<QuestionShortDTO> unRelatedQuestionDTOList
                = BeanUtil.listCopyTo(unRelatedQuestionList, QuestionShortDTO.class);
        return unRelatedQuestionDTOList;
    }
}