package com.ruoyi.applet.service.impl;

import com.cyl.h5.pojo.vo.H5OrderVO;
import com.cyl.h5.service.H5OrderService;
import com.cyl.manager.oms.domain.OmsOrderService;
import com.cyl.manager.oms.mapper.OrderMapper;
import com.ruoyi.applet.service.IMallOrderService;
import com.ruoyi.common.config.properties.SmsProperties;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.sms.AliyunSmsUtils;
import com.ruoyi.model.domain.*;
import com.ruoyi.model.service.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Slf4j
public class IMallOrderServiceImpl implements IMallOrderService {

    //下单小程序：那边来的订单信息
    @Autowired
    private H5OrderService h5OrderService;
    @Autowired
    private OrderMapper orderMapper;
    //伴宠师小程序：获取已经认证好的伴宠师微信信息以及认证信息
    @Autowired
    private IAppUsersService appUsersService;
    //伴宠师小程序：派单信息的接收写入
    @Autowired
    private IAppletOrderService appletOrderService;

    @Autowired
    private IAppletAddressService appletAddressService;

    @Autowired
    private IAppletOrderItemDateService appletOrderItemDateService;
    @Autowired
    private SmsProperties smsProperties;


    //点击派单：进入派单逻辑
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void dispatch(Long orderId){
        //获取下单小程序的所有订单信息
        H5OrderVO h5OrderVO = h5OrderService.orderDetail(orderId);
        log.info("得到的伴宠师标识:userId:{}",h5OrderVO.getStaffId());
        //获取当前规则内的可接单的伴宠师

        //测试：目前随机给一个   ----需要再次优化：lzx:对接下单小程序
        Long appletUserId = h5OrderVO.getStaffId();
        appletUserId = 1743362133542L; //指定测试
        //测试：目前给所有能接单的伴宠师
        //appletUserId = null;

        acceptDispatch(appletUserId, h5OrderVO);

    }


    //接单：进入接单逻辑 -> 1.根据规则查询可接单的伴宠师
    // 有id传入则指定人员，如果没有则进入接单大厅接单逻辑
    @Override
    public AjaxResult acceptDispatch(Long appletUserId, H5OrderVO h5OrderVO){
        //查询该订单是否已存在
        AppletOrder order = appletOrderService.selectAppletOrderByOrderId(h5OrderVO.getOrderId());
        if(order != null){
            log.error("该订单已存在，无需重复派单,order:{}",order);
            return  AjaxResult.error("该订单已存在，无需重复派单");
        }

        AppletOrder appletOrder = new AppletOrder();
        if(appletUserId != null){
            //指定人员接单
            AppUsers appUsers = appUsersService.selectAppUsersByUserId(appletUserId);
            if (appUsers == null) {
                log.error("未找到伴宠师或伴宠师状态异常,流转进入接单大厅接单逻辑,appletUserId:{}",appletUserId);
                acceptDispatchAll(h5OrderVO);
                AjaxResult.error();;
            }
            long l = System.currentTimeMillis();
            appletOrder.setId(l);
            appletOrder.setPayTime(LocalDateTime.now());
            appletOrder.setCreateTime(LocalDateTime.now());
            appletOrder.setType("1"); //指定人接单
            //appletUserId 用json形式储存
            appletOrder.setUserIdJson(""+appletUserId);
            appletOrder.setStartUserIdJson(""+appletUserId);
            appletOrder.setOrderTime(3); //设置为三分钟
            appletOrder.setNum(1);
            appletOrder.setStatus(0); //派单中
            appletOrder.setPrice(h5OrderVO.getPayAmount());//订单支付金额：这个地方用来计算订单的佣金
            //详细地址通过拼接得到
            String address = h5OrderVO.getReceiverProvince() + h5OrderVO.getReceiverCity() + h5OrderVO.getReceiverDistrict() + h5OrderVO.getReceiverDetailAddress();
            appletOrder.setAddress(address);//订单详细地址
            appletOrder.setOrderSn(h5OrderVO.getOrderSn());
            appletOrder.setOrderId(h5OrderVO.getOrderId());
            appletOrder.setCompanionLevel(h5OrderVO.getCompanionLevel());
            appletOrder.setLongitude(Double.valueOf(h5OrderVO.getLongitude()));
            appletOrder.setLatitude(Double.valueOf(h5OrderVO.getLatitude()));

            appletOrder.setCreateType(appletOrder.getType());//开始接单类型
            appletOrder.setNewOrderTime(LocalDateTime.now());//最新派单时间

            if (h5OrderVO.getOldOrderId() != null && h5OrderVO.getOldOrderId() != 0){//修改订单
                appletOrderService.insertAppletOrder(appletOrder, false);
            }else {
                appletOrderService.insertAppletOrder(appletOrder, true);//需要短信
            }



//            //根据服务频率 服务日期 生成日订单
//            for (OmsOrderService service : h5OrderVO.getOrderServiceList()) {
//                AppletOrderItemDate appletOrderItemDate = new AppletOrderItemDate();
//
//                appletOrderItemDate.setOrderId(l);
//                appletOrderItemDate.setStatus(0);
//                appletOrderItemDate.setOrderServiceId(service.getId());
//                appletOrderItemDate.setServiceDate(service.getServiceDate());
//                appletOrderItemDate.setCityAddress(h5OrderVO.getReceiverProvince() + h5OrderVO.getReceiverCity() + h5OrderVO.getReceiverDistrict());
//                appletOrderItemDate.setAddress(h5OrderVO.getReceiverDetailAddress());
//                appletOrderItemDateService.insertAppletOrderItemDate(appletOrderItemDate);
//
//            }

        }else {
            //接单大厅接单
            acceptDispatchAll(h5OrderVO);
        }
        return AjaxResult.success();
    }


