package com.yc.ship.module.trade.service.pda;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yc.ship.framework.common.pojo.CommonResult;
import com.yc.ship.framework.common.pojo.PageResult;
import com.yc.ship.framework.common.util.object.BeanUtils;
import com.yc.ship.framework.tenant.core.aop.TenantIgnore;
import com.yc.ship.framework.tenant.core.context.TenantContextHolder;
import com.yc.ship.module.product.api.ProductApi;
import com.yc.ship.module.product.api.dto.ProductBaseRespDTO;
import com.yc.ship.module.product.api.dto.ProductCheckChannelRespDTO;
import com.yc.ship.module.product.service.productSpu.ProductSpuService;
import com.yc.ship.module.resource.dal.dataobject.checkchannel.CheckChannelDO;
import com.yc.ship.module.resource.service.channel.ScenicChannelService;
import com.yc.ship.module.resource.service.checkchannel.CheckChannelService;
import com.yc.ship.module.resource.service.machine.ScenicMachineService;
import com.yc.ship.module.resource.service.site.ScenicSiteService;
import com.yc.ship.module.system.api.dict.DictDataApi;
import com.yc.ship.module.system.api.dict.dto.DictDataRespDTO;
import com.yc.ship.module.trade.controller.admin.order.vo.check.CheckOrderPageVO;
import com.yc.ship.module.trade.controller.admin.order.vo.order.*;
import com.yc.ship.module.trade.controller.app.pda.vo.PdaQueryOrderReqVO;
import com.yc.ship.module.trade.controller.app.pda.vo.PdaQueryVoucherReqVO;
import com.yc.ship.module.trade.dal.dataobject.order.TradeVisitorDO;
import com.yc.ship.module.trade.dal.mysql.order.TradeDetailMapper;
import com.yc.ship.module.trade.enums.VoucherStatusEnum;
import com.yc.ship.module.trade.framework.common.IPUtils;
import com.yc.ship.module.trade.service.order.TradeCheckService;
import com.yc.ship.module.trade.service.order.TradeOrderRepositoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

import static com.yc.ship.module.trade.enums.ErrorCodeConstants.INVALID_DEVICE;


/**
 * &#064;Description Pda service实现
 */
@Service
@Slf4j
public class PdaServiceImpl implements PdaService {

    @Resource
    private ScenicMachineService scenicMachineService;
    @Resource
    private ScenicSiteService scenicSiteService;
    @Resource
    private CheckChannelService checkChannelService;
    @Resource
    private ScenicChannelService scenicChannelService;
    @Resource
    private DictDataApi dictDataApi;
    @Resource
    private ProductApi productApi;
    @Resource
    private ProductSpuService productSpuService;
    @Resource
    private TradeOrderRepositoryService tradeOrderRepositoryService;
    @Resource
    private TradeCheckService tradeCheckService;
    @Resource
    private TradeDetailMapper tradeDetailMapper;


    @Override
    public CommonResult<?> getSiteChannel(HttpServletRequest request) {
        return CommonResult.success(scenicChannelService.getCheckChannelList());
    }

    @Override
    @TenantIgnore
    public CommonResult<?> queryVoucher(PdaQueryVoucherReqVO reqVO) {
        String machineId = IPUtils.getIpAddr();
        Map machineMap = scenicMachineService.getMachineInfo(1, machineId);
        if (machineMap==null) {
            return CommonResult.error(INVALID_DEVICE);
        }
        Long channelId = MapUtil.getLong(machineMap, "channelId");
        reqVO.setChannelId(channelId);
        List<TradeDetailRespVO> detailList;
        if(StringUtils.isNotBlank(reqVO.getVoucherCode())){
            if(reqVO.getVoucherCode().length()==18){
                detailList = tradeOrderRepositoryService.getTradeDetailWithBaseByCodeAndIdcard(reqVO);
            }else {
                TenantContextHolder.setIgnore(true);
                detailList = tradeDetailMapper.getPlatByVoucherCode1(reqVO.getVoucherCode());
                if(detailList==null){
                    detailList = tradeDetailMapper.getPlatByVoucherCode2(reqVO.getVoucherCode());
                }
                TenantContextHolder.setIgnore(false);
            }
        }else {
            detailList = tradeOrderRepositoryService.getTradeDetailWithBaseByCodeAndIdcard(reqVO);
        }
        this.bulidCanCheckDetail(detailList, channelId);
        return CommonResult.success(detailList);
    }


