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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.biz.BookLabelBiz;
import com.pcloud.book.book.constant.BookConstant;
import com.pcloud.book.book.dao.BookAdviserDao;
import com.pcloud.book.book.dao.BookDao;
import com.pcloud.book.book.dao.BookLabelDao;
import com.pcloud.book.book.dao.BookLabelTrimDao;
import com.pcloud.book.book.dao.BookLabelTrimRelateDao;
import com.pcloud.book.book.dto.BookDto;
import com.pcloud.book.book.entity.BookLabel;
import com.pcloud.book.book.entity.BookLabelTrim;
import com.pcloud.book.book.entity.BookLabelTrimRelate;
import com.pcloud.book.book.enums.BookLabelAuditState;
import com.pcloud.book.book.vo.BookLabelVO;
import com.pcloud.book.consumer.user.AdviserConsr;
import com.pcloud.book.es.biz.ESBookAndAdviserBiz;
import com.pcloud.book.util.properties.BookProps;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.core.constant.SystemCode;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.cache.redis.JedisClusterUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.resourcecenter.base.enums.AuditStateEnum;
import com.pcloud.usercenter.party.adviser.dto.AdviserBaseInfoDto;

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

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;

import static com.pcloud.book.book.constant.BookConstant.BOOK_CACHE_SECOUND;

@Component("bookLabelBiz")
@Slf4j
public class BookLabelBizImpl implements BookLabelBiz {

    @Autowired
    private BookLabelDao bookLabelDao;
    @Autowired
    private AdviserConsr adviserConsr;
    @Autowired
    private BookLabelTrimRelateDao bookLabelTrimRelateDao;
    @Autowired
    private BookDao bookDao;
    @Autowired
    private BookLabelTrimDao bookLabelTrimDao;
    @Autowired
    private ESBookAndAdviserBiz esBookAndAdviserBiz;
    @Autowired
    private BookAdviserDao bookAdviserDao;

    @Override
    public void applyBookLabel(BookLabel bookLabel, String systemCode) {
        List<BookLabel> labels = bookLabelDao.getListByType(bookLabel.getType(), null);
        List<String> names = labels.stream().filter(s->s.getName()!=null).map(BookLabel::getName).collect(Collectors.toList());
        if (names.contains(bookLabel.getName())){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"标签名称重复或已申请");
        }
        Integer seq = bookLabelDao.getMaxSeqByType(bookLabel.getType());
        if (SystemCode.pcloud.code.equalsIgnoreCase(systemCode)){//平台端直接新增
            bookLabel.setAuditState(BookLabelAuditState.pass.code);
            bookLabel.setSeq(seq+1);
            bookLabelDao.insert(bookLabel);
        } else if (SystemCode.adviser.code.equalsIgnoreCase(systemCode)){//编辑端要审核
            if (StringUtil.isEmpty(bookLabel.getRemark())){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少标签申请说明");
            }
            bookLabel.setAuditState(BookLabelAuditState.wait.code);
            bookLabel.setSeq(seq+1);
            bookLabelDao.insert(bookLabel);
        }
        JedisClusterUtils.del(BookConstant.BOOK_LABEL_CACHE);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditBookLabel(BookLabelVO bookLabelVO) {
        BookLabel updateLabel = new BookLabel();
        updateLabel.setId(bookLabelVO.getLabelId());
        updateLabel.setAuditState(bookLabelVO.getAuditState());
        if (BookLabelAuditState.update_pass.code.equals(bookLabelVO.getAuditState())){//修改后入库
            List<BookLabel> labels = bookLabelDao.getListByType(bookLabelVO.getType(), null);
            List<String> names = labels.stream().filter(s->s.getName()!=null).map(BookLabel::getName).collect(Collectors.toList());
            if (names.contains(bookLabelVO.getName())){
                throw new BookBizException(BookBizException.PARAM_IS_NULL,"标签名称重复或已申请");
            }
            BookLabel bookLabel = new BookLabel();
            bookLabel.setType(bookLabelVO.getType());
            bookLabel.setName(bookLabelVO.getName());
            bookLabel.setCreateUser(0L);
            bookLabel.setAuditState(BookLabelAuditState.pass.code);
            Integer seq = bookLabelDao.getMaxSeqByType(bookLabel.getType());
            bookLabel.setSeq(seq+1);
            bookLabelDao.insert(bookLabel);
            Long labelId = bookLabel.getId();
            updateLabel.setUpdateLabelId(labelId);
        }
        bookLabelDao.update(updateLabel);
        JedisClusterUtils.del(BookConstant.BOOK_LABEL_CACHE);
    }

    @Override
    public void deleteById(Long labelId) {
        bookLabelDao.deleteById(labelId);
        JedisClusterUtils.del(BookConstant.BOOK_LABEL_CACHE);
    }

