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

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bohuikeji.delivery.backstage.constants.KeyConst;
import com.bohuikeji.delivery.backstage.entity.*;
import com.bohuikeji.delivery.backstage.mapper.TCourierMapper;
import com.bohuikeji.delivery.backstage.service.*;
import com.bohuikeji.delivery.backstage.thread.OffLineMsgThread;
import com.bohuikeji.frame.module.admin.base.ServiceImplBase;
import com.bohuikeji.frame.module.admin.component.RedisUtil;
import com.bohuikeji.frame.module.admin.entity.back.APIEntity;
import com.bohuikeji.frame.module.admin.entity.sys.SysConfig;
import com.bohuikeji.frame.module.admin.entity.vo.AddressVo;
import com.bohuikeji.frame.module.admin.service.ISysConfigService;
import com.bohuikeji.frame.module.admin.service.ITFranchiseeInformationService;
import com.bohuikeji.frame.module.admin.thread.CachedThreadPool;
import com.bohuikeji.frame.module.admin.utils.DistanceUtils;
import com.bohuikeji.frame.module.admin.utils.MapUtils;
import com.bohuikeji.frame.module.admin.utils.NumberUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

import static com.bohuikeji.delivery.backstage.constants.KeyConst.REDIS_COURIER_LOCATION_ADDRESS;

/**
 * <p>
 * 派送员信息表 服务实现类
 * </p>
 *
 * @author 10552
 * @since 2019-08-22
 */
@Service
@Slf4j
public class TCourierServiceImpl extends ServiceImplBase<TCourierMapper, TCourier> implements ITCourierService {
    @Autowired
    ISysConfigService sysConfigService;
    @Autowired
    ITVehicleInformationService carService;
    @Autowired
    ITCourierService courierService;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    ITLocationService locationService;
    @Autowired
    ITFranchiseeInformationService franchiseeInformationService;
    @Autowired
    ITOrderService orderService;
    @Autowired
    ITCustomerBigService customerBigService;
    @Autowired
    ITCustomerService customerService;
    @Autowired
    ISocketService socketService;
    @Autowired
    IWxUserService wxUserService;



    @Override
    public List<TCourier> getMonthRanking() {
        return this.baseMapper.selectMonthRanking();
    }

    @Override
    public List<TCourier> getWeekRanking() {
        return this.baseMapper.selectWeekRanking();
    }

    @Override
    public BigDecimal getTodayIncome(Integer id) { return this.baseMapper.selectTodayIncome(id); }//今日收入

    @Override
    public Integer getTordercount(Integer id) {
        return this.baseMapper.selectTodayCount(id);
    }//今日单量

    @Override
    public Integer getTotalCount(Integer id) { return this.baseMapper.selectTotalCount(id); }//派送员接单总数

    @Override
    public Integer getNotCompleteCount(Integer id) { return this.baseMapper.selectNotCompleteCount(id); }//派送员未完成订单总数

    @Override
    public Integer getCompleteCount(Integer id) { return this.baseMapper.selectCompleteCount(id); }//派送员完成订单总数

    @Override
    public BigDecimal getTotalIncomeCount(Integer id) { return this.baseMapper.selectIncome(id); }//派送员完成订单总收入金额

    @Override
    public SysConfig getCourierPrice(Integer id) {
        TCourier tCourier = getById(id);
        if("全职".equals(tCourier.getCourierType())){
            return sysConfigService.getOne(new QueryWrapper<SysConfig>().eq("config_key","courier_settled_money"));
        }
        //获取派送员最后一次认证车辆信息
        TVehicleInformation car=carService.getOne(new QueryWrapper<TVehicleInformation>().eq("courier_id",id).orderByDesc("vehicle_id").last(" limit 1"));
        if(car==null){
            //未认证车辆缴费金额
            return sysConfigService.getOneByKey("courier_add_price_car_type_null");
        }
        //已提交认证车辆缴费金额
        return sysConfigService.getOneByKey("courier_add_price_"+(sysConfigService.getById(car.getVehicleTypeId()).getConfigKey()));
    }

    @Override
    public TCourier getCacheById(Integer id) {
        TCourier courier=redisUtil.get("courier:id:"+id,TCourier.class);
        if(courier==null){
            courier=getById(id);
            redisUtil.set("courier:id:"+id,courier,60*60*6);
        }
        return courier;
    }

    @Override
    public AddressVo getAddress(String location,Integer id) {
        AddressVo address = null;
        StringBuilder str = new StringBuilder();
            address=redisUtil.get(REDIS_COURIER_LOCATION_ADDRESS+id,AddressVo.class);
            if(null != address){
                str.append(address.getLng());
                str.append(",");
                str.append(address.getLat());
            }
            if(!str.equals(location)){
                address= MapUtils.getAddressReGeo(location);
                redisUtil.set(REDIS_COURIER_LOCATION_ADDRESS+id,address,3600*8);
            }
        return address;
    }

