package com.liquidnet.client.admin.zhengzai.smile.service.impl;


import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.liquidnet.client.admin.common.core.domain.AjaxResult;
import com.liquidnet.client.admin.common.core.page.TableDataInfo;
import com.liquidnet.client.admin.common.utils.StringUtils;
import com.liquidnet.client.admin.zhengzai.smile.dto.*;
import com.liquidnet.client.admin.zhengzai.smile.service.ISmileShowService;
import com.liquidnet.client.admin.zhengzai.smile.utils.SmileRedisUtils;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.galaxy.utils.ObjectUtil;
import com.liquidnet.service.goblin.constant.SmileRedisConst;
import com.liquidnet.service.goblin.dto.vo.SmileAgentVo;
import com.liquidnet.service.goblin.dto.vo.SmileUserVO;
import com.liquidnet.service.kylin.dao.TicketAndStatusDao;
import com.liquidnet.service.kylin.dao.report.KylinPerformancesDto;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.kylin.dto.vo.partner.KylinPerformancesVo;
import com.liquidnet.service.kylin.entity.KylinPerformances;
import com.liquidnet.service.kylin.mapper.*;
import com.liquidnet.service.smile.entity.SmileAgent;
import com.liquidnet.service.smile.entity.SmilePrice;
import com.liquidnet.service.smile.entity.SmileSchool;
import com.liquidnet.service.smile.entity.SmileUser;
import com.liquidnet.service.smile.entity.dto.ShowBaseVoDto;
import com.liquidnet.service.smile.mapper.SmileAgentMapper;
import com.liquidnet.service.smile.mapper.SmilePriceMapper;
import com.liquidnet.service.smile.mapper.SmileSchoolMapper;
import com.liquidnet.service.smile.mapper.SmileUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author liquidnet
 * @since 2022-03-14
 */
@Slf4j
@Service
public class SmileShowServiceImpl extends ServiceImpl<SmileSchoolMapper, SmileSchool> implements ISmileShowService {

    @Autowired
    SmileRedisUtils smileRedisUtils;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    KylinPerformancesMapper kylinPerformancesMapper;

    @Autowired
    KylinOrderTicketRelationsMapper kylinOrderTicketRelationsMapper;

    @Autowired
    KylinOrderTicketsMapper kylinOrderTicketsMapper;

    @Autowired
    SmileAgentMapper smileAgentMapper;

    @Autowired
    KylinTicketsMapper kylinTicketsMapper;

    @Autowired
    SmileUserMapper smileUserMapper;

    @Autowired
    SmilePriceMapper smilePriceMapper;

    @Autowired
    KylinPerformanceStatusMapper kylinPerformanceStatusMapper;

    @Override
    public TableDataInfo listShow(SmileShowParam smileShowParam) {
        PageHelper.startPage(smileShowParam.getPageNum(), smileShowParam.getPageSize());
        TableDataInfo rspData = new TableDataInfo();
        //查询所有代理的演出id
        List<KylinPerformancesDto> kylinPerformancesList = kylinPerformancesMapper.selectPerIdByAgent();
        List<ShowVo> showVoList = kylinPerformancesList.stream().map(kylinPerformancesDto -> {
            ShowVo vo = ShowVo.getNew().copy(kylinPerformancesDto);
            Integer ordNum = kylinOrderTicketRelationsMapper.concatByAgentDed(kylinPerformancesDto.getPerformancesId());
            vo.setTotalOutAgent(ordNum);
            //打款状态
            vo.setStatus(smileRedisUtils.getShowStatus(kylinPerformancesDto.getPerformancesId()));
            //判断该演出是否打款
            Integer showPriceId = smileRedisUtils.getShowPriceId(kylinPerformancesDto.getPerformancesId());
            if (showPriceId != null) {
                //返回记录中的缓存  保证打款外部数据不变
                return smileRedisUtils.getShowVoByPerId(kylinPerformancesDto.getPerformancesId());
            } else {
                //redis保存演出数据
                smileRedisUtils.setShowVoByPerId(vo);
                return vo;
            }
        }).collect(Collectors.toList());
        rspData.setCode(0);
        rspData.setRows(showVoList);
        rspData.setTotal(new PageInfo(kylinPerformancesList).getTotal());
        return rspData;
    }

