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


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
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.goblin.dto.vo.SmileSellDataVO;
import com.liquidnet.service.kylin.dao.KylinOrderTicketAndAgentVo;
import com.liquidnet.service.kylin.dao.TicketAndStatusDao;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.kylin.entity.KylinPerformanceStatus;
import com.liquidnet.service.kylin.entity.KylinPerformances;
import com.liquidnet.service.kylin.mapper.*;
import com.liquidnet.service.kylin.service.admin.IKylinPerformancesAdminService;
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.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.BeanUtils;
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 java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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
    KylinTicketStatusMapper ticketStatusMapper;

    @Autowired
    SmileRedisUtils smileRedisUtils;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    IKylinPerformancesAdminService kylinPerformancesService;

    @Autowired
    KylinPerformancesMapper kylinPerformancesMapper;

    @Autowired
    private KylinOrderTicketRelationsMapper kylinOrderTicketRelationsMapper;

    @Autowired
    KylinOrderTicketsMapper kylinOrderTicketsMapper;

    @Autowired
    SmileAgentMapper smileAgentMapper;

    @Autowired
    KylinTicketsMapper kylinTicketsMapper;

    @Autowired
    SmileUserMapper smileUserMapper;

    @Autowired
    SmilePriceMapper smilePriceMapper;

    @Autowired
    KylinPerformanceStatusMapper kylinPerformanceStatusMapper;

    @Autowired
    private KylinOrderTicketsMapper orderTicketsMapper;

    @Override
    public TableDataInfo listShow(SmileShowParam smileShowParam) {
        PageInfo<KylinPerformances> pageInfo;
        TableDataInfo rspData = new TableDataInfo();
        //查询所有代理的演出id
        List<KylinPerformances> kylinPerformancesList = kylinPerformancesMapper.selectPerIdByAgent();
        pageInfo = new PageInfo<>(kylinPerformancesList);
        List<ShowVo> showVoList = kylinPerformancesList.stream().map(kylinPerformances -> {
            ShowVo vo = new ShowVo();
            //演出id
            vo.setPerformancesId(kylinPerformances.getPerformancesId());
            //演出名称
            vo.setTitle(kylinPerformances.getTitle());
            //城市
            vo.setCityName(kylinPerformances.getCityName());
            //根据演出id  查询所有订单
            Map map = kylinOrderTicketsMapper.selectByPerformanceId(kylinPerformances.getPerformancesId());
            vo.setOpen(map != null ? (BigDecimal) (map.get("open")) : null);
            vo.setTotalSalePrice(map != null ? (BigDecimal) (map.get("price")) : null);
            //根据演出id查询销售代理
            List<Long> ordNum = kylinOrderTicketRelationsMapper.concatByAgentDed(kylinPerformances.getPerformancesId());
            vo.setTotalOutAgent(ordNum.stream().reduce(Long::sum).orElse(0L));
            //演出结束时间
            vo.setTimeEnd(kylinPerformances.getTimeEnd());
            //演出开始时间
            vo.setTimeStart(kylinPerformances.getTimeStart());

            //演出状态
            LambdaQueryWrapper<KylinPerformanceStatus> queryWrapper = Wrappers.lambdaQuery(KylinPerformanceStatus.class);
            queryWrapper.eq(KylinPerformanceStatus::getPerformanceId, kylinPerformances.getPerformancesId());
            vo.setShowStatus(kylinPerformanceStatusMapper.selectOne(queryWrapper).getStatus());

            //打款状态
            vo.setStatus(smileRedisUtils.getShowStatus(kylinPerformances.getPerformancesId()));

            //演出顺序
            vo.setComment(kylinPerformances.getComment());

            return vo;
        }).collect(Collectors.toList());
        rspData.setCode(0);
        rspData.setRows(showVoList);
        rspData.setTotal(pageInfo.getTotal());
        return rspData;
    }

    @Override
    public AjaxResult sort(ShowSort showSort) {
        //查询数据库是否又该顺序的演出
        kylinPerformancesMapper.updateComment(showSort.getSort());
        kylinPerformancesMapper.updateCommentByPer(showSort.getSort(), showSort.getPerformancesId());

        //获取排序演出id
        List<String> collect = kylinPerformancesMapper.selectPerIdByAgent().stream().map(KylinPerformances::getPerformancesId).collect(Collectors.toList());
        String perId = StringUtils.join(collect, ",");
        //保存所有演出id带顺序
        smileRedisUtils.setShowIds(perId);
        log.info("redis show key:{}", perId);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult price(SmilePriceParam smilePriceParam) {
        SmilePrice smilePrice = new SmilePrice();
        BeanUtils.copyProperties(smilePriceParam, smilePrice);
        //查询演出状态
        AjaxResult showStatue = showStatue(smilePriceParam);
        if (showStatue != null) {
            return showStatue;
        }
        Integer status = smileRedisUtils.getShowPriceUid(smilePriceParam.getPerformancesId(), smilePriceParam.getUid());
        if (smilePriceParam.getStatus().equals(status)) {
            return AjaxResult.warn("不可重复打款");
        }
        if (smilePriceParam.getStatus().equals(0)) {
            //计算该用户的佣金
            Map userPerformance = orderTicketsMapper.getUserPerformanceByUidAndProId(smilePriceParam.getUid(), smilePriceParam.getPerformancesId());
            BigDecimal price = userPerformance.get("commiss") == null ? new BigDecimal(0) : new BigDecimal(userPerformance.get("commiss").toString());
            smilePrice.setPrice(price);
            smilePrice.setCreatedDate(LocalDateTime.now());
            smilePriceMapper.insert(smilePrice);
            smileRedisUtils.setPriceByUid(smilePriceParam.getPerformancesId(), smilePriceParam.getUid());
            //计算总营收
            BigDecimal userTotalPrice = smileRedisUtils.getUserTotalPrice(smilePriceParam.getUid());
            smileRedisUtils.setUserTotalPrice(smilePriceParam.getUid(), price.add(userTotalPrice));
        }
        /*else {
            LambdaQueryWrapper<SmilePrice> queryWrapper = Wrappers.lambdaQuery(SmilePrice.class);
            queryWrapper.eq(SmilePrice::getPerformancesId, smilePriceParam.getPerformancesId());
            queryWrapper.eq(SmilePrice::getUid, smilePriceParam.getUid());
            queryWrapper.eq(SmilePrice::getDelTag,0);
            queryWrapper.eq(SmilePrice::getUpdatedDate,"");
            SmilePrice smilePrice1 = smilePriceMapper.selectOne(queryWrapper);
            BigDecimal userTotalPrice = smileRedisUtils.getUserTotalPrice(smilePriceParam.getUid());
            smileRedisUtils.setUserTotalPrice(smilePriceParam.getUid(),userTotalPrice.subtract(smilePrice1.getPrice()));
            //删除打款信息
            smileRedisUtils.delPriceByUid(smilePriceParam.getPerformancesId(), smilePriceParam.getUid());
            //更新打款表
            smilePrice.setUpdatedDate(LocalDateTime.now());
            smilePrice.setDelTag(1);
            smilePriceMapper.updateById(smilePrice);
        }*/
        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());
            try {
                assert kylinPerformanceVo != null;
            } catch (Exception e) {
                return null;
            }

            //票提集合  根据演出id查询票提id
            List<ShowAgentVo> showAgentVoList = new ArrayList<>();
            List<ShowTicketVo> showTicketVoList = new ArrayList<>();
            List<SmileAgent> smileAgents = getSmileAgentsByProId(performancesId);
            Map<String, SmileAgent> map = getSmileAgentMap(smileAgents);

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

            if (ticketsIdList.size() > 0) {
                //根据票提IDs查询票信息
                List<TicketAndStatusDao> ticketAndStatusDaoList = kylinTicketsMapper.selectTicketsByIds(ticketsIdList);

                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());
                    showTicketVo.setUseEnd(ticketAndStatusDao.getUseEnd());
                    showTicketVo.setUseStart(ticketAndStatusDao.getUseStart());
                    showTicketVo.setTotalGeneral(ticketAndStatusDao.getTotalGeneral());

                    //根据演出id查询处所有订单
                    List<KylinOrderTicketAndAgentVo> kylinOrderTicketsList = kylinOrderTicketsMapper.selectListByPerformanceId(performancesId, ticketAndStatusDao.getTicketsId());
                    //代理销售数量
                    int agentSaleNum = 0;
                    //总销售金额
                    BigDecimal totalPrice = BigDecimal.valueOf(0);
                    //总代票提
                    for (KylinOrderTicketAndAgentVo kylinOrderTicketAndAgentVo : kylinOrderTicketsList) {
                        int num = kylinOrderTicketAndAgentVo.getNumber() - kylinOrderTicketAndAgentVo.getRefundNumber();
                        if (num > 0) {
                            agentSaleNum += num;
                            //单价*(总代票提+抽成票提）*数量
                            totalPrice = totalPrice.add(
                                    (ticketAndStatusDao.getPrice().multiply(kylinOrderTicketAndAgentVo.getAgentDistributions().add(kylinOrderTicketAndAgentVo.getAgentDistributionsMaster())))
                                            .multiply(BigDecimal.valueOf(num)));
                        }
                    }

                    showTicketVo.setAgentSaleNum(agentSaleNum);
                    showTicketVo.setTotalPrice(totalPrice);

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

                }
            }
            /*ShowTicketVo showTicketVo = new ShowTicketVo();
            //代理销售总张数
            showTicketVo.setTitle("总计");
            //总
            showTicketVo.setAgentSaleNum((int) smileRedisUtils.get(SmileRedisConst.SELL_SHOW_POEN.concat(performancesId)));
            showTicketVo.setTotalPrice((BigDecimal) smileRedisUtils.get(SmileRedisConst.SELL_SHOW_TOTAL_SALE_PRICE.concat(performancesId)));

            showTicketVoList.add(showTicketVo);*/

            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);
    }

    @Override
    public AjaxResult saleData(String performancesId) {

        if (!StringUtils.isEmpty(performancesId)) {
            SaleDataVo saleDataVo = new SaleDataVo();
            //演出id
            saleDataVo.setPerformancesId(performancesId);
            //设置演出状态
            saleDataVo.setPriceStatus(smileRedisUtils.getShowPriceId(performancesId));
            List<SmileAgent> smileAgents = getSmileAgentsByProId(performancesId);
            if (smileAgents.size() == 0) {
                return AjaxResult.error("该演出未开启代理");
            }
            //演出名称
            KylinPerformanceVo kylinPerformanceVo = mongoTemplate.findOne(Query.query(Criteria.where("performancesId").is(performancesId)), KylinPerformanceVo.class, KylinPerformanceVo.class.getSimpleName());
            assert kylinPerformanceVo != null;
            saleDataVo.setTitle(kylinPerformanceVo.getTitle());
            Map<String, SmileAgent> map = 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 = map.get(ticketAndStatusDao.getTicketsId());
                ShowAgentVo showAgentVo = getShowAgentVo(performancesId, ticketAndStatusDao, smileAgent);
                showAgentVoList.add(showAgentVo);
            }
            //根据演出id查询出所有代理人的uid
            List<SmileUser> smileUsers = smileUserMapper.getAllUidByPerId(performancesId);
            List<UserData> userDataList = new ArrayList<>(smileUsers.size());
            for (SmileUser smileUser : smileUsers) {
                UserData userData = getUserData(performancesId, smileUser);
                userDataList.add(userData);
            }
            saleDataVo.setUserDataList(userDataList);
            saleDataVo.setShowAgentVoList(showAgentVoList);
            return AjaxResult.success(saleDataVo);
        }
        return AjaxResult.warn("请重试");
    }

    @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();
    }

    private UserData getUserData(String performancesId, SmileUser smileUser) {
        UserData userData = new UserData();
        //个人用户的演出数据详情
        //获取 该人 该演出 的所有订单
        SmileSellDataVO smileSellDataVO = smileRedisUtils.getSellDataVO(smileUser.getUid(), performancesId);
        BeanUtils.copyProperties(smileSellDataVO, userData);
        userData.setUid(smileUser.getUid());
        userData.setUsername(smileUser.getName());
        userData.setCityName(smileUser.getCity());
        userData.setType(smileUser.getType());
        //设置打款状态
        userData.setPriceStatus(smileRedisUtils.getShowPriceUid(performancesId, smileUser.getUid()));
        return userData;
    }

    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());
        //总代票提
        showAgentVo.setTotalCarry(smileAgent.getTotalCarry());
        //普代票提
        showAgentVo.setOrdCarry(smileAgent.getOrdCarry());
        return showAgentVo;
    }


}
