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.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.SellDataVO;
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;

    @Override
    public PageInfo<ShowVo> listShow(SmileShowParam smileShowParam) {
        PageInfo<ShowVo> pageInfo;
        //查询所有代理的演出id
        List<KylinPerformances> kylinPerformancesList = kylinPerformancesMapper.selectPerIdByAgent();
        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  查询所有订单
            List<KylinOrderTicketAndAgentVo> kylinOrderTicketsList = kylinOrderTicketsMapper.selectListByPerformanceId(kylinPerformances.getPerformancesId(), null);

            int open = 0;
            BigDecimal totalSalePrice = BigDecimal.valueOf(0);
            for (KylinOrderTicketAndAgentVo kylinOrderTicketAndAgentVo : kylinOrderTicketsList) {
                //演出张数
                int num = kylinOrderTicketAndAgentVo.getNumber() - kylinOrderTicketAndAgentVo.getRefundNumber();
                if (num > 0) {
                    open += num;
                    //实付价格-退款价格
                    totalSalePrice = totalSalePrice.add((kylinOrderTicketAndAgentVo.getPriceActual()).subtract(kylinOrderTicketAndAgentVo.getPriceRefund()));
                }
            }
            vo.setOpen(open);

            vo.setTotalSalePrice(totalSalePrice);

            //根据演出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());
        pageInfo = new PageInfo<>(showVoList);
        return pageInfo;
    }

    @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);
        Integer status = smileRedisUtils.getShowPriceUid(smilePriceParam.getPerformancesId(), smilePriceParam.getUid());
        if (smilePriceParam.getStatus().equals(status)) {
            return AjaxResult.warn("不可重复打款");
        }
        //查询该用户的佣金
        SellDataVO sellDataVO = smileRedisUtils.getSellDataVO(smilePriceParam.getUid(), smilePriceParam.getPerformancesId());
        smilePrice.setPrice(sellDataVO.getTotalCommission());
        if (smilePriceParam.getStatus().equals(0)){
            smilePrice.setCreatedDate(LocalDateTime.now());
            smilePriceMapper.insert(smilePrice);
            smileRedisUtils.setPriceByUid(smilePriceParam.getPerformancesId(), smilePriceParam.getUid());
        } else {
            //删除打款信息
            smileRedisUtils.delPriceByUid(smilePriceParam.getPerformancesId(), smilePriceParam.getUid());
            LambdaQueryWrapper<SmilePrice> queryWrapper = Wrappers.lambdaQuery(SmilePrice.class);
            queryWrapper.eq(SmilePrice::getPerformancesId, smilePriceParam.getPerformancesId());
            queryWrapper.eq(SmilePrice::getUid, smilePriceParam.getUid());
            smilePrice.setUpdatedDate(LocalDateTime.now());
            smilePrice.setDelTag(1);
            smilePriceMapper.update(smilePrice, queryWrapper);
        }
        return AjaxResult.success();
    }

    @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();
            //设置演出状态
            saleDataVo.setPriceStatus(smileRedisUtils.getShowPriceId(performancesId));
            List<SmileAgent> smileAgents = getSmileAgentsByProId(performancesId);
            if (smileAgents.size() == 0) {
                return AjaxResult.error("该演出未开启代理");
            }
            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(String performancesId) {
        //缓存redis
        smileRedisUtils.setShowPriceId(performancesId);
        return AjaxResult.success();
    }

    private UserData getUserData(String performancesId, SmileUser smileUser) {
        UserData userData = new UserData();
        SellDataVO sellDataVO = smileRedisUtils.getSellDataVO(smileUser.getUid(), performancesId);
        BeanUtils.copyProperties(sellDataVO, 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;
    }


}