    @Override
    public void updateLabelSeq(Long labelId, Integer seq) {
        BookLabel updateLabel = new BookLabel();
        updateLabel.setId(labelId);
        updateLabel.setSeq(seq);
        bookLabelDao.update(updateLabel);
        JedisClusterUtils.del(BookConstant.BOOK_LABEL_CACHE);
    }

    @Override
    public PageBeanNew<BookLabelVO> listAuditPassBookLabel(Integer labelType, Integer currentPage, Integer numPerPage) {
        Map<String,Object> map = new HashMap<>();
        map.put("type", labelType);
        map.put("auditState", BookLabelAuditState.pass.code);
        PageBeanNew<BookLabelVO> pageBeanNew = bookLabelDao.listPageNew(new PageParam(currentPage,numPerPage), map,"listBookLabel");
        return pageBeanNew;
    }

    @Override
    public PageBeanNew<BookLabelVO> listApplyBookLabel(Integer labelType, Integer currentPage, Integer numPerPage, String name,
                                                       String startTime, String endTime, Integer auditState) {
        Map<String,Object> map = new HashMap<>();
        map.put("type", labelType);
        map.put("name", name);
        map.put("startTime", startTime);
        map.put("endTime", endTime);
        map.put("filterApply", 1);
        map.put("auditState", auditState);
        PageBeanNew<BookLabelVO> pageBeanNew = bookLabelDao.listPageNew(new PageParam(currentPage,numPerPage), map,"listBookLabel");
        if (null ==pageBeanNew || ListUtils.isEmpty(pageBeanNew.getRecordList())){
            return new PageBeanNew<>(currentPage,numPerPage,0,new ArrayList<>());
        }
        List<BookLabelVO> list = pageBeanNew.getRecordList();
        List<Long> adviserIds = list.stream().filter(s->s.getCreateUser()>0).map(BookLabelVO::getCreateUser).distinct().collect(Collectors.toList());
        Map<Long, AdviserBaseInfoDto> adviserBaseInfoDtoMap = new HashMap<>();
        if (!ListUtils.isEmpty(adviserIds)){
            adviserBaseInfoDtoMap = adviserConsr.getAdviserId2AdviserInfoDtoMap(adviserIds);
        }
        for (BookLabelVO bookLabelVO:list){
            if (!MapUtils.isEmpty(adviserBaseInfoDtoMap) && adviserBaseInfoDtoMap.containsKey(bookLabelVO.getCreateUser())){
                AdviserBaseInfoDto adviserBaseInfoDto = adviserBaseInfoDtoMap.get(bookLabelVO.getCreateUser());
                if (null!=adviserBaseInfoDto){
                    bookLabelVO.setAdviserName(adviserBaseInfoDto.getPartyName());
                    bookLabelVO.setAgentName(adviserBaseInfoDto.getAgentName());
                    bookLabelVO.setPhoneNum(adviserBaseInfoDto.getPhoneNum());
                }
            }
        }
        return pageBeanNew;
    }

    @Override
    public Map<Long, String> getLabelMapByIds(List<Long> labelIds) {
        if(ListUtils.isEmpty(labelIds)){
            return new HashMap<>();
        }
        List<BookLabel> labelList = bookLabelDao.getByLabelIds(new ArrayList<>(labelIds));
        if(ListUtils.isEmpty(labelList)){
            return  new HashMap<>();
        }
        Map<Long, String> map = labelList.stream().collect(Collectors.toMap(a -> a.getId(), a -> a.getName(), (k1, k2) -> (k2)));
        return map;
    }

    @Override
    public List<BookLabelVO> getLabelByIds(List<Long> labelIds) {
        List<BookLabel> labelList = bookLabelDao.getByLabelIds(labelIds);
        if (ListUtils.isEmpty(labelList)) {
            return new ArrayList<>();
        }
        List<BookLabelVO> labelVOS = new ArrayList<>();
        for (BookLabel bookLabel : labelList) {
            BookLabelVO bookLabelVO = new BookLabelVO();
            BeanUtils.copyProperties(bookLabel, bookLabelVO);
            bookLabelVO.setLabelId(bookLabel.getId());
            labelVOS.add(bookLabelVO);
        }
        return labelVOS;
    }

    @Override
    @ParamLog("根据类型获取已经通过审核的标签")
    public List<BookLabel> getBookLabelsByType(Integer labelType) {
        List<BookLabel> bookLabels = new ArrayList<>();
        String labelKey = BookConstant.BOOK_LABEL_CACHE + "RAYS_QUESTION";
        bookLabels = JedisClusterUtils.getJsonList(labelKey, BookLabel.class);
        if (ListUtils.isEmpty(bookLabels)) {
            bookLabels = bookLabelDao.getListByType(labelType, AuditStateEnum.AUDIT_SUCCESS.value);
            if (!ListUtils.isEmpty(bookLabels)) {
                JedisClusterUtils.setJsonList(labelKey, bookLabels, BOOK_CACHE_SECOUND);
            }
        }
        return ListUtils.isEmpty(bookLabels) ? new ArrayList<>() : bookLabels;
    }


