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

import com.pcloud.appcenter.assist.dto.AssistTempletDTO;
import com.pcloud.book.applet.biz.AppletBooklistBiz;
import com.pcloud.book.applet.contants.AppletConstants;
import com.pcloud.book.applet.dao.AppletBooklistClassifyDao;
import com.pcloud.book.applet.dao.AppletBooklistDao;
import com.pcloud.book.applet.dto.AddBookParamDTO;
import com.pcloud.book.applet.dto.AppletBooklistClassifyDTO;
import com.pcloud.book.applet.dto.AppletBooklistDTO;
import com.pcloud.book.applet.dto.BookDTO4Booklist;
import com.pcloud.book.applet.entity.AppletBooklist;
import com.pcloud.book.applet.entity.AppletBooklistClassify;
import com.pcloud.book.applet.entity.AppletBooklistClassifyUser;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.biz.BookBiz;
import com.pcloud.book.book.dao.BookRaysClassifyDao;
import com.pcloud.book.consumer.app.AssistTempletConsr;
import com.pcloud.book.consumer.user.AdviserConsr;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.cache.redis.JedisClusterUtils;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 小程序书单
 */
@Component
public class AppletBooklistBizImpl implements AppletBooklistBiz {


    @Autowired
    private AppletBooklistClassifyDao appletBooklistClassifyDao;
    @Autowired
    private AppletBooklistDao appletBooklistDao;
    @Autowired
    private AdviserConsr adviserConsr;
    @Autowired
    private AssistTempletConsr assistTempletConsr;
    @Autowired
    private BookBiz bookBiz;
    @Autowired
    private BookRaysClassifyDao bookRaysClassifyDao;


    @Override
    public Long addBooklistClassify(AppletBooklistClassify appletBooklistClassify) {
        Integer seq = appletBooklistClassifyDao.getMaxSeq();
        appletBooklistClassify.setSeq(seq+1);
        appletBooklistClassify.setShowState(false);
        appletBooklistClassifyDao.insert(appletBooklistClassify);
        return appletBooklistClassify.getId();
    }

    @Override
    public void deleteBooklistClassifyById(Long id) {
        List<AppletBooklist> booklists = appletBooklistDao.getByClassifyId(id);
        if (!ListUtils.isEmpty(booklists)){
            throw new BookBizException(BookBizException.ERROR,"请先删除关联书单");
        }
        appletBooklistClassifyDao.deleteById(id);
    }

    @Override
    public void updateBooklistClassify(AppletBooklistClassify appletBooklistClassify) {
        if (null==appletBooklistClassify.getId()){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少id");
        }
        appletBooklistClassifyDao.update(appletBooklistClassify);
        JedisClusterUtils.del(AppletConstants.HOME_BOOKLIST);
    }

    @Override
    public PageBeanNew<AppletBooklistClassifyDTO> listBooklistClassify(Integer currentPage, Integer numPerPage, String name) {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("name", name);
        PageBeanNew<AppletBooklistClassifyDTO> pageBeanNew = appletBooklistClassifyDao.listPageNew(
                new PageParam(currentPage,numPerPage) ,paramMap,"listBooklistClassify");
        return pageBeanNew;
    }

    @Override
    public Long addBooklist(AppletBooklist appletBooklist) {
        appletBooklistDao.insert(appletBooklist);
        return appletBooklist.getId();
    }

    @Override
    public void deleteBooklistById(Long id) {
        appletBooklistDao.deleteById(id);
        appletBooklistDao.deleteConfigByBooklistId(id);
        //删除客户端缓存
        JedisClusterUtils.del(AppletConstants.BOOKLIST_BOOK+id);
        JedisClusterUtils.del(AppletConstants.HOME_BOOKLIST);
    }

    @Override
    public void updateBooklist(AppletBooklist appletBooklist) {
        if (null==appletBooklist.getId()){
            throw new BookBizException(BookBizException.PARAM_IS_NULL,"缺少id");
        }
        appletBooklistDao.update(appletBooklist);
    }

