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.constant.SmileRedisConst;
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.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;

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

            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);
            //缓存redis
            smileRedisUtils.set(SmileRedisConst.SELL_SHOW_POEN.concat(kylinPerformances.getPerformancesId()), open);

            vo.setTotalSalePrice(totalSalePrice);
            //缓存redis
            smileRedisUtils.set(SmileRedisConst.SELL_SHOW_TOTAL_SALE_PRICE.concat(kylinPerformances.getPerformancesId()), totalSalePrice);

            //根据演出id查询销售代理
            vo.setTotalOutAgent(kylinOrderTicketRelationsMapper.concatByAgentDed(kylinPerformances.getPerformancesId()));
            //演出结束时间
            vo.setTimeEnd(kylinPerformances.getTimeEnd());

            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.selectByComment().stream().map(KylinPerformances::getPerformancesId).collect(Collectors.toList());
        String perId = StringUtils.strip(collect.toString(), "[]");
        smileRedisUtils.set(SmileRedisConst.SMILE_SHOW, perId);
        log.info("redis show key:{}", perId);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult price(SmilePriceParam smilePriceParam) {
        if (!smileRedisUtils.hasKey(SmileRedisConst.SELL_SHOW_PAYMENT.concat(smilePriceParam.getPerformancesId()))) {
            if(smileRedisUtils.set(SmileRedisConst.SELL_SHOW_PAYMENT.concat(smilePriceParam.getPerformancesId()), 1)){
                //TODO:持久化存儲操作
                SmilePrice smilePrice = new SmilePrice();
                BeanUtils.copyProperties(smilePriceParam, smilePrice);
                smilePrice.setCreatedAt(LocalDateTime.now());
                smilePriceMapper.insert(smilePrice);
            }
        } else {
            smileRedisUtils.del(SmileRedisConst.SELL_SHOW_PAYMENT.concat(smilePriceParam.getPerformancesId()));
            smilePriceMapper.deleteById(smilePriceParam.getId());
        }

        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;
            }
            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());
            //票提集合  根据演出id查询票提id
            List<ShowAgentVo> showAgentVoList = new ArrayList<>();
            List<ShowTicketVo> showTicketVoList = new ArrayList<>();
            List<SmileAgent> smileAgents = getSmileAgentsByProId(performancesId);
            Map<String, SmileAgent> map = getSmileAgentMap(smileAgents);
            List<String> ticketsIdList = smileAgents.stream().map(SmileAgent::getTicketId).collect(Collectors.toList());

            //根据票提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);
                //代理销售数量
                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()))
                                        .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);

            showVoById.setShowAgentVoList(showAgentVoList);
            showVoById.setShowTicketVoList(showTicketVoList);

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

    @Override
    public AjaxResult saleData(String performancesId) {

        if (!StringUtils.isEmpty(performancesId)){
            SaleDataVo saleDataVo = new SaleDataVo();

            List<SmileAgent> smileAgents = getSmileAgentsByProId(performancesId);
            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("请重试");
    }

    private UserData getUserData(String performancesId, SmileUser smileUser) {
        UserData userData = new UserData();
        SellDataVO sellDataVO = (SellDataVO) smileRedisUtils.get(SmileRedisConst.SELL_DATA.concat(smileUser.getUid()).concat(performancesId));
        BeanUtils.copyProperties(sellDataVO, userData);
        userData.setUid(smileUser.getUid());
        userData.setUsername(smileUser.getName());
        userData.setCityName(smileUser.getCity());
        userData.setType(smileUser.getType());
        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);
        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;
    }


}