    @Override
    public AjaxResult sort(ShowSort showSort) {

        //查询数据库是否又该顺序的演出
        kylinPerformancesMapper.updateComment(showSort.getSort());
        kylinPerformancesMapper.updateCommentByPer(showSort.getSort(), showSort.getPerformancesId());
        log.info("redis show key:{}", showSort.getPerformancesId());
        //判断该演出是否修改过票提
        List<String> showIds = smileRedisUtils.getShowIds();
        if (showIds.contains(showSort.getPerformancesId())) {
            showIds.remove(showSort.getPerformancesId());
            showIds.add(0, showSort.getPerformancesId());
            smileRedisUtils.setShowIds(showIds);

            return AjaxResult.success();
        } else {
            return AjaxResult.warn("清先为演出设置票提！");
        }
    }

    @Override
    public AjaxResult price(SmilePriceParam smilePriceParam) {
        //查询演出状态
        AjaxResult showStatue = showStatue(smilePriceParam);
        if (showStatue != null) {
            return showStatue;
        }
        //用户是否打款
        Integer status = smileRedisUtils.getShowPriceUid(smilePriceParam.getPerformancesId(), smilePriceParam.getUid());
        if (status != null) {
            return AjaxResult.warn("不可重复打款");
        } else {
            //判断演出是否有用户打过款
            Integer showPriceId = smileRedisUtils.getShowPriceId(smilePriceParam.getPerformancesId());
            if (showPriceId == null) {
                //演出数据保存
                //1.1.记录该演出打款数据
                ShowVo showVoByPerId = smileRedisUtils.getShowVoByPerId(smilePriceParam.getPerformancesId());
                if (showVoByPerId != null) {
                    SmilePrice smilePriceByPerId = new SmilePrice();
                    smilePriceByPerId.setPerformancesId(smilePriceParam.getPerformancesId());
                    String showVoByPerIdJson = JSON.toJSONString(showVoByPerId);
                    smilePriceByPerId.setPrice(showVoByPerId.getTotalSalePrice());
                    smilePriceByPerId.setRecord(showVoByPerIdJson);
                    smilePriceMapper.insert(smilePriceByPerId);
                    //1.2.保存演出打款标识
                    smileRedisUtils.setShowPriceId(smilePriceParam.getPerformancesId());
                } else {
                    return AjaxResult.error("请刷新页面重试！");
                }
                //个人打款数据记录保存
                //2.1.获取演出代理全部uid
                List<SmileUser> smileUsers = smileUserMapper.selectUidByPerIdNotType(smilePriceParam.getPerformancesId());
                //遍历smile获取列表数据保存入打款表中
                for (SmileUser smileUser : smileUsers) {
                    //获取缓存单个用户代理记录
                    UserData userDataByUid = smileRedisUtils.getUserDataByUid(smilePriceParam.getPerformancesId(), smileUser.getUid());
                    if (userDataByUid != null) {
                        SmilePrice smilePriceByUidAndPerId = SmilePrice.getNew();
                        BigDecimal price = new BigDecimal("0");
                        List<UserDataAgentVo> dataAgentVos = userDataByUid.getDataAgentVos();
                        for (UserDataAgentVo userDataAgentVo : dataAgentVos) {
                            price = price.add(userDataAgentVo.getCommission());
                        }
                        smilePriceByUidAndPerId.setPerformancesId(smilePriceParam.getPerformancesId());
                        smilePriceByUidAndPerId.setUid(smileUser.getUid());
                        smilePriceByUidAndPerId.setPrice(price);
                        smilePriceByUidAndPerId.setCreatedDate(LocalDateTime.now());

                        String userDataJson = JSON.toJSONString(userDataByUid);
                        //保存打款金额
                        smilePriceByUidAndPerId.setRecord(userDataJson);
                        smilePriceByUidAndPerId.setStatus(0);
                        smilePriceMapper.insert(smilePriceByUidAndPerId);
                    }
                }
            }
            //打过款   表中已有数据直接修改打款记录即可
            LambdaQueryWrapper<SmilePrice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(SmilePrice::getUid, smilePriceParam.getUid());
            lambdaQueryWrapper.eq(SmilePrice::getPerformancesId, smilePriceParam.getPerformancesId());
            SmilePrice smilePriceUpdate = SmilePrice.getNew();
            smilePriceUpdate.setStatus(1);
            smilePriceUpdate.setUpdatedDate(LocalDateTime.now());
            smilePriceMapper.update(smilePriceUpdate, lambdaQueryWrapper);
            SmilePrice smilePrice = smilePriceMapper.selectOne(lambdaQueryWrapper);
            //该用户该演出标记打款
            smileRedisUtils.setPriceByUid(smilePriceParam.getPerformancesId(), smilePriceParam.getUid());
            //计算总营收
            BigDecimal userTotalPrice = smileRedisUtils.getUserTotalPrice(smilePriceParam.getUid());
            smileRedisUtils.setUserTotalPrice(smilePriceParam.getUid(), smilePrice.getPrice().add(userTotalPrice));
        }
        return AjaxResult.success();
    }

