package com.bohuikeji.delivery.backstage.service.third;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bohuikeji.delivery.backstage.entity.TConfig;
import com.bohuikeji.delivery.backstage.entity.TCourier;
import com.bohuikeji.delivery.backstage.entity.TOrder;
import com.bohuikeji.delivery.backstage.entity.TOrderCircu;
import com.bohuikeji.delivery.backstage.entity.open.VoBase;
import com.bohuikeji.delivery.backstage.entity.open.vo.CourierVo;
import com.bohuikeji.delivery.backstage.entity.third.OrderDetailDO;
import com.bohuikeji.delivery.backstage.listener.order.OrderCheckPriceListener;
import com.bohuikeji.delivery.backstage.service.ITConfigService;
import com.bohuikeji.delivery.backstage.service.ITCourierService;
import com.bohuikeji.delivery.backstage.service.ITOrderService;
import com.bohuikeji.delivery.backstage.service.third.base.ThirdBase;
import com.bohuikeji.delivery.backstage.task.JdCancelOrderTask;
import com.bohuikeji.delivery.backstage.util.capacity.JdUtils;
import com.bohuikeji.delivery.backstage.util.capacity.ShanSongUtils;
import com.bohuikeji.frame.module.admin.component.MqTool;
import com.bohuikeji.frame.module.admin.component.RedisUtil;
import com.bohuikeji.frame.module.admin.entity.back.APIEntity;
import com.bohuikeji.frame.module.admin.entity.vo.AddressVo;
import com.bohuikeji.frame.module.admin.utils.MapUtils;
import com.bohuikeji.frame.module.admin.utils.TaskUtils;
import com.bohuikeji.frame.module.admin.utils.YiXunGmsUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 京东配送服务类
 * @author Admin
 */
@Slf4j
@Component
public class JdServer  extends ThirdBase {
    /**
     * 子类向父类注册自己
     ***
     */
    public JdServer(ITOrderService orderService, RedisTemplate<String, Object> redisTemplate, MqTool mqTool,RedisUtil redisUtil,ITConfigService configService,ITCourierService courierService) {
        super(NAME, JdServer.class, "京东获取取件任务", "揽收任务分配", "快递接货", "妥投", "终止揽收");
        this.orderService = orderService;
        this.redisTemplate=redisTemplate;
        this.mqTool = mqTool;
        this.redisUtil=redisUtil;
        this.configService=configService;
        this.courierService = courierService;
    }
    final ITOrderService orderService;
    final RedisTemplate<String, Object> redisTemplate;
    final MqTool mqTool;
    final RedisUtil redisUtil;
    final ITConfigService configService;
    final ITCourierService courierService;
    /**
     * 服务名
     */
    public static final String NAME ="JD";

    @Override
    public APIEntity<OrderDetailDO> orderInquiryAndPlace(TOrder order) {
        //return APIEntity.fail("暂停京东推送业务！");
        log.error("##################################京东下单业务#######################");
        /*if(order.getPlayerId()==203){
            return APIEntity.fail("【京东推单取消】订单：{}，周立武的订单不推送京东。",order.getOrderNum());
        }*/
        if (!JdServer.isJdOrder(order.getOrderNum())){
            return APIEntity.fail("【京东推单取消】订单：{}，非京东订单。",order.getOrderNum());
        }
        //下单
        JSONObject res=JdUtils.receiveOrderInfo(order);
        if (res.getIntValue("resultCode")!=100){
            YiXunGmsUtils.sendTxt(order.getMailingPhone(),"您的订单："+order.getOrderNum()+"由于："+res.getString("resultMessage"));
            orderService.cancelAndRefund(order);
            return APIEntity.fail("【京东下单失败】{}",res.getString("resultMessage"));
        }
        OrderDetailDO detailDO=new OrderDetailDO();
        detailDO.setThirdName(NAME);
        detailDO.setThirdNum(res.getString("deliveryId"));
        detailDO.setOrderNumber(order.getOrderNum());
        detailDO.setDistance(String.valueOf(order.getOrderDistance()));
        detailDO.setOrderPrice(order.getOrderExpectPrice());
        return APIEntity.success(detailDO);
    }

    @Override
    public APIEntity<OrderDetailDO> orderDetail(String orderNum, String thirdNum) {
        //先查询缓存订单
        OrderDetailDO detailDO= redisUtil.get(ThirdBase.getCacheKey(orderNum,NAME),OrderDetailDO.class);
        if (detailDO==null){
            detailDO=new OrderDetailDO();
        }
        detailDO.setThirdName(NAME);
        detailDO.setThirdNum(thirdNum);
        detailDO.setOrderNumber(orderNum);
        //查询价格
        JSONObject res=JdUtils.queryOrderPrice(detailDO.getThirdNum()).getJSONObject("data");
        if (res==null){
            log.error("订单：{}，无法查询价格，返回空当前状态：{}",orderNum,detailDO.getStatus());
            return APIEntity.fail("【京东核查价格失败】订单：{}尚未生产运单信息",orderNum);
        }
        if (res.getIntValue("code")!=1){
            log.error("订单：{}，无法查询价格，查询失败，当前状态：{}",orderNum,detailDO.getStatus());
            return APIEntity.fail("【京东核查价格失败】订单：{}查询失败，返回信息：{}",res.getString("msg"));
        }
        log.error("订单价格核查：订单号：{}，三方单号：{}",orderNum,thirdNum);
        log.error("订单价格核查,返回信息：{}",res);
        BigDecimal price=sumPrice(res.getJSONArray("feeInfoList"));
        detailDO.setOrderPrice(price.multiply(new BigDecimal("0.7")).setScale(2, RoundingMode.DOWN));
        return APIEntity.success(detailDO);
    }