    @Override
    public AppletBooklistDTO getBooklistById(Long id) {
        AppletBooklist appletBooklist = appletBooklistDao.getById(id);
        AppletBooklistDTO dto = new AppletBooklistDTO();
        if (null != appletBooklist){
            BeanUtils.copyProperties(appletBooklist,dto);
        }
        return dto;
    }

    @Override
    public PageBeanNew<AppletBooklistDTO> listBooklist(Integer currentPage, Integer numPerPage, String name, Long classifyId) {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("name", name);
        paramMap.put("classifyId", classifyId);
        PageBeanNew<AppletBooklistDTO> pageBeanNew = appletBooklistDao.listPageNew(
                new PageParam(currentPage,numPerPage), paramMap,"listBooklist");
        if(null == pageBeanNew || ListUtils.isEmpty(pageBeanNew.getRecordList())){
            return new PageBeanNew<>(currentPage,numPerPage,0,new ArrayList<>());
        }
        List<Long> booklistIds = pageBeanNew.getRecordList().stream().filter(s->s!=null).map(AppletBooklistDTO::getId).collect(Collectors.toList());
        List<BookDTO4Booklist> booklists = appletBooklistDao.getConfigByBooklistIds(booklistIds);
        Map<Long,List<BookDTO4Booklist>> map = new HashMap<>();
        if (!ListUtils.isEmpty(booklists)){
           map = booklists.stream().collect(Collectors.groupingBy(BookDTO4Booklist::getBooklistId));
        }
        for (AppletBooklistDTO booklistDTO: pageBeanNew.getRecordList()){
            if (!MapUtils.isEmpty(map) && map.containsKey(booklistDTO.getId())){
                List<BookDTO4Booklist> bookDTO4Booklists = map.get(booklistDTO.getId());
                booklistDTO.setBookDTO4Booklists(bookDTO4Booklists);
            }
        }
        return pageBeanNew;
    }

    @Override
    public void addBookToBooklist(AddBookParamDTO addBookParamDTO) {
        Long booklistId = addBookParamDTO.getBooklistId();
        List<BookDTO4Booklist> configDTOS = addBookParamDTO.getBookDTO4Booklists();
        for(BookDTO4Booklist bookDTO4Booklist:configDTOS){
            bookDTO4Booklist.setBooklistId(booklistId);
            bookDTO4Booklist.setSeq(configDTOS.indexOf(bookDTO4Booklist));
        }
        appletBooklistDao.deleteConfigByBooklistId(booklistId);
        appletBooklistDao.addBooklistConfig(configDTOS);
        //删除客户端缓存
        JedisClusterUtils.del(AppletConstants.BOOKLIST_BOOK+booklistId);
        JedisClusterUtils.del(AppletConstants.HOME_BOOKLIST);
    }

    @Override
    public PageBeanNew<BookDTO4Booklist> listPageBook4AppletBooklist(Long booklistId, Integer currentPage, Integer numPerPage) {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("booklistId", booklistId);
        PageBeanNew<BookDTO4Booklist> pageBeanNew = appletBooklistDao.listPageNew(
                new PageParam(currentPage,numPerPage), paramMap, "listPageBook4AppletBooklist");
        if (null == pageBeanNew || ListUtils.isEmpty(pageBeanNew.getRecordList())){
            return new PageBeanNew<>(currentPage,numPerPage,0,new ArrayList<>());
        }
        fillAgentTempletName(pageBeanNew.getRecordList());
        return pageBeanNew;
    }

