package cn.freemud.adapter;

import cn.freemud.base.util.DateUtil;
import cn.freemud.entities.dto.QueryOrdersResponseDto;
import cn.freemud.entities.vo.CreateDeliveryPreferentialVo;
import cn.freemud.entities.vo.CreateDeliveryVo;
import cn.freemud.entities.vo.ProductInfo;
import cn.freemud.entities.vo.ProductVo;
import cn.freemud.enums.DeliveryChannelEnum;
import cn.freemud.enums.OrderSourceType;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.deliverycenter.dto.CreateDeliveryOrderRequestDto;
import com.freemud.application.sdk.api.ordercenter.request.OrderExtInfoDto;
import com.freemud.application.sdk.api.storecenter.response.StoreResponse;
import com.freemud.sdk.api.assortment.order.enums.OldOrderAccountType;
import com.freemud.sdk.api.assortment.order.request.order.OrderProductAddInfoDto;
import com.freemud.sdk.api.assortment.order.request.order.OrderSpecialExtraAttrRequest;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

@Component
public class DeliveryAdapter {




    public CreateDeliveryOrderRequestDto convertToWeixinDeliveryOrderRequestDto(QueryOrdersResponseDto.DataBean.OrderBean orderBean, StoreResponse storeInfo, String accessToken, String deliveryCallBackUrl) {
        CreateDeliveryOrderRequestDto deliveryOrderRequestDto = new CreateDeliveryOrderRequestDto();

        OrderExtInfoDto orderExtInfoDto = JSONObject.parseObject(orderBean.getExtInfo(), OrderExtInfoDto.class) == null ? new OrderExtInfoDto() : JSONObject.parseObject(orderBean.getExtInfo(), OrderExtInfoDto.class);

        deliveryOrderRequestDto.setDeliveryChannel(DeliveryChannelEnum.WEIXIN.getCode());
        deliveryOrderRequestDto.setAccessToken(accessToken);
        deliveryOrderRequestDto.setOpenId(orderExtInfoDto.getOpenid());
        deliveryOrderRequestDto.setWxAppId(orderExtInfoDto.getAppid());
        BigDecimal weight = (orderBean.getWeight() == null || new BigDecimal("0").compareTo(orderBean.getWeight()) == 0) ? new BigDecimal("1") : orderBean.getWeight();
        deliveryOrderRequestDto.setDepatchWeight(weight.divide(new BigDecimal("1000"))); //克转化为千克
        deliveryOrderRequestDto.setSerialNumber(orderBean.getDaySeq().toString());
        deliveryOrderRequestDto.setOrderId(orderBean.getOid());
        deliveryOrderRequestDto.setOrderRemark(orderBean.getRemark());
        deliveryOrderRequestDto.setOrderTotalAmount(orderBean.getAmount().intValue() == 0 ? 1 : orderBean.getAmount().intValue());
        deliveryOrderRequestDto.setOrderActualAmount(orderBean.getAmount().intValue() == 0 ? 1 : orderBean.getAmount().intValue());
        deliveryOrderRequestDto.setPartnerId(orderBean.getCompanyId());
        deliveryOrderRequestDto.setOrderChannel(orderBean.getSource());
        deliveryOrderRequestDto.setIsPre(0);
        deliveryOrderRequestDto.setStoreId(storeInfo.getBizVO().getStoreId());
        deliveryOrderRequestDto.setStoreCode(storeInfo.getBizVO().getStoreCode());
        deliveryOrderRequestDto.setStoreAddress(storeInfo.getBizVO().getAddress());
        deliveryOrderRequestDto.setStoreLng(new BigDecimal(storeInfo.getBizVO().getLongitude()));
        deliveryOrderRequestDto.setStoreLat(new BigDecimal(storeInfo.getBizVO().getLatitude()));
        deliveryOrderRequestDto.setStorePhone(storeInfo.getBizVO().getPhone());
        deliveryOrderRequestDto.setStoreName(orderBean.getShopName());
        deliveryOrderRequestDto.setStoreProvince(storeInfo.getBizVO().getProvince());
        deliveryOrderRequestDto.setStoreCity(storeInfo.getBizVO().getCity());
        deliveryOrderRequestDto.setStoreArea(storeInfo.getBizVO().getRegion());
        deliveryOrderRequestDto.setStoreContact(StringUtils.isEmpty(storeInfo.getBizVO().getStoreContacts()) ? storeInfo.getBizVO().getStoreName() : storeInfo.getBizVO().getStoreContacts());

        deliveryOrderRequestDto.setReceiverName(orderBean.getUserName());
        deliveryOrderRequestDto.setReceiverPrimaryPhone(orderBean.getPhone());
        deliveryOrderRequestDto.setReceiverAddress(orderBean.getAddress());
        deliveryOrderRequestDto.setReceiverLng(new BigDecimal(orderBean.getLongitude()));
        deliveryOrderRequestDto.setReceiverLat(new BigDecimal(orderBean.getLatitude()));
        deliveryOrderRequestDto.setProvinceName(orderBean.getReceiveProvince());
        deliveryOrderRequestDto.setCityName(orderBean.getReceiveCity());
        deliveryOrderRequestDto.setAreaName(orderBean.getReceiveRegion());
        deliveryOrderRequestDto.setOrderTime(new Date(orderBean.getGmtCreate()));
        deliveryOrderRequestDto.setCallbackUrl(deliveryCallBackUrl);
        deliveryOrderRequestDto.setWxaPath("pages/index");

        List<CreateDeliveryOrderRequestDto.DeliveryProductInfo> productInfos = new ArrayList<>();
        orderBean.getProductList().forEach(productList -> {
            CreateDeliveryOrderRequestDto.DeliveryProductInfo deliveryProductInfo = new CreateDeliveryOrderRequestDto.DeliveryProductInfo();
            deliveryProductInfo.setProductCode(productList.getProductId());
            deliveryProductInfo.setProductName(productList.getProductName());
            deliveryProductInfo.setProductNumber(productList.getNumber());
            deliveryProductInfo.setProductPrice(productList.getPrice().intValue());
            deliveryProductInfo.setProductImg(productList.getPicture());
            productInfos.add(deliveryProductInfo);
        });
        deliveryOrderRequestDto.setProductInfos(productInfos);

        return deliveryOrderRequestDto;
    }