    private AjaxResult showStatue(SmilePriceParam smilePriceParam) {
        LambdaQueryWrapper<KylinPerformances> queryWrapper = Wrappers.lambdaQuery(KylinPerformances.class);
        queryWrapper.eq(KylinPerformances::getPerformancesId, smilePriceParam.getPerformancesId());
        LocalDateTime timeEnd = kylinPerformancesMapper.selectOne(queryWrapper).getTimeEnd();
        if (timeEnd.isAfter(LocalDateTime.now())) {
            return AjaxResult.warn("演出尚未结束不能进行打款");
        }
        return null;
    }

    @Override
    public AjaxResult getShowById(String performancesId) {
        if (!StringUtils.isEmpty(performancesId)) {
            ShowVoById showVoById = new ShowVoById();
            //根据演出ID查询演出数据演出数据
            KylinPerformanceVo kylinPerformanceVo = mongoTemplate.findOne(Query.query(Criteria.where("performancesId").is(performancesId)), KylinPerformanceVo.class, KylinPerformanceVo.class.getSimpleName());
            if (kylinPerformanceVo == null) {
                return AjaxResult.warn("演出未找到");
            }
            //票提集合  根据演出id查询票提id
            List<ShowAgentVo> showAgentVoList = new ArrayList<>();
            List<ShowTicketVo> showTicketVoList = new ArrayList<>();
            List<SmileAgent> smileAgents = getSmileAgentsByProId(performancesId);
            if (smileAgents == null) {
                return AjaxResult.warn("该演出未开启代理票种");
            }
            Map<String, SmileAgent> map = getSmileAgentMap(smileAgents);

            //代理票的id
            List<String> ticketsIdList = smileAgents.stream().map(SmileAgent::getTicketId).collect(Collectors.toList());

            if (ticketsIdList.size() > 0) {
                ShowTicketVo totalShowTicketVo = new ShowTicketVo();
                totalShowTicketVo.setTitle("合计");
                totalShowTicketVo.setAgentSaleNum(BigDecimal.ZERO);
                totalShowTicketVo.setTotalPrice(BigDecimal.ZERO);
                //根据票提IDs查询票信息
                List<TicketAndStatusDao> ticketAndStatusDaoList = kylinTicketsMapper.selectTicketsByIds(ticketsIdList);
                if (ticketAndStatusDaoList != null && ticketAndStatusDaoList.size() > 0) {
                    for (TicketAndStatusDao ticketAndStatusDao : ticketAndStatusDaoList) {
                        SmileAgent smileAgent = map.get(ticketAndStatusDao.getTicketsId());

                        ShowAgentVo showAgentVo = getShowAgentVo(performancesId, ticketAndStatusDao, smileAgent);

                        ShowTicketVo showTicketVo = new ShowTicketVo();
                        showTicketVo.setTitle(ticketAndStatusDao.getTitle());
                        //单价
                        showTicketVo.setPrice(ticketAndStatusDao.getPrice());
                        showTicketVo.setType(ticketAndStatusDao.getType() == 1 ? "单日票" : "通票");
                        showTicketVo.setUseEnd(ticketAndStatusDao.getUseEnd());
                        showTicketVo.setUseStart(ticketAndStatusDao.getUseStart());
                        showTicketVo.setTotalGeneral(ticketAndStatusDao.getTotalGeneral());

                        //根据演出id和票提id查询出一共卖出票的数量
                        Map numAndPrice = kylinOrderTicketsMapper.selectNumAndPrice(performancesId, ticketAndStatusDao.getTicketsId());
                        //销售总数
                        showTicketVo.setAgentSaleNum(numAndPrice != null ? (BigDecimal) numAndPrice.get("agentSaleNum") : BigDecimal.valueOf(0));
                        //销售金额
                        showTicketVo.setTotalPrice(numAndPrice != null ? (BigDecimal) numAndPrice.get("totalPrice") : BigDecimal.valueOf(0));

                        showAgentVoList.add(showAgentVo);
                        showTicketVoList.add(showTicketVo);

                        totalShowTicketVo.setTotalPrice(totalShowTicketVo.getTotalPrice().add(showTicketVo.getTotalPrice()));
                        totalShowTicketVo.setAgentSaleNum(totalShowTicketVo.getAgentSaleNum().add(showTicketVo.getAgentSaleNum()));
                    }
                    showTicketVoList.add(totalShowTicketVo);
                } else {
                    return AjaxResult.warn("查询票提信息失败");
                }
            }

            getShowVo(showVoById, kylinPerformanceVo, showAgentVoList, showTicketVoList);

            return AjaxResult.success(showVoById);
        }
        return AjaxResult.warn("请重试");
    }