    @Override
    public CommonResult<?> queryOrder(PdaQueryOrderReqVO reqVO) {
        String machineId = IPUtils.getIpAddr();
        Map<String, Object> machineMap = scenicMachineService.getMachineInfo(1, machineId);
        if (machineMap==null) {
            return CommonResult.error(INVALID_DEVICE);
        }
        Long channelId = MapUtil.getLong(machineMap, "channelId");
        TenantContextHolder.setIgnore(true);
        if(StringUtils.isNotBlank(reqVO.getOrderNo())) {
            //转换为平台订单
            String orderNo = tradeOrderRepositoryService.getPlatOrderNo(reqVO.getOrderNo());
            if(StringUtils.isNotBlank(orderNo)) {
                reqVO.setOrderNo(orderNo);
            }
        }
        reqVO.setChannelId(channelId);
        List<TradeOrderPdaRespVO> orderList = tradeOrderRepositoryService.getOrderAndDetail(reqVO);
        orderList.forEach(orderRespVO -> {

            Integer thisSiteCanCheckNum = 0;
            List<TradeDetailRespVO> list = orderRespVO.getTradeDetailList();
            orderRespVO.setNum(list.size());
            orderRespVO.setThisSiteCanCheckNum(thisSiteCanCheckNum);
//            orderRespVO.setTradeDetailList(null);
        });
        TenantContextHolder.setIgnore(false);
        return CommonResult.success(orderList);
    }

    @Override
    public CommonResult<?> queryOrderWithoutSiteNum(CheckOrderPageVO reqVO) {
        IPage<TradeOrderRespVO> page = tradeOrderRepositoryService.getCheckOrder(reqVO);

        List<DictDataRespDTO> dictList = dictDataApi.getDictDataList("project_specification_type");
        page.getRecords().forEach(vo -> {
            //获取订单门票信息
            vo.setTradeDetailList(tradeDetailMapper.getOrderIdDetail(vo.getId()));
            // 统计各规格数量
            List<TradeDetailRespVO> list = vo.getTradeDetailList();
            StringJoiner joiner = new StringJoiner("、");
            List<Integer> statusList = Arrays.asList(1,2,3,4,6,8,9);
            for (DictDataRespDTO dict : dictList) {
                long count = list.stream().filter(item -> dict.getValue().equals(item.getSpecType()) && (statusList.contains(item.getVoucherStatus()))).count();
                if (count > 0) {
                    joiner.add(dict.getLabel() + "*" + count);
                }
            }
            vo.setSpecNumber(joiner.toString());
            vo.setNum(list.size());
        });
        return CommonResult.success(new PageResult<>(page.getRecords(), page.getTotal()));
    }

    @Override
    public CommonResult<?> queryOrderGuideWithoutSiteNum(CheckOrderPageVO reqVO) {
        IPage<TradeOrderRespVO> page = tradeOrderRepositoryService.getCheckOrder(reqVO);

        List<DictDataRespDTO> dictList = dictDataApi.getDictDataList("project_specification_type");
        page.getRecords().forEach(vo -> {
            //获取订单门票信息
            vo.setTradeDetailList(tradeDetailMapper.getOrderIdDetail(vo.getId()));
            // 统计各规格数量
            List<TradeDetailRespVO> list = vo.getTradeDetailList();
            StringJoiner joiner = new StringJoiner("、");
            List<Integer> statusList = Arrays.asList(1,2,3,4,6,8,9);
            for (DictDataRespDTO dict : dictList) {
                long count = list.stream().filter(item -> dict.getValue().equals(item.getSpecType()) && (statusList.contains(item.getVoucherStatus()))).count();
                if (count > 0) {
                    joiner.add(dict.getLabel() + "*" + count);
                }
            }
            vo.setSpecNumber(joiner.toString());
            vo.setNum(list.size());
        });
        return CommonResult.success(new PageResult<>(page.getRecords(), page.getTotal()));
    }