    /**
     * 判断骑手的缴费金额等级符不符合接单规则
     * @param courier
     * @param order
     * @return
     */
    @Override
    public JSONObject getType(TCourier courier, TOrder order) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type",true);
        Double goodsValue = Double.valueOf(order.getWorthName().replaceAll("元",""));
        if("兼职".equals(courier.getCourierType()) || "营销".equals(courier.getCourierType())){
            if(courier.getCourierSettledMoney().compareTo(new BigDecimal("1000.00")) == 0){
                jsonObject.put("type",true);
                return jsonObject;
            }
            if(courier.getCourierSettledMoney().compareTo(new BigDecimal("0.00")) ==0 && goodsValue > 500d || courier.getCourierSettledMoney().compareTo(new BigDecimal("0.00")) ==0 && order.getOrderExpectPrice().compareTo(new BigDecimal(30)) == 1){
                jsonObject.put("type",false);
                jsonObject.put("message","您的入驻等级不够，无法接取价值50元和运费15元以上的订单");
            }
            if(courier.getCourierSettledMoney().compareTo(new BigDecimal("50.00")) ==0 && goodsValue > 1000d || courier.getCourierSettledMoney().compareTo(new BigDecimal("50.00")) ==0 && order.getOrderExpectPrice().compareTo(new BigDecimal(50)) == 1){
                jsonObject.put("type",false);
                jsonObject.put("message","您的入驻等级不够，无法接取价值300元和运费30元以上的订单");
            }
            if(courier.getCourierSettledMoney().compareTo(new BigDecimal("100.00")) ==0 && goodsValue > 2000d || courier.getCourierSettledMoney().compareTo(new BigDecimal("100.00")) ==0 && order.getOrderExpectPrice().compareTo(new BigDecimal(100)) ==1){
                jsonObject.put("type",false);
                jsonObject.put("message","您的入驻等级不够，无法接取价值1000元和运费50元以上的订单");
            }
            if(courier.getCourierSettledMoney().compareTo(new BigDecimal("200.00")) ==0 && goodsValue > 3000d || courier.getCourierSettledMoney().compareTo(new BigDecimal("200.00")) ==0 && order.getOrderExpectPrice().compareTo(new BigDecimal(200)) ==1){
                jsonObject.put("bool",false);
                jsonObject.put("message","您的入驻等级不够，无法接取价值3000元和运费200元以上的订单");
            }
            if(courier.getCourierSettledMoney().compareTo(new BigDecimal("300.00")) ==0 && goodsValue > 5000d || courier.getCourierSettledMoney().compareTo(new BigDecimal("300.00")) ==1 && order.getOrderExpectPrice().compareTo(new BigDecimal(500)) ==1){
                jsonObject.put("type",false);
                jsonObject.put("message","您的入驻等级不够，无法接取价值5000元和运费500元以上的订单");
            }
            if(courier.getCourierSettledMoney().compareTo(new BigDecimal("500.00")) ==0 && goodsValue > 10000d || courier.getCourierSettledMoney().compareTo(new BigDecimal("500.00")) ==1 && order.getOrderExpectPrice().compareTo(new BigDecimal(1000)) ==1){
                jsonObject.put("type",false);
                jsonObject.put("message","您的入驻等级不够，无法接取价值10000元和运费1000元以上的订单");
            }
        }
        return jsonObject;
    }

    /**
     * 根据配送方式判断骑手可不可以接单
     * @param courier
     * @param order
     * @return
     */
    @Override
    public JSONObject getJson(TCourier courier, TOrder order) {
        JSONObject jsonObject = new JSONObject();
         if(orderService.list(new QueryWrapper<TOrder>().eq("courier_id",courier.getCourierId()).in("order_status","待支付","待取件","取件中","待派送","派送中")).size()>0){
            if("直送(一对一)".equals(order.getWayName())){
                jsonObject.put("type",false);
                jsonObject.put("message","您有正在进行的订单，无法接取“直送(一对一)”方式的订单，请先完成其他订单");
            }
            if(orderService.list(new QueryWrapper<TOrder>().eq("courier_id",courier.getCourierId()).eq("way_name","直送(一对一)").in("order_status","待支付","待取件","取件中","待派送","派送中")).size()>0){
                jsonObject.put("type",false);
                jsonObject.put("message","您已经接取“直送(一对一)”订单，无法在接取其他订单，请先完成其他订单");
            }
            if(orderService.list(new QueryWrapper<TOrder>().eq("courier_id",courier.getCourierId()).eq("way_name","极送-平均1小时").in("order_status","待支付","待取件","取件中","待派送","派送中")).size()>=2){
                jsonObject.put("type",false);
                jsonObject.put("message","您已经接取“极送-平均1小时”订单，接取的订单不可以超过2单，请先完成其他订单");
            }
            if(orderService.list(new QueryWrapper<TOrder>().eq("courier_id",courier.getCourierId()).in("order_status","待支付","待取件","取件中","待派送","派送中")).size()>=1){
                for(TOrder tOrder : orderService.list(new QueryWrapper<TOrder>().eq("courier_id",courier.getCourierId()).in("order_status","待支付","待取件","取件中","待派送","派送中"))){
                    double stratdist =  DistanceUtils.getDistance(tOrder.getMailingAddress().getLng(),tOrder.getMailingAddress().getLat(),order.getMailingAddress().getLng(),order.getMailingAddress().getLat());//根据经纬度计算两点之间距离
                    double enddist =  DistanceUtils.getDistance(tOrder.getReceiptAddress().getLng(),tOrder.getReceiptAddress().getLat(),order.getReceiptAddress().getLng(),order.getReceiptAddress().getLat());//根据经纬度计算两点之间距离
                    log.info("寄件地址的距离:[{}]",stratdist);
                    log.info("收件地址的距离:[{}]",enddist);
                    if(stratdist > 3 && enddist > 3){
                        jsonObject.put("type",false);
                        jsonObject.put("message","该订单超过你顺路的范围，请先完成其他订单");
                    }
                }
            }
        }
        if(jsonObject.isEmpty()){
            jsonObject.put("type",true);
            return jsonObject;
        }
         return jsonObject;
    }

    @Override
    public List<TOrder> getRunOrderList(Integer courierId) {
        return null;
        /*return list(new QueryWrapper<TOrder>().eq("courier_id",courierId).in("",""));*/
    }

    @Override
    public TCourier getCourier(TCustomer customer) {
        TCourier courier=null;
        TCustomerBig customerBig = customerBigService.getById(customer.getBigId());
        if(customerBig != null){
            courier = courierService.getById(customerBig.getCourierId());
            if(courier==null){
                return null;
            }
        }
        return courier;
    }

    /**
     * 更新骑手活跃时间
     *
     * @param id
     */
    @Override
    public void updateTime(Integer id) {
        update(new UpdateWrapper<TCourier>().set("courier_update_time",LocalDateTime.now()).eq("courier_id",id));
    }

    /**
     * 给当地加盟商下的骑手发送离线消息
     */
    @Override
    public void sendOffLineMgs(TOrder order) {
        //从Redis获取离线骑手
        Set<String> offInes=redisUtil.getPatternKeys(KeyConst.REDIS_COURIER_LAST_ADDRESS+"*");
        if (offInes.isEmpty()){
            log.error("【离线消息退送失败】没有符合的离线骑手~");
            return;
        }
        //id缓存
        List<Integer> idsCatch=new ArrayList<>(100);
        Iterator<String> it = offInes.iterator();
        while (it.hasNext()) {
            String key=it.next();
            AddressVo address=redisUtil.getByFinalKey(key,AddressVo.class);
            double dist = DistanceUtils.getDistance(order.getMailingAddress().getLng(), order.getMailingAddress().getLat(), address.getLng(), address.getLat());
            if (dist<80){
                int leng = key.length();
                Integer id=Integer.valueOf(key.substring(key.lastIndexOf(":") + 1, leng));
                idsCatch.add(id);
            }
            if(it.hasNext()&&idsCatch.size()<100){
                continue;
            }
            try {
                CachedThreadPool.execute(new OffLineMsgThread(wxUserService,idsCatch,order));
            } catch (Exception e) {
                log.error("【离线推送线程启动失败】",e);
                e.printStackTrace();
            }
            idsCatch=new ArrayList<>(100);
        }
    }

    /**
     * 判断是否为弹框
     * @param type
     * @return
     */
    public  Boolean contrast(String type){
        String[] strArr = {"弹框","立减弹框","满减弹框","折扣弹框","万能弹框"};
        boolean res = Arrays.asList(strArr).contains(type);
        return res;
    }

    @Override
    public Boolean getCourierStatus(Integer courierId) {
        TCourier tCourier = courierService.getById(courierId);
        String[] strArr = {"已注销","禁止接单","禁止登陆","停止"};
        boolean res = Arrays.asList(strArr).contains(tCourier.getCourierStatus());
        return res;
    }

    @Override
    public TCourier saveCourier(String phone) {
        TCourier courier = new TCourier();
        String num= NumberUtils.getShort();
        courier.setCourierName("派送员"+num);
        courier.setCourierNumber(num);
        courier.setCourierPwd(NumberUtils.getPwd());
        courier.setCourierPhone(phone);
        courierService.save(courier);
        return courier;
    }

}