    private void getShowVo(ShowVoById showVoById, KylinPerformanceVo kylinPerformanceVo, List<ShowAgentVo> showAgentVoList, List<ShowTicketVo> showTicketVoList) {
        showVoById.setPerformancesId(kylinPerformanceVo.getPerformancesId());
        showVoById.setImgPoster(kylinPerformanceVo.getImgPoster());
        showVoById.setTitle(kylinPerformanceVo.getTitle());
        showVoById.setTimeStart(kylinPerformanceVo.getTimeStart());
        showVoById.setTimeEnd(kylinPerformanceVo.getTimeEnd());
        showVoById.setCityId(kylinPerformanceVo.getCityId());
        showVoById.setCityName(kylinPerformanceVo.getCityName());
        showVoById.setFieldId(kylinPerformanceVo.getFieldId());
        showVoById.setFieldName(kylinPerformanceVo.getFieldName());
        showVoById.setShowAgentVoList(showAgentVoList);
        showVoById.setShowTicketVoList(showTicketVoList);
        showVoById.setDetails(kylinPerformanceVo.getDetails());
    }

    @Override
    public SaleDataVo saleData(String performancesId) {
        SaleDataVo saleDataVo = new SaleDataVo();
        //演出id
        saleDataVo.setPerformancesId(performancesId);
        //设置演出状态
        saleDataVo.setPriceStatus(smileRedisUtils.getShowPriceId(performancesId));
        List<SmileAgent> smileAgents = getSmileAgentsByProId(performancesId);
        if (smileAgents == null) {
            return null;
        }
        //演出名称
        LambdaQueryWrapper<KylinPerformances> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(KylinPerformances::getPerformancesId, performancesId);
        KylinPerformances kylinPerformances = kylinPerformancesMapper.selectOne(queryWrapper);
        if (kylinPerformances == null) {
            return null;
        }
        saleDataVo.setTitle(kylinPerformances.getTitle());
        //map 票提id，票提信息
        Map<String, SmileAgent> tidMap = getSmileAgentMap(smileAgents);

        List<String> ticketsIdList = smileAgents.stream().map(SmileAgent::getTicketId).collect(Collectors.toList());

        List<ShowAgentVo> showAgentVoList = new ArrayList<>();
        //根据票提IDs查询票信息
        List<TicketAndStatusDao> ticketAndStatusDaoList = kylinTicketsMapper.selectTicketsByIds(ticketsIdList);
        for (TicketAndStatusDao ticketAndStatusDao : ticketAndStatusDaoList) {
            SmileAgent smileAgent = tidMap.get(ticketAndStatusDao.getTicketsId());
            ShowAgentVo showAgentVo = getShowAgentVo(performancesId, ticketAndStatusDao, smileAgent);
            showAgentVoList.add(showAgentVo);
        }

        List<String> ids = ObjectUtil.cloneLinkedListStr();
        //创建list长度定位分组数量
        List<UserData> userDataList = new ArrayList<>();
        //已打款跳出循环,去打款表中获取打款记录
        LambdaQueryWrapper<SmilePrice> lambdaQueryWrapper = Wrappers.lambdaQuery(SmilePrice.class);
        lambdaQueryWrapper.eq(SmilePrice::getPerformancesId, performancesId);
        lambdaQueryWrapper.isNotNull(SmilePrice::getUid);
        lambdaQueryWrapper.eq(SmilePrice::getDelTag, 0);
        List<SmilePrice> smilePrices = smilePriceMapper.selectList(lambdaQueryWrapper);
        for (SmilePrice smilePrice : smilePrices) {
            if (smilePrice.getRecord() != null && !smilePrice.getRecord().equals("")) {
                UserData userData = JSON.parseObject(smilePrice.getRecord(), UserData.class);
                //保存打款标识
                userData.setPriceStatus(smileRedisUtils.getShowPriceUid(performancesId, userData.getUid()));
                userDataList.add(userData);
                ids.add(userData.getUid());
            }
        }

        //判断该演出是否有打款
        Integer showPriceId = smileRedisUtils.getShowPriceId(performancesId);

        if (showPriceId == null) {
            //根据演出id查询出所有代理人的销售
            List<ShowBaseVoDto> showBaseVoList = smileAgentMapper.selectMapByPerId(performancesId);
            //根据代理id进行分组
            Map<String, List<ShowBaseVoDto>> stringListMap = showBaseVoList.stream().collect(Collectors.groupingBy(ShowBaseVoDto::getAgentId));
            //所有提成佣金
            List<Map<String, Object>> agentIdCommissionList = smileAgentMapper.getUserOrgByPerIdAndUidAndAgentMaster(performancesId);
            Map<String, BigDecimal> agentIdMasterMap = new HashMap<>();
            agentIdCommissionList.forEach(map -> {
                agentIdMasterMap.put((String) map.get("uid"), (BigDecimal) map.get("totalPrice"));
            });
            //遍历分组
            for (Map.Entry<String, List<ShowBaseVoDto>> showMap : stringListMap.entrySet()) {
                UserData userData = UserData.getNew();
                List<ShowBaseVoDto> showBaseVoDtoList = showMap.getValue();
                List<UserDataAgentVo> userDataAgentVos = new ArrayList<>();
                //当前list不为null，遍历有数据，方便后期判断是否总代取uid
                ShowBaseVoDto baseVoDto = showBaseVoDtoList.get(0);
                //根据票提id分组 list数量小于等于票提数量
                Map<String, List<ShowBaseVoDto>> tidMapByUid = showBaseVoDtoList.stream().collect(Collectors.groupingBy(ShowBaseVoDto::getTid));

                //总佣金
                BigDecimal totalCommission = BigDecimal.ZERO;

                //对票提进行遍历（总代没有售出而普代有售出）
                for (TicketAndStatusDao smileAgent : ticketAndStatusDaoList) {
                    //为没个uid的没个票提id 塞数据
                    UserDataAgentVo userDataAgentVo = UserDataAgentVo.getNew();
                    //有且只有一条
                    List<ShowBaseVoDto> showBaseVoDtoS = tidMapByUid.get(smileAgent.getTicketsId());
                    //判断用户是否卖出该票提
                    if (showBaseVoDtoS != null && showBaseVoDtoS.size() > 0) {
                        ShowBaseVoDto showBaseVoDto = showBaseVoDtoS.get(0);
                        userDataAgentVo.setTicketsId(showBaseVoDto.getTid());
                        userDataAgentVo.setTicketName(smileAgent.getTitle());
                        userDataAgentVo.setNumber(showBaseVoDto.getNumber());
                        userDataAgentVo.setPrice(showBaseVoDto.getPrice().stripTrailingZeros());
                        userDataAgentVo.setPriceReal(showBaseVoDto.getPriceReal().stripTrailingZeros());
//                    userDataAgentVo.setAgent(showBaseVoDto.getUse());
                        userDataAgentVo.setCommission(showBaseVoDto.getTotalPrice().stripTrailingZeros());
                    } else {
                        //没有买过
                        userDataAgentVo.setTicketsId(smileAgent.getTicketsId());
                        userDataAgentVo.setTicketName(smileAgent.getTitle());
                        userDataAgentVo.setNumber(BigDecimal.ZERO);
                        userDataAgentVo.setPrice(BigDecimal.ZERO);
                        userDataAgentVo.setPriceReal(BigDecimal.ZERO);
//                    userDataAgentVo.setAgent(showBaseVoDto.getType() == 1 ? tidMap.get(smileAgent.getTicketsId()).getTotalCarry() : tidMap.get(smileAgent.getTicketsId()).getOrdCarry());
                        userDataAgentVo.setCommission(BigDecimal.ZERO);
                    }
                    totalCommission = totalCommission.add(userDataAgentVo.getCommission());
                    userDataAgentVos.add(userDataAgentVo);
                }
                //判断是否为总代
                if (baseVoDto.getType() == 5) {
                    //不是特邀代理 //在原有的数据上新增加该用户下所有普代的提成
                    if (agentIdMasterMap.get(baseVoDto.getAgentId()) != null) {
                        userData.setTotalCommission(totalCommission.add(agentIdMasterMap.get(baseVoDto.getAgentId())).stripTrailingZeros());
                    }
                } else {
                    userData.setTotalCommission(totalCommission.stripTrailingZeros());
                }
                userData.setUid(showBaseVoDtoList.get(0).getAgentId());
                userData.setUsername(showBaseVoDtoList.get(0).getName());
                userData.setCityName(showBaseVoDtoList.get(0).getCity());
                userData.setType(showBaseVoDtoList.get(0).getType());
                userData.setPhone(showBaseVoList.get(0).getPhone());
                if (userData.getType() != 2) {
                    userData.setAgentName(showBaseVoDtoList.get(0).getName());
                } else {
                    userData.setAgentName(showBaseVoDtoList.get(0).getAgentName());
                }
                userData.setDataAgentVos(userDataAgentVos);
                //设置打款状态
                userData.setPriceStatus(smileRedisUtils.getShowPriceUid(performancesId, showBaseVoDtoList.get(0).getAgentId()));
                ids.add(userData.getUid());
                userDataList.add(userData);
                //缓存用户redis记录 计算
                smileRedisUtils.setUserDataByUid(userData, performancesId);
            }
            //查询这场演出所有总代理uid
            List<SmileUser> smileUsers = smileUserMapper.selectUidByPerId(performancesId);
            smileUsers.forEach(smileUser -> {
                if (!ids.contains(smileUser.getUid())) {
                    UserData userData = UserData.getNew();
                    List<UserDataAgentVo> userDataAgentVos = new ArrayList<>();
                    for (TicketAndStatusDao smileAgent : ticketAndStatusDaoList) {
                        UserDataAgentVo userDataAgentVo = UserDataAgentVo.getNew();
                        userDataAgentVo.setTicketsId(smileAgent.getTicketsId());
                        userDataAgentVo.setTicketName(smileAgent.getTitle());
                        userDataAgentVo.setNumber(BigDecimal.ZERO);
                        userDataAgentVo.setPrice(BigDecimal.ZERO);
                        userDataAgentVo.setPriceReal(BigDecimal.ZERO);
                        userDataAgentVo.setCommission(BigDecimal.ZERO);
                        userDataAgentVos.add(userDataAgentVo);
                    }
                    //不是特邀代理  //在原有的数据上新增加该用户下所有普代的提成
                    BigDecimal decimal = agentIdMasterMap.get(smileUser.getUid());
                    userData.setTotalCommission(decimal.stripTrailingZeros());
                    userData.setUid(smileUser.getUid());
                    userData.setUsername(smileUser.getName());
                    userData.setCityName(smileUser.getCity());
                    userData.setType(smileUser.getType());
                    userData.setPhone(smileUser.getPhone());
                    //判断用户是否为总代
                    if (userData.getType() == 1) {
                        userData.setAgentName(smileUser.getName());
                    } else {
                        if (!StringUtils.isEmpty(smileUser.getAgentId())) {
                            SmileUserVO smileUserVO = smileRedisUtils.getSmileUserVO(smileUser.getAgentId());
                            userData.setAgentName(smileUserVO.getName());
                        } else {
                            userData.setAgentName(null);
                        }
                    }
                    userData.setDataAgentVos(userDataAgentVos);
                    //设置打款状态
                    userData.setPriceStatus(smileRedisUtils.getShowPriceUid(performancesId, smileUser.getUid()));
                    //缓存用户redis记录 计算
                    smileRedisUtils.setUserDataByUid(userData, performancesId);
                    userDataList.add(userData);
                }
            });
        }
        saleDataVo.setUserDataList(userDataList);
        saleDataVo.setShowAgentVoList(showAgentVoList);
        return saleDataVo;
    }