    /**
     * 创建配送单请求对象
     *
     * @param order
     * @param storeInfo
     * @return
     */
    public CreateDeliveryVo buildDeliveryOrderRequestDto(QueryOrdersResponseDto.DataBean.OrderBean order
            , StoreResponse storeInfo, String deliveryCallBackUrl, String displayOrderId ) {

        SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

        CreateDeliveryVo deliveryOrderRequestDto = new CreateDeliveryVo();
        OrderExtInfoDto orderExtInfoDto = JSON.parseObject(order.getExtInfo(), OrderExtInfoDto.class);
        deliveryOrderRequestDto.setInvoiceTitle(orderExtInfoDto.getInvoiceTitle());
        deliveryOrderRequestDto.setDepatchWeight(order.getWeight());
        //deliveryOrderRequestDto.setSerialNumber(order.getOtherCode());
        deliveryOrderRequestDto.setOrderId(order.getOid());
        JSONObject json = JSON.parseObject(order.getExtInfo());
        String needTableWare = json.getString("needTableware");
        if("0".equals(needTableWare)) {
            deliveryOrderRequestDto.setOrderRemark("无需餐具（刀、叉、勺），"+order.getRemark());
        } else {
            deliveryOrderRequestDto.setOrderRemark("需要餐具（刀、叉、勺），"+order.getRemark());
        }
        deliveryOrderRequestDto.setOrderTotalAmount(order.getAmount().intValue());
        deliveryOrderRequestDto.setOrderActualAmount(order.getAmount().intValue());
        deliveryOrderRequestDto.setPartnerId(order.getCompanyId());
        deliveryOrderRequestDto.setOrderChannel(order.getSource());
        deliveryOrderRequestDto.setStoreId(storeInfo.getBizVO().getStoreId());
        deliveryOrderRequestDto.setStoreCode(storeInfo.getBizVO().getStoreCode());
        StringBuffer address = new StringBuffer(storeInfo.getBizVO().getCity())
                .append(storeInfo.getBizVO().getProvince())
                .append(storeInfo.getBizVO().getRegion())
                .append(storeInfo.getBizVO().getAddress());
        deliveryOrderRequestDto.setStoreAddress(address.toString());
        deliveryOrderRequestDto.setStoreLng(new BigDecimal(storeInfo.getBizVO().getLongitude()));
        deliveryOrderRequestDto.setStoreLat(new BigDecimal(storeInfo.getBizVO().getLatitude()));
        deliveryOrderRequestDto.setStorePhone(storeInfo.getBizVO().getPhone());
        deliveryOrderRequestDto.setStoreName(order.getShopName());
        deliveryOrderRequestDto.setCityName(storeInfo.getBizVO().getCity());
        deliveryOrderRequestDto.setReceiverName(order.getUserName());
        deliveryOrderRequestDto.setReceiverPrimaryPhone(order.getPhone());
        deliveryOrderRequestDto.setReceiverAddress(order.getAddress());
        deliveryOrderRequestDto.setReceiverLng(new BigDecimal(order.getLongitude()));
        deliveryOrderRequestDto.setReceiverLat(new BigDecimal(order.getLatitude()));
        deliveryOrderRequestDto.setOrderTime(DateUtil.addHours(new Date(order.getGmtCreate()), -8));
        deliveryOrderRequestDto.setCallbackUrl(deliveryCallBackUrl);
        // 预约单预计送到时间
        if (order.getGmtExpect() != null && order.getGmtExpect() != 0) {
            deliveryOrderRequestDto.setExpectTime(new Date(order.getGmtExpect()));
            deliveryOrderRequestDto.setIsPre(1);
        } else {
            deliveryOrderRequestDto.setIsPre(0);
        }

        //---麦咖啡餐道专用---
        deliveryOrderRequestDto.setDisplayOrderId(displayOrderId);
        deliveryOrderRequestDto.setTaxFlag(1);
        if (CollectionUtils.isNotEmpty(order.getAccountList())) {
            List<QueryOrdersResponseDto.DataBean.OrderBean.AccountBean> collect = order.getAccountList().stream().filter(account -> account != null && OldOrderAccountType.DELIVERY_AMOUNT.getCode().equals(account.getType())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {
                //配送费
                deliveryOrderRequestDto.setDeliveryTotal(collect.get(0).getPrice().intValue());
            } else {
                deliveryOrderRequestDto.setDeliveryTotal(0);
            }
        }else {
            deliveryOrderRequestDto.setDeliveryTotal(0);
        }
        deliveryOrderRequestDto.setIsPayed(1);
        deliveryOrderRequestDto.setTenderType("WeChat");
        deliveryOrderRequestDto.setIsLargeOrder(0);
        if (deliveryOrderRequestDto.getIsPre()== 1 && deliveryOrderRequestDto.getExpectTime() !=null){
            deliveryOrderRequestDto.setIsImmediateDelivery(0);
            deliveryOrderRequestDto.setExpectDeliveryTimeByUTC(simpleDateFormat.format(DateUtil.addHours(deliveryOrderRequestDto.getExpectTime(), -8)));
        }else {
            deliveryOrderRequestDto.setIsImmediateDelivery(1);
            String expectDeliveryTimeByUTC = order.getGmtCreate() !=null ?
                    simpleDateFormat.format(DateUtil.addHours(DateUtil.addMinutes(new Date(order.getGmtCreate()),storeInfo.getBizVO().getServiceTime()), -8)) :null;
            deliveryOrderRequestDto.setExpectDeliveryTimeByUTC(expectDeliveryTimeByUTC);
        }

        Optional<QueryOrdersResponseDto.DataBean.OrderBean.ProductBean> productVoOptional = order.getProductList().stream()
                .filter(o -> StringUtils.isNotBlank(JSON.parseObject(o.getExtInfo(), OrderProductAddInfoDto.class).getSplitIndex()))
                .findFirst();
        Map<String, Integer> existMap = new HashMap<>();

        if(productVoOptional.isPresent()) {
            int size = order.getProductList().size();
            List<QueryOrdersResponseDto.DataBean.OrderBean.ProductBean> productVoList = new ArrayList<>();
            for(int i=0;i<size;i++) {
                QueryOrdersResponseDto.DataBean.OrderBean.ProductBean productBean = order.getProductList().get(i);
                String splitIndex = JSON.parseObject(productBean.getExtInfo(), OrderProductAddInfoDto.class).getSplitIndex();
                if(StringUtils.isBlank(splitIndex)) {
                    productVoList.add(productBean);
                } else {
                    if(existMap.get(splitIndex) == null) {
                        existMap.put(splitIndex, productVoList.size());
                        productVoList.add(productBean);
                    } else {
                        QueryOrdersResponseDto.DataBean.OrderBean.ProductBean productBeanExists = productVoList.get(existMap.get(splitIndex));
                        productBeanExists.setNumber(productBeanExists.getNumber() + productBean.getNumber());
                    }
                }
            }
            order.setProductList(productVoList);
        }

        List<ProductInfo> productInfos = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(order.getProductList())) {
            order.getProductList().forEach(productList -> {
                ProductInfo deliveryProductInfo = new ProductInfo();
                deliveryProductInfo.setProductCode(productList.getProductId().substring(4));
                String productName = StringUtils.isBlank(productList.getSpecificationName()) ? productList.getProductName() : productList.getSpecificationName();
                String grilling = "";

                OrderProductAddInfoDto extInfo = JSON.parseObject(productList.getExtInfo(), OrderProductAddInfoDto.class);
                if(CollectionUtils.isNotEmpty(extInfo.getSpecialAttrs())) {
                    String attr = "";
                    for (OrderSpecialExtraAttrRequest special : extInfo.getSpecialAttrs()) {
                        if(special.getAttributeName().indexOf("冰") >= 0) {
                            attr = special.getAttributeName();
                            break;
                        }
                    }
                    if(attr.length() > 0) {
                        productName += "("+attr+")";
                    }
                }

                if(CollectionUtils.isNotEmpty(productList.getMaterialProduct())) {
                    for (QueryOrdersResponseDto.DataBean.OrderBean.ProductBean material : productList.getMaterialProduct()) {
                        grilling += material.getSpecificationName() + "/";
                    }
                }
                if(grilling.length() > 0) {
                    grilling = grilling.substring(0, grilling.length()-1);
                }
                deliveryProductInfo.setGrilling(grilling);
                deliveryProductInfo.setProductName(productName);
                deliveryProductInfo.setProductNumber(productList.getNumber());
                deliveryProductInfo.setProductPrice(productList.getSalePrice().intValue());
                //餐道使用
                deliveryProductInfo.setCumulatedTotal(productList.getNumber() * productList.getSalePrice().intValue());
                OrderProductAddInfoDto orderProductAddInfoDto = JSON.parseObject(productList.getAddInfo(), OrderProductAddInfoDto.class);
                deliveryProductInfo.setTaxId(StringUtils.isNotEmpty(orderProductAddInfoDto.getTaxId()) ? orderProductAddInfoDto.getTaxId() : "10");
                deliveryProductInfo.setTaxRate(orderProductAddInfoDto.getTax() > 0 ? orderProductAddInfoDto.getTax() : 6);
                deliveryProductInfo.setParentCode(-1l);

                productInfos.add(deliveryProductInfo);

                boolean isFeiChangDa = productList.getProductName().equalsIgnoreCase("啡常搭");

                if(CollectionUtils.isNotEmpty(productList.getComboProduct())) {
                    productList.getComboProduct().forEach(comboProduct -> {
                        ProductInfo deliveryComboProductInfo = new ProductInfo();
                        deliveryComboProductInfo.setProductCode(comboProduct.getProductId().length()>4?comboProduct.getProductId().substring(4):comboProduct.getProductId());
                        String productNameCombo = StringUtils.isBlank(comboProduct.getSpecificationName()) ? comboProduct.getProductName() : comboProduct.getSpecificationName();
                        String grillingCombo = "";

                        OrderProductAddInfoDto extInfoCombo = JSON.parseObject(comboProduct.getExtInfo(), OrderProductAddInfoDto.class);
                        if(CollectionUtils.isNotEmpty(extInfoCombo.getSpecialAttrs())) {
                            String attr = "";
                            for (OrderSpecialExtraAttrRequest special : extInfoCombo.getSpecialAttrs()) {
                                if(special.getAttributeName().indexOf("冰") >= 0) {
                                    attr = special.getAttributeName();
                                    break;
                                }
                            }
                            if(attr.length() > 0) {
                                productNameCombo += "("+attr+")";
                            }
                        }

                        if(CollectionUtils.isNotEmpty(comboProduct.getMaterialProduct())) {
                            for (QueryOrdersResponseDto.DataBean.OrderBean.ProductBean material : comboProduct.getMaterialProduct()) {
                                grillingCombo += material.getSpecificationName() + "/";
                            }
                        }
                        if(grillingCombo.length() > 0) {
                            grillingCombo = grillingCombo.substring(0, grillingCombo.length()-1);
                        }
                        deliveryComboProductInfo.setGrilling(grillingCombo);
                        deliveryComboProductInfo.setProductName(productNameCombo);
                        deliveryComboProductInfo.setProductNumber(comboProduct.getNumber()/productList.getNumber());
                        if(isFeiChangDa) {
                            deliveryComboProductInfo.setProductPrice(comboProduct.getSalePrice().intValue());
                            //餐道使用
                            deliveryComboProductInfo.setCumulatedTotal(comboProduct.getNumber() * comboProduct.getSalePrice().intValue());
                        } else {
                            deliveryComboProductInfo.setProductPrice(0);
                            //餐道使用
                            deliveryComboProductInfo.setCumulatedTotal(0);
                        }
                        OrderProductAddInfoDto orderComboProductAddInfoDto = JSON.parseObject(comboProduct.getAddInfo(), OrderProductAddInfoDto.class);
                        deliveryComboProductInfo.setTaxId(StringUtils.isNotEmpty(orderComboProductAddInfoDto.getTaxId()) ? orderComboProductAddInfoDto.getTaxId() : "10");
                        deliveryComboProductInfo.setTaxRate(orderComboProductAddInfoDto.getTax() > 0 ? orderComboProductAddInfoDto.getTax() : 6);

                        deliveryComboProductInfo.setParentCode(Long.valueOf(comboProduct.getParentProductId().replace("_", "").substring(4)));
                        deliveryProductInfo.setProductCode(deliveryComboProductInfo.getParentCode()+"");

                        if(CollectionUtils.isNotEmpty(comboProduct.getMaterialProduct())) {
                            comboProduct.getMaterialProduct().forEach(o -> {
                                deliveryComboProductInfo.setProductPrice(deliveryComboProductInfo.getProductPrice() + o.getSalePrice().intValue());
                                //餐道使用
                                deliveryComboProductInfo.setCumulatedTotal(deliveryComboProductInfo.getCumulatedTotal() + comboProduct.getNumber() * o.getSalePrice().intValue());

                                deliveryProductInfo.setProductPrice(deliveryProductInfo.getProductPrice() + o.getSalePrice().intValue());
                                //餐道使用
                                deliveryProductInfo.setCumulatedTotal(deliveryProductInfo.getCumulatedTotal() + comboProduct.getNumber() * o.getSalePrice().intValue());
                            });
                        }

                        productInfos.add(deliveryComboProductInfo);
                    });
                }

                if(CollectionUtils.isNotEmpty(productList.getMaterialProduct())) {
                    productList.getMaterialProduct().forEach(o -> {
                        deliveryProductInfo.setProductPrice(deliveryProductInfo.getProductPrice() + o.getSalePrice().intValue());
                        //餐道使用
                        deliveryProductInfo.setCumulatedTotal(deliveryProductInfo.getCumulatedTotal() + productList.getNumber() * o.getSalePrice().intValue());
                    });
                }
            });
            deliveryOrderRequestDto.setProductTotal(productInfos.stream().mapToInt(t -> t.getCumulatedTotal()==null?0:t.getCumulatedTotal()).sum());
        }



        deliveryOrderRequestDto.setProductInfos(productInfos);
        deliveryOrderRequestDto.setOrderSource(OrderSourceType.ALIPAY.getCode().equals(order.getSource())?"Alipay":"freemud");
        if(CollectionUtils.isNotEmpty(order.getAccountList())) {
            List<CreateDeliveryPreferentialVo> createDeliveryPreferentialVos = new ArrayList<>();
            order.getAccountList().stream().forEach(accountBean -> {
                if (OldOrderAccountType.COUPON.getCode().equals(accountBean.getType())
                        || OldOrderAccountType.BUY_DISCOUNT.getCode().equals(accountBean.getType())
                        || OldOrderAccountType.PRODUCT_COUPON.getCode().equals(accountBean.getType())
                        || OldOrderAccountType.SUPER_PURCHASE.getCode().equals(accountBean.getType())
                        || OldOrderAccountType.DISCOUNT_AMOUNT.getCode().equals(accountBean.getType())
                        || OldOrderAccountType.FREIGHT_COUPON.getCode().equals(accountBean.getType())) {
                    CreateDeliveryPreferentialVo createDeliveryPreferentialVo = new CreateDeliveryPreferentialVo();
                    createDeliveryPreferentialVo.setPreferentialContent(accountBean.getName());
                    createDeliveryPreferentialVo.setPreferentialPrice(0-accountBean.getPrice());
                    createDeliveryPreferentialVos.add(createDeliveryPreferentialVo);
                }
            });
            deliveryOrderRequestDto.setPreferentials(createDeliveryPreferentialVos);
        }
        return deliveryOrderRequestDto;
    }

}