    @Override
    public APIEntity<CourierVo> courierInfo(String orderNum, String thirdNum) {
        TOrder order = orderService.getByNum(orderNum);
        if("待接单".equals(order.getOrderStatus()) && order.getCourierId() == null){
            return APIEntity.fail("该订单骑手未接单！");
        }if("已完成".equals(order.getOrderStatus())){
            return APIEntity.fail("运单已完成，无实时位置数据！");
        }
        TCourier courier=courierService.getById(order.getCourierId());
        JSONObject res=JdUtils.waybillGisTrack(thirdNum);
        log.info("京东经纬度逆地理编码：{}",res);
        if(res.getInteger("statusCode") != 1){
            return APIEntity.fail(res.getString("statusMessage"));
        }
        JSONObject data=res.getJSONObject("data");
        JSONArray gisDtoList = data.getJSONArray("waybillGisDtoList");
        String location=null;
        if(gisDtoList.size()>=1){
            JSONObject job = (JSONObject) gisDtoList.get(gisDtoList.size()-1);
            location = job.getDoubleValue("lng")+","+job.getDoubleValue("lat");
        }
        CourierVo courierVo= VoBase.copy(courier,CourierVo.class);
        courierVo.setCourierName(data.getString("courierName"));
        courierVo.setCourierPhone(data.getString("courierMobile"));
        AddressVo addressVo = MapUtils.getAddressReGeo(location);
        courierVo.setLastLocation(addressVo);
        return APIEntity.success(courierVo);
    }

    @Override
    public APIEntity<JSONObject> orderCancel(String orderNum, String thirdNum) {
        //不是京东的订单，直接取消成功
        if (!thirdNum.contains(NAME)){
            return APIEntity.success();
        }
        if(!JdUtils.cancelOrder(thirdNum,"客户主动取消","客户")){
            TaskUtils.add(new JdCancelOrderTask())
                    .addParam("deliveryId",thirdNum)
                    .addParam("times",1)
                    .addParam("reason","客户主动取消")
                    .addParam("operator","客户");
        }
        return APIEntity.success();
    }

    @Override
    public APIEntity<JSONObject> orderTip(String orderNum, String thirdNum, BigDecimal tipAmount) {
        return null;
    }

    @Override
    public List<TOrderCircu> orderRecord(String orderNum, String thirdNum) {
        JSONObject res=JdUtils.queryTrace(thirdNum);
        if (res.getIntValue("code")!=100){
            return null;
        }
        return res.getJSONArray("data").stream().map(v->{
            TOrderCircu circ=new TOrderCircu();
            JSONObject json=(JSONObject) v;
            circ.setChangeStatus(json.getString("opeRemark"));
            circ.setChangeTime(LocalDateTime.ofInstant(json.getDate("opeTime").toInstant(), ZoneId.systemDefault()));
            return circ;
        }).collect(Collectors.toList());
    }

    @Override
    public String queryStatusDesc(int statusCode) {
        return null;
    }

    /**
     * 该方法必须子线程调用，主线程调用可能阻塞
     * 订单复核——第三方接单之后
     * @param orderNum 订单号
     * @param thirdNum 第三方订单号
     */
    @Override
    public void orderReview(String orderNum, String thirdNum) {
        //延迟5分钟，复核京东计费
        mqTool.sendDelayMsg(orderNum, OrderCheckPriceListener.class, Duration.ofMinutes(8));
    }

    /**
     * 计算补充价格
     * @param orderNum 订单号
     * @return
     */
    public BigDecimal computeSupplyPay(String orderNum){
        TOrder order=orderService.getByNum(orderNum);
        JSONObject res=JdUtils.queryOrderPrice(order.getThirdNum()).getJSONObject("data");
        if (res==null){
            return null;
        }
        JSONArray array=res.getJSONArray("feeInfoList");
        if (array==null){
            return null;
        }
        BigDecimal allPrice=sumPrice(array);
        //京东价格比订单价格高，说明存在差价，发送短信
        if(allPrice.compareTo(order.getOrderFactPrice().add(order.getPrefAmount()))>0){
            return allPrice.subtract(order.getOrderFactPrice().add(order.getPrefAmount()));
        }
        return new BigDecimal("0.00");
    }

    /**
     * 京东费用信息累加
     * @param array
     * @return
     */
    private BigDecimal sumPrice(JSONArray array){
        BigDecimal allPrice=new BigDecimal("0.00").setScale(2, BigDecimal.ROUND_DOWN);
        if (array==null){
            return allPrice;
        }
        for (int i = 0; i < array.size(); i++) {
            allPrice=allPrice.add(array.getJSONObject(i).getBigDecimal("standardAmount"));
        }
        return allPrice;
    }

    /**
     * 判断订单号是否为京东订单
     * @param orderNum
     * @return
     */
    public static boolean isJdOrder(String orderNum){
        return "D".equals(orderNum.substring(0,1));
    }
}