    @Override
    public AjaxResult allPrice(SmilePriceParam smilePriceParam) {
        Integer showPriceId = smileRedisUtils.getShowPriceId(smilePriceParam.getPerformancesId());
        //查询演出状态
        AjaxResult showStatue = showStatue(smilePriceParam);
        if (showStatue != null) {
            return showStatue;
        }
        //判断打款标识
        if (smilePriceParam.getStatus().equals(showPriceId)) {
            return AjaxResult.warn("不可重复提交");
        }
        if (smilePriceParam.getStatus().equals(0)) {
            //打款
            smileRedisUtils.setShowPriceId(smilePriceParam.getPerformancesId());
        } else {
            //未打款
            smileRedisUtils.delShowPriceId(smilePriceParam.getPerformancesId());
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult updateRedis() {
        try {
            String perIds = (String) smileRedisUtils.get(SmileRedisConst.SMILE_SHOW);
            if (StringUtils.isNotBlank(perIds)) {
                List<String> list = new ArrayList<>(Arrays.asList(perIds.split(",")));
                smileRedisUtils.setShowIds(list);
            }
        } catch (Exception e) {
            log.error("updateRedis()");
        }
        ArrayList<String> showIds = (ArrayList<String>) smileRedisUtils.getShowIds().stream().distinct().collect(Collectors.toList());
        smileRedisUtils.setShowIds(showIds);
        return AjaxResult.success(showIds);
    }

    private Map<String, SmileAgent> getSmileAgentMap(List<SmileAgent> smileAgents) {
        Map<String, SmileAgent> map = new HashMap<>(smileAgents.size());
        smileAgents.forEach(smileAgent -> map.put(smileAgent.getTicketId(), smileAgent));
        return map;
    }

    private List<SmileAgent> getSmileAgentsByProId(String performancesId) {
        LambdaQueryWrapper<SmileAgent> queryWrapper = Wrappers.lambdaQuery(SmileAgent.class);
        queryWrapper.eq(SmileAgent::getPerformanceId, performancesId);
        queryWrapper.eq(SmileAgent::getDelTag, 0);
        return smileAgentMapper.selectList(queryWrapper);
    }

    private ShowAgentVo getShowAgentVo(String performancesId, TicketAndStatusDao ticketAndStatusDao, SmileAgent smileAgent) {
        ShowAgentVo showAgentVo = new ShowAgentVo();
        showAgentVo.setId(ticketAndStatusDao.getMid());
        showAgentVo.setPerformanceId(performancesId);
        showAgentVo.setTicketId(ticketAndStatusDao.getTicketsId());
        showAgentVo.setTitle(ticketAndStatusDao.getTitle());
        //开始结束时间转换年月日
        String start = ticketAndStatusDao.getUseStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String end = ticketAndStatusDao.getUseEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        if (start.equals(end)) {
            showAgentVo.setTitle(ticketAndStatusDao.getTitle().concat("(").concat(start).concat(")"));
        } else {
            showAgentVo.setTitle(ticketAndStatusDao.getTitle().concat("(").concat(start).concat("--").concat(end).concat(")"));
        }
        //总代票提
        showAgentVo.setTotalCarry(smileAgent.getTotalCarry().stripTrailingZeros());
        //普代票提
        showAgentVo.setOrdCarry(smileAgent.getOrdCarry().stripTrailingZeros());
        return showAgentVo;
    }

    @Override
    public void exportData(ServletOutputStream servletOutputStream, String performancesId) {
        ExcelWriter writer = EasyExcelFactory.write(servletOutputStream).build();
        // 动态添加表头，适用一些表头动态变化的场景
        SaleDataVo saleDataVo = saleData(performancesId);
        WriteSheet sheet1 = new WriteSheet();
        sheet1.setSheetName("演出id_".concat(performancesId).concat("演出数据"));
        sheet1.setSheetNo(0);

        List<UserData> userDataList = saleDataVo.getUserDataList();
        ArrayList<String> ticketList = Lists.newArrayList();
        List<ShowAgentVo> agentVoList = saleDataVo.getShowAgentVoList();
        agentVoList.forEach(showAgentVo -> ticketList.add(showAgentVo.getTitle()));
        // 创建一个表格，用于 Sheet 中使用
        WriteTable table = new WriteTable();
        table.setTableNo(1);
        table.setHead(head(ticketList));
        // 写数据
        if (userDataList != null) {
            writer.write(contentData(userDataList, agentVoList), sheet1, table);
        }
        writer.finish();
    }

    @Override
    public AjaxResult upTakeByPerId(String perId, Integer type) {
        //是否设置过票提
        LambdaQueryWrapper<SmileAgent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SmileAgent::getPerformanceId, perId);
        queryWrapper.eq(SmileAgent::getDelTag, 0);
        List<SmileAgent> smileAgents = smileAgentMapper.selectList(queryWrapper);
        boolean tag = true;
        for (SmileAgent smileAgent : smileAgents) {
            if (smileRedisUtils.getAgent(smileAgent.getPerformanceId(), smileAgent.getTicketId()) != null) {
                tag = false;
                break;
            }
        }
        if (tag) {
            return AjaxResult.warn("还未设置票提！");
        }

        List<String> showIds = smileRedisUtils.getShowIds();
        if (type.equals(1)) {
            showIds.remove(perId);
        } else {
            showIds.add(perId);
        }
        smileRedisUtils.setShowIds(showIds);
        smileAgentMapper.upTakeByPerId(perId, type);
        return AjaxResult.success();
    }

    @Override
    public ResponseDto<List<KylinPerformancesVo>> listAll() {
        //返回可代理的演出名称和id
        List<KylinPerformancesDto> kylinPerformancesDtoList =  kylinPerformancesMapper.getListAll();
        List<KylinPerformancesVo> kylinPerformancesVos = kylinPerformancesDtoList.stream().map(kylinPerformancesDto -> KylinPerformancesVo.getNew().copyListAll(kylinPerformancesDto)).collect(Collectors.toList());
        return ResponseDto.success(kylinPerformancesVos);
    }

    private List<List<String>> head(List<String> ticketList) {
        List<List<String>> headTitles = new ArrayList<>();
        String basicInfo = "代理数据";
        String ticket = "票数据";
        String saleData = "销售数据";
        headTitles.add(Lists.newArrayList(basicInfo, basicInfo, "uid"));
        headTitles.add(Lists.newArrayList(basicInfo, basicInfo, "姓名"));
        headTitles.add(Lists.newArrayList(basicInfo, basicInfo, "所属地区"));
        headTitles.add(Lists.newArrayList(basicInfo, basicInfo, "身份"));
        headTitles.add(Lists.newArrayList(basicInfo, basicInfo, "手机号"));
        headTitles.add(Lists.newArrayList(basicInfo, basicInfo, "总代姓名"));

        //做表
        ticketList.forEach(title -> headTitles.add(Lists.newArrayList(ticket, ticket, title)));
        ArrayList<String> dataList = Lists.newArrayList("总销售张数", "总销售金额", "总销售佣金", "打款状态");
        //做表
        dataList.forEach(dataStr -> headTitles.add(Lists.newArrayList(saleData, saleData, dataStr)));

        return headTitles;
    }

    private List<List<Object>> contentData(List<UserData> userDataList, List<ShowAgentVo> agentVoList) {
        List<List<Object>> contentList = Lists.newArrayList();
        //这里一个List<Object>才代表一行数据，需要映射成每行数据填充，横向填充（把实体数据的字段设置成一个List<Object>）
        userDataList.forEach(userData -> {
            //总销售张数
            BigDecimal num = new BigDecimal("0");
            //总销售金额
            BigDecimal price = new BigDecimal("0");

            ArrayList<Object> arrayList = Lists.newArrayList();
            arrayList.add(userData.getUid());
            arrayList.add(userData.getUsername());
            arrayList.add(userData.getCityName());
            Integer type = userData.getType();
            if (type == 1) {
                arrayList.add("总代");
            } else if (type == 2) {
                arrayList.add("普代");
            } else if (type == 5) {
                arrayList.add("特邀代理");
            } else {
                arrayList.add("未知");
            }
            arrayList.add(userData.getPhone());
            arrayList.add(userData.getAgentName());
            //便利票数据
            List<UserDataAgentVo> dataAgentVos = userData.getDataAgentVos();
            Map<String, UserDataAgentVo> agentVoMap = dataAgentVos.stream().collect(Collectors.toMap(UserDataAgentVo::getTicketsId, Function.identity()));
            //遍历agentVoList顺序塞值
            for (ShowAgentVo showAgentVo : agentVoList) {
                UserDataAgentVo userDataAgentVo = agentVoMap.get(showAgentVo.getTicketId());
                if (userDataAgentVo != null) {
                    num = num.add(new BigDecimal(userDataAgentVo.getNumber().toString()));
                    price = price.add(userDataAgentVo.getPriceReal());
                    arrayList.add(userDataAgentVo.getNumber());
                } else {
                    arrayList.add(0);
                }
            }
            arrayList.add(num);
            arrayList.add(price);
            arrayList.add(userData.getTotalCommission());
            arrayList.add(userData.getPriceStatus() != null && userData.getPriceStatus() == 0 ? "已打款" : "待打款");
            contentList.add(arrayList);
        });
        return contentList;
    }

}