    private void fillAgentTempletName(List<BookDTO4Booklist> list) {
        List<Long> adviserIds=list.stream().filter(s->s.getAdviserId()!=null).map(BookDTO4Booklist::getAdviserId).distinct().collect(Collectors.toList());
        Map<Long, AdviserBaseInfoDto> infoDtoMap = adviserConsr.getAdviserId2AdviserInfoDtoMap(adviserIds);
        List<Long> templetIds = new ArrayList<>();
        list.forEach(dto4Booklist -> {
            if (Objects.nonNull(dto4Booklist.getTempletId())) {
                templetIds.add(dto4Booklist.getTempletId());
            }
            if (Objects.nonNull(dto4Booklist.getSecondTempletId())) {
                templetIds.add(dto4Booklist.getSecondTempletId());
            }
        });
        Map<Long, AssistTempletDTO> assistTempletDTOMap = assistTempletConsr.mapByIds(templetIds);
        for (BookDTO4Booklist dto4Booklist : list) {
            Long secondTempletId = dto4Booklist.getSecondTempletId();
            Long templetId = dto4Booklist.getTempletId();
            if (secondTempletId!=null&&assistTempletDTOMap!=null) {
                AssistTempletDTO templetDTO = assistTempletDTOMap.get(secondTempletId);
                dto4Booklist.setSecondTempletName(Optional.ofNullable(templetDTO).map(AssistTempletDTO::getTempletName).orElse(null));
            }
            if (templetId!=null && assistTempletDTOMap!=null) {
                AssistTempletDTO templetDTO = assistTempletDTOMap.get(templetId);
                dto4Booklist.setTempletName(Optional.ofNullable(templetDTO).map(AssistTempletDTO::getTempletName).orElse(null));
            }
            Long adviserId=dto4Booklist.getAdviserId();
            if (!MapUtils.isEmpty(infoDtoMap)){
                AdviserBaseInfoDto infoDto = infoDtoMap.get(adviserId);
                if (infoDto!=null){
                    dto4Booklist.setAgentName(infoDto.getAgentName());
                }
            }
        }
    }

    @Override
    public void updateBookSeq(Long configId, Integer seq) {
        appletBooklistDao.updateBookSeq(configId, seq);
    }

    @Override
    public List<AppletBooklistClassifyDTO> getAllBooklistClassify(Boolean showState){
        return appletBooklistClassifyDao.getAllBooklistClassify(showState);
    }