    /**
     * 整理后的标签查询，只支持生产环境
     * @author：zhuyajie
     * @date：2021/8/5 16:43
     *  * @param null
     */
    private Map<String, Object> getLabel(Long bookId, String bookName) {
        if (!"pro".equals(BookProps.getSystemEnv())) {
            return new HashMap<>();
        }
        Map<String, Object> labelMap = new HashMap<>();
        try {
            JSONObject dataJsonObj = new JSONObject();
            dataJsonObj.put(bookId.toString(), bookName);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("data", dataJsonObj);
            jsonObject.put("type", "book");
            String response = HttpUtil.post("http://192.168.92.168:8000/getLabels", jsonObject.toString());
            // 解析结果
            JSONObject object = JSONObject.parseObject(response);
            log.info("标签解析结果==" + object.toString());
            if (!"success".equals(object.getString("info")) || StringUtil.isEmpty(object.getString("data"))) {
                return null;
            }
            Map<String, Object> stringObjectMap = JSON.parseObject(object.getString("data"), new TypeReference<Map<String, Object>>() {
            });
            if (null == stringObjectMap.get(bookId.toString())) {
                return null;
            }
            labelMap = (Map<String, Object>) stringObjectMap.get(bookId.toString());
        } catch (Exception e) {
            log.error("调用查标签失败" + e.getMessage(), e);
        }
        return labelMap;
    }

    @Override
    public void addBookNewLabel(List<Long> bookIds) {
        if(ListUtils.isEmpty(bookIds)) {
            return;
        }
        if (!"pro".equals(BookProps.getSystemEnv())) {
            //只支持查生产环境
            return;
        }
        Map<Long,BookDto> bookDtoMap = bookDao.getMapByBookIds(bookIds);
        if (MapUtils.isEmpty(bookDtoMap)) {
            return;
        }
        //已有标签
        Map<Long,BookLabelTrimRelate> labelTrimRelateMap = bookLabelTrimRelateDao.mapBookTrimLabel(bookIds);
        for (BookDto bookDto : bookDtoMap.values()) {
            Map<String, Object> labelMap = this.getLabel(bookDto.getBookId(), bookDto.getBookName());
            BookLabelTrimRelate labelTrimRelate = new BookLabelTrimRelate();
            labelTrimRelate.setBookId(bookDto.getBookId());
            labelTrimRelate.setLabel1((String) labelMap.get("label1"));
            labelTrimRelate.setLabel2((String) labelMap.get("label2"));
            labelTrimRelate.setLabel3((String) labelMap.get("label3"));
            labelTrimRelate.setLabel4((String) labelMap.get("label4"));
            if (!MapUtils.isEmpty(labelTrimRelateMap) && labelTrimRelateMap.containsKey(bookDto.getBookId())) {
                //修改
                BookLabelTrimRelate relate = labelTrimRelateMap.get(bookDto.getBookId());
                labelTrimRelate.setId(relate.getId());
                bookLabelTrimRelateDao.update(labelTrimRelate);
            } else {
                //新增
                bookLabelTrimRelateDao.insert(labelTrimRelate);
            }
        }
        esBookAndAdviserBiz.updateBookAndAdviserToES(bookIds);
    }

    @Override
    public Map<Long, BookLabelTrimRelate> mapBookTrimLabel(List<Long> bookIds) {
        if (ListUtils.isEmpty(bookIds)) {
            return new HashMap<>();
        }
        return bookLabelTrimRelateDao.mapBookTrimLabel(bookIds);
    }

    @Override
    public List<BookLabelTrim> getBookLabelTrimList(Integer type) {
        return bookLabelTrimDao.getBookLabelTrimList(type);
    }

    @Override
    public void updateYesterdayBookNewLabel() {
        Date yesterday = DateUtils.addDay(new Date(),-1);
        String startTime = DateUtils.formatDate(DateUtils.getDayStart(yesterday), DateUtils.DATE_FORMAT_DATETIME);
        String endTime = DateUtils.formatDate(DateUtils.getDayEnd(yesterday), DateUtils.DATE_FORMAT_DATETIME);
        List<Long> bookIds = bookAdviserDao.getYesterdayUpdateBookIds(startTime, endTime);
        if (!ListUtils.isEmpty(bookIds)) {
            this.addBookNewLabel(bookIds);
        }
    }
}