    @Override
    public CommonResult<?> queryVoucherWithoutSiteNum(CheckOrderPageVO reqVO) {
        IPage<TradeOrderRespVO> page = tradeOrderRepositoryService.getCheckOrder(reqVO);
        List<TradeDetailExtRespVO> result = new ArrayList<>();
        page.getRecords().forEach(vo -> {
            List<TradeDetailRespVO> detailList = tradeDetailMapper.getOrderIdDetail(vo.getId());
            vo.setTradeDetailList(detailList);
            for (TradeDetailRespVO tradeDetail : detailList) {
                // 过滤 证件号
                if (!Objects.isNull(reqVO.getCredentialNo())) {
                    for (TradeVisitorDO visitor : tradeDetail.getVisitors()) {
                        if (reqVO.getCredentialNo().equals(visitor.getCredentialNo())) {
                            result.add(addVoucher(tradeDetail, vo));
                            break;
                        }
                    }
                } else if (!Objects.isNull(reqVO.getVoucherCode()) && StrUtil.equals(reqVO.getVoucherCode(), tradeDetail.getVoucherCode())) {
                    result.add(addVoucher(tradeDetail, vo));
                } else {
                    result.add(addVoucher(tradeDetail, vo));
                }
            }
        });
        return CommonResult.success(result);
    }

    private TradeDetailExtRespVO addVoucher(TradeDetailRespVO detail, TradeOrderRespVO order) {
        List<DictDataRespDTO> orderStatusDict = dictDataApi.getDictDataList("trade_order_status");
        List<DictDataRespDTO> voucherStatusDict = dictDataApi.getDictDataList("voucher_status");
        List<DictDataRespDTO> specDict = dictDataApi.getDictDataList("project_specification_type");
        TradeDetailExtRespVO extModel = BeanUtils.toBean(detail, TradeDetailExtRespVO.class);
        extModel.setOrderNo(order.getOrderNo());
        extModel.setIsAddOrder(order.getIsAddOrder());
        extModel.setOrderStatus(order.getOrderStatus());
        extModel.setMobile(order.getMobile());
        extModel.setContactName(order.getContactName());
        extModel.setAmount(order.getAmount());
        extModel.setPayAmount(order.getPayAmount());
        extModel.setSourceName(order.getSourceName());
        Optional<DictDataRespDTO> first = orderStatusDict.stream().filter(d -> Objects.equals(d.getValue(),extModel.getOrderStatus()+"")).findFirst();
        first.ifPresent(d -> extModel.setOrderStatusName(d.getLabel()));
        first = voucherStatusDict.stream().filter(d -> Objects.equals(d.getValue(),extModel.getVoucherStatus()+"")).findFirst();
        first.ifPresent(d -> extModel.setVoucherStatusName(d.getLabel()));
        first = specDict.stream().filter(d -> Objects.equals(d.getValue(),extModel.getSpecType())).findFirst();
        first.ifPresent(d -> extModel.setSpecTypeName(d.getLabel()));
        return extModel;
    }

    private void bulidCanCheckDetail(List<TradeDetailRespVO> detailList, Long channelId) {
    }

    private void bulidDetailVisitor(List<TradeDetailRespVO> detailList) {
        detailList.forEach(tradeDetail -> {
            List<TradeVisitorDO> visitorList = tradeOrderRepositoryService.queryVisitorByDetailId(tradeDetail.getId());
            tradeDetail.setVisitors(visitorList);
        });
    }
}