    //接单：没有找到对应人员进入接单大厅接单逻辑
    @Override
    public AjaxResult acceptDispatchAll(H5OrderVO h5OrderVO){
        //查询该订单是否已存在
        AppletOrder order = appletOrderService.selectAppletOrderByOrderId(h5OrderVO.getOrderId());
        if(order != null){
            log.error("该订单已存在，无需重复派单,order:{}",order);
            return  AjaxResult.error("该订单已存在，无需重复派单");
        }

        AppletOrder appletOrder = new AppletOrder();
        long l = System.currentTimeMillis();
        appletOrder.setId(l);
        appletOrder.setPayTime(LocalDateTime.now());
        appletOrder.setCreateTime(LocalDateTime.now());
        appletOrder.setType("0"); //系统派单


        //appletUserId 用json形式储存  == 》这个地方还需要调优
        AppUsers usersGo = new AppUsers();
        usersGo.setUserBcs(1);
        List<AppUsers> appUsers = appUsersService.selectAppUsersList(usersGo);
        //得到所有的伴宠师id
        String appletUserId = "";
        for (AppUsers users : appUsers) {
            appletUserId += users.getUserId()+",";
        }


        appletOrder.setOrderTime(3); //设置为三分钟
        appletOrder.setUserIdJson(appletUserId);
        appletOrder.setNum(1);
        appletOrder.setStatus(0); //派单中
        appletOrder.setPrice(h5OrderVO.getPayAmount());//订单支付金额：这个地方用来计算订单的佣金
        //详细地址通过拼接得到
        String address = h5OrderVO.getReceiverProvince() + h5OrderVO.getReceiverCity() + h5OrderVO.getReceiverDistrict() + h5OrderVO.getReceiverDetailAddress();
        appletOrder.setAddress(address);//订单详细地址
        appletOrder.setOrderSn(h5OrderVO.getOrderSn());
        appletOrder.setOrderId(h5OrderVO.getOrderId());
        appletOrder.setCompanionLevel(h5OrderVO.getCompanionLevel());
        appletOrder.setLongitude(Double.valueOf(h5OrderVO.getLongitude()));
        appletOrder.setLatitude(Double.valueOf(h5OrderVO.getLatitude()));

        appletOrder.setCreateType(appletOrder.getType());//开始接单类型
        appletOrder.setNewOrderTime(LocalDateTime.now());//最新派单时间


        if (h5OrderVO.getOldOrderId() != null && h5OrderVO.getOldOrderId() != 0){//修改订单
            appletOrderService.insertAppletOrder(appletOrder, false);
        }else {
            appletOrderService.insertAppletOrder(appletOrder, true);//需要短信
        }


//        //根据服务频率 服务日期 生成日订单
//        for (OmsOrderService service : h5OrderVO.getOrderServiceList()) {
//            AppletOrderItemDate appletOrderItemDate = new AppletOrderItemDate();
//
//            appletOrderItemDate.setOrderId(l);
//            appletOrderItemDate.setStatus(0);
//            appletOrderItemDate.setOrderServiceId(service.getId());
//            appletOrderItemDate.setServiceDate(service.getServiceDate());
//            appletOrderItemDate.setCityAddress(h5OrderVO.getReceiverProvince() + h5OrderVO.getReceiverCity() + h5OrderVO.getReceiverDistrict());
//            appletOrderItemDate.setAddress(h5OrderVO.getReceiverDetailAddress());
//            appletOrderItemDateService.insertAppletOrderItemDate(appletOrderItemDate);
//
//        }


        return AjaxResult.success();
    }



    //系统派单逻辑

    public String acceptDispatch(AppletOrder order) {
        //得到关联的订单标识
        Long orderId = order.getOrderId();
        //获取经纬度
        H5OrderVO h5OrderVO = orderMapper.selectOrderDetail(orderId);
        log.info("订单数据:{}",h5OrderVO);

        //TODO 系统派单逻辑 acceptDispatch

        // 获取经度
        String longitudeStr = h5OrderVO.getLongitude();
        longitudeStr = "112.89175415039062";
        // 获取纬度
        String latitudeStr = h5OrderVO.getLatitude();
        latitudeStr = "28.18972396850586";

        // 转换为double
        double longitude = Double.parseDouble(longitudeStr);
        double latitude = Double.parseDouble(latitudeStr);

        // 查询所有地址（或添加基本筛选条件减少数据量）
        List<AppletAddress> allAddresses = appletAddressService.selectAppletAddressList(new AppletAddress());

        // 筛选15公里内的地址
        List<AppletAddress> nearbyAddresses = allAddresses.stream()
                .filter(address -> {
                    double addrLon = Double.parseDouble(address.getLongitude());
                    double addrLat = Double.parseDouble(address.getLatitude());
                    return calculateDistance(latitude, longitude, addrLat, addrLon) <= 15;
                })
                .collect(Collectors.toList());
        //如果15公里范围内没有伴宠师
        if (nearbyAddresses.isEmpty()) {
            //短信提醒
            AliyunSmsUtils util = new AliyunSmsUtils(smsProperties);
            util.sendBcshHasOrderSMS("17674618290");
            return "no_teacher";
        }



        return "success";
    }


    // 计算两个经纬度之间的距离（单位：公里）
    private double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        final int R = 6371;



        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);
        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return R * c;
    }




}