    @Override
    public PageBeanNew<AppletBooklistDTO> listBooklist4Wechat(Long classifyId, Integer currentPage, Integer numPerPage, Long wechatUserId) {
        PageBeanNew<AppletBooklistDTO> pageBeanNew = new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
        Map<String, Object> map = new HashMap<>();
        if (null == classifyId) {//首页书单推荐
            List<Long> classifyIds = appletBooklistClassifyDao.getClassifyIdsByUserId(wechatUserId);
            if (ListUtils.isEmpty(classifyIds)) {//没有栏目id取第一个
                List<AppletBooklistClassifyDTO> classifyDTOS = getAllBooklistClassify(true);
                if (ListUtils.isEmpty(classifyDTOS)) {
                    return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
                }
                classifyId = classifyDTOS.get(0).getId();
                classifyIds.add(classifyId);
            }
            map.put("classifyIdList", classifyIds);
            map.put("order", 1);
            //首页3条缓存5小时
            if (currentPage==0 && numPerPage==3){
                List<AppletBooklistDTO> homeList = JedisClusterUtils.getJsonList(AppletConstants.HOME_BOOKLIST, AppletBooklistDTO.class);
                if (!ListUtils.isEmpty(homeList)) {
                    pageBeanNew = new PageBeanNew<>(0, 3, homeList.size(), homeList);
                } else {
                    pageBeanNew = appletBooklistDao.listPageNew(new PageParam(0, 3), map, "listBooklist4Wechat");
                    JedisClusterUtils.setJsonList(AppletConstants.HOME_BOOKLIST, pageBeanNew.getRecordList(), 5 * 3600);
                }
            }
        } else {
            map.put("classifyId", classifyId);
        }
        if (ListUtils.isEmpty(pageBeanNew.getRecordList())){
            pageBeanNew = appletBooklistDao.listPageNew(new PageParam(currentPage, numPerPage), map, "listBooklist4Wechat");
        }
        if (null == pageBeanNew || ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, 0, new ArrayList<>());
        }
        for (AppletBooklistDTO booklistDTO : pageBeanNew.getRecordList()) {
            Long booklistId = booklistDTO.getId();
            String key = AppletConstants.BOOKLIST_BOOK + booklistId;
            List<BookDTO4Booklist> bookList = JedisClusterUtils.getJsonList(key, BookDTO4Booklist.class);
            if (ListUtils.isEmpty(bookList)) {
                bookList = appletBooklistDao.getBookBaseByBooklistId(booklistId, 0, 3);
                JedisClusterUtils.setJson(key, bookList);
                JedisClusterUtils.expire(key, 3600);
            }
            booklistDTO.setBookDTO4Booklists(bookList);
        }
        return pageBeanNew;
    }

    @Override
    public AppletBooklistDTO getBooklistById4Wechat(Long booklistId){
        AppletBooklistDTO booklistDTO = getBooklistById(booklistId);
        if (null==booklistDTO){
            return new AppletBooklistDTO();
        }
        List<BookDTO4Booklist> bookList = appletBooklistDao.listPageBook4AppletBooklist(booklistId);
        if (!ListUtils.isEmpty(bookList)){
            fillAgentTempletName(bookList);
            booklistDTO.setBookDTO4Booklists(bookList);
            booklistDTO.setBookCounts(bookList.size());
        }
        return booklistDTO;
    }

    @Override
    public BookDTO4Booklist getByBookIdAdviserChannel(Long adviserId, Long channelId, Long bookId) {
        BookDTO4Booklist bookDTO4Booklist = appletBooklistDao.getByBookIdAdviserChannel(adviserId,channelId,bookId);
        if (null!=bookDTO4Booklist){
            fillAgentTempletName(Arrays.asList(bookDTO4Booklist));
        }
        return bookDTO4Booklist;
    }

    @Override
    public void addUserBooklistClassify(List<Long> classifyIds, Long wechatUserId) {
        if (null == wechatUserId){
            return;
        }
        appletBooklistClassifyDao.deleteClassifyByWechatUesrId(wechatUserId);
        if (ListUtils.isEmpty(classifyIds)){
            List<AppletBooklistClassifyDTO> classifyDTOS = getAllBooklistClassify(true);
            if (ListUtils.isEmpty(classifyDTOS)){
                return;
            }
            classifyIds.add(classifyDTOS.get(0).getId());
        }
        List<AppletBooklistClassifyUser> addList = new ArrayList<>();
        for (Long classifyId : classifyIds){
            AppletBooklistClassifyUser classifyUser = new AppletBooklistClassifyUser();
            classifyUser.setClassifyId(classifyId);
            classifyUser.setWechatUserId(wechatUserId);
            addList.add(classifyUser);
        }
        appletBooklistClassifyDao.batchInsertUserBooklistClassify(addList);
    }

    @Override
    public List<AppletBooklistClassifyDTO> getAllBooklistClassify4Wechat(Long wechatUserId) {
        List<AppletBooklistClassifyDTO> list = appletBooklistClassifyDao.getAllBooklistClassify(true);
        if (ListUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<Long> chooseIds = appletBooklistClassifyDao.getClassifyIdsByUserId(wechatUserId);
        if (ListUtils.isEmpty(chooseIds)) {
            chooseIds.add(list.get(0).getId());
        }
        for (AppletBooklistClassifyDTO appletNewsClassifyDTO : list) {
            if (!ListUtils.isEmpty(chooseIds) && chooseIds.contains(appletNewsClassifyDTO.getId())) {
                appletNewsClassifyDTO.setChoose(true);
            } else {
                appletNewsClassifyDTO.setChoose(false);
            }
        }
        return list;
    }

    @Override
    public List<AppletBooklistClassifyDTO> getBooklistClassifyByUser(Long wechatUserId) {
        List<AppletBooklistClassifyDTO> list = appletBooklistClassifyDao.getClassifysByUserId(wechatUserId);
        if (ListUtils.isEmpty(list)){
            List<AppletBooklistClassifyDTO> allBooklistClassify = appletBooklistClassifyDao.getAllBooklistClassify(true);
            if (ListUtils.isEmpty(allBooklistClassify)){
                return new ArrayList<>();
            }
            list.add(allBooklistClassify.get(0));
        }
        return list;
    }
}
