package com.tourism.webadmin.app.wechat.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.lang.Snowflake;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.page.PageMethod;
import com.tourism.common.additional.utils.StringUtils;
import com.tourism.common.core.annotation.DisableDataFilter;
import com.tourism.common.core.annotation.MyRequestBody;
import com.tourism.common.core.constant.ErrorCodeEnum;
import com.tourism.common.core.object.*;
import com.tourism.common.core.util.MathCalculateUtils;
import com.tourism.common.core.util.MyCommonUtil;
import com.tourism.common.core.util.MyModelUtil;
import com.tourism.common.core.util.MyPageUtil;
import com.tourism.webadmin.back.dto.DeliveryOrderDto;
import com.tourism.webadmin.back.dto.DeliveryOrderItemsDto;
import com.tourism.webadmin.back.dto.DeliveryOrderWebDto;
import com.tourism.webadmin.back.model.DeliveryOrder;
import com.tourism.webadmin.back.model.DeliveryOrderItems;
import com.tourism.webadmin.back.service.DeliveryOrderItemsService;
import com.tourism.webadmin.back.service.DeliveryOrderService;
import com.tourism.webadmin.back.vo.DeliveryOrderItemsVo;
import com.tourism.webadmin.back.vo.DeliveryOrderVo;
import com.tourism.common.additional.config.ApplicationConfig;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.junit.Ignore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@Tag(name = "外卖订单接口")
@Slf4j
@RestController
@DisableDataFilter
@RequestMapping("/wechat/delivery/order")
//@SaIgnore
public class WechatDeliveryOrderController {

    @Autowired
    private ApplicationConfig appConfig;
    @Autowired
    private DeliveryOrderService deliveryOrderService;
    @Autowired
    private DeliveryOrderItemsService deliveryOrderItemsService;
    /**
     * 创建订单
     */
//    @SaIgnore
    @PostMapping("/createOrder")
    public ResponseResult<String> createOrder(@MyRequestBody DeliveryOrderDto deliveryOrderDto,
                              @MyRequestBody List<DeliveryOrderItemsDto> deliveryOrderItemsDtoList) {
        ResponseResult<Tuple2<DeliveryOrder, JSONObject>> verifyResult =
                this.doBusinessDataVerifyAndConvert(deliveryOrderDto, false, deliveryOrderItemsDtoList);
        if (!verifyResult.isSuccess()) {
            return ResponseResult.errorFrom(verifyResult);
        }
        Tuple2<DeliveryOrder, JSONObject> bizData = verifyResult.getData();
        DeliveryOrder deliveryOrder = bizData.getFirst();
        deliveryOrder.setOrderNo(deliveryOrder.getId());
        deliveryOrder = deliveryOrderService.saveNewWithRelation(deliveryOrder, bizData.getSecond());
        return ResponseResult.success(deliveryOrder.getId().toString());
    }

    /**
     * 订单列表
     */
//    @SaIgnore
    @GetMapping("/orderList")
    @DisableDataFilter
    public ResponseResult<MyPageData<DeliveryOrderVo>> orderList(DeliveryOrderWebDto deliveryOrderDtoFilter) {
        if (deliveryOrderDtoFilter != null) {
            PageMethod.startPage(deliveryOrderDtoFilter.getPageNum(), deliveryOrderDtoFilter.getPageSize(), true);
        }
        DeliveryOrder deliveryOrderFilter = MyModelUtil.copyTo(deliveryOrderDtoFilter, DeliveryOrder.class);
        Long userId = TokenData.takeFromRequest().getUserId();
        deliveryOrderFilter.setCreateUserId(userId);
//        String orderBy = MyOrderParam.buildOrderBy(orderParam, DeliveryOrder.class);
        List<DeliveryOrder> deliveryOrderList =
                deliveryOrderService.getDeliveryOrderListWithRelation(deliveryOrderFilter, "create_time desc");
        deliveryOrderService.maskFieldDataList(deliveryOrderList, null);

        //查询订单详情
        if (!deliveryOrderList.isEmpty()) {
            Set<String> orderIds = deliveryOrderList.stream().map(e -> e.getId()).collect(Collectors.toSet());
            List<DeliveryOrderItems> items = deliveryOrderItemsService.getDeliveryOrderItemsVoList(orderIds);
            List<DeliveryOrderItemsVo> deliveryOrderItemsVos = MyModelUtil.copyCollectionTo(items, DeliveryOrderItemsVo.class);
            //做成map，方便匹配
            Map<String, List<DeliveryOrderItemsVo>> collect1 = deliveryOrderItemsVos.stream().collect(Collectors.groupingBy(DeliveryOrderItemsVo::getOrderId));
            MyPageData<DeliveryOrderVo> pageData = MyPageUtil.makeResponseData(deliveryOrderList, DeliveryOrderVo.class);
            pageData.getDataList().forEach(e -> {
                e.setItemList(collect1.get(e.getId()));
            });
            List<DeliveryOrderVo> dataList = pageData.getDataList();
            dataList.sort(new Comparator<DeliveryOrderVo>() {
                @Override
                public int compare(DeliveryOrderVo o1, DeliveryOrderVo o2) {
                    int compareTo = o2.getCreateTime().compareTo(o1.getCreateTime());
                    return compareTo;
                }
            });
            pageData.setDataList(dataList);
            return ResponseResult.success(pageData);

        }
        MyPageData<DeliveryOrderVo> pageData = new MyPageData<>();
        pageData.setDataList(new ArrayList<>());
        pageData.setTotalCount(0l);
        return ResponseResult.success(pageData);
    }

    /**
     * 订单详情
     */
//    @SaIgnore
    @RequestMapping("/orderDetail")
    public ResponseResult<DeliveryOrderVo> orderDetail(@RequestParam String id) {
        DeliveryOrder deliveryOrder = deliveryOrderService.getByIdWithRelation(id, MyRelationParam.full());
        if (deliveryOrder == null) {
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
        }
        deliveryOrderService.maskFieldData(deliveryOrder, null);
        DeliveryOrderVo deliveryOrderVo = MyModelUtil.copyTo(deliveryOrder, DeliveryOrderVo.class);
        DeliveryOrderItems build = DeliveryOrderItems.builder().orderId(deliveryOrderVo.getId()).build();
        List<DeliveryOrderItems> items = deliveryOrderItemsService.getDeliveryOrderItemsList(build, "create_time");
        //items转为vo
        deliveryOrderVo.setItemList(MyModelUtil.copyCollectionTo(items, DeliveryOrderItemsVo.class));
        return ResponseResult.success(deliveryOrderVo);
    }

    /**
     * 计算两个经纬度直接距离
     * @param initLongitude 初始点位经度
     * @param initLatitude 初始点位纬度
     * @param lastLongitude 目标点经度
     * @param lastLatitude 目标点纬度
     * @return
     * @throws Exception
     */
    @RequestMapping("/getCalculatedDistance")
    @SaIgnore
    public ResponseResult<String> getCalculatedDistance(@RequestParam("initLongitude") String initLongitude,
                                                        @RequestParam("initLatitude") String initLatitude,
                                                        @RequestParam("lastLongitude") String lastLongitude,
                                                        @RequestParam("lastLatitude") String lastLatitude
    ) throws Exception {
        if (StringUtils.isBlank(initLongitude) || StringUtils.isBlank(initLatitude) || StringUtils.isBlank(lastLongitude)) {
            throw new Exception("起始经纬度或目标经纬度有一个为空！！！");
        }
       Double v = MathCalculateUtils.calculateDistance(Double.parseDouble(initLongitude), Double.parseDouble(initLatitude), Double.parseDouble(lastLongitude), Double.parseDouble(lastLatitude));
        return ResponseResult.success(v.toString());
    }
    private ResponseResult<Tuple2<DeliveryOrder, JSONObject>> doBusinessDataVerifyAndConvert(
            DeliveryOrderDto deliveryOrderDto,
            boolean forUpdate,
            List<DeliveryOrderItemsDto> deliveryOrderItemsDtoList) {
        ErrorCodeEnum errorCode = ErrorCodeEnum.DATA_VALIDATED_FAILED;
        String errorMessage = MyCommonUtil.getModelValidationError(deliveryOrderDto, false);
        if (errorMessage != null) {
            return ResponseResult.error(errorCode, errorMessage);
        }
        errorMessage = MyCommonUtil.getModelValidationError(deliveryOrderItemsDtoList);
        if (errorMessage != null) {
            return ResponseResult.error(errorCode, "参数 [deliveryOrderItemsDtoList] " + errorMessage);
        }
        // 全部关联从表数据的验证和转换
        JSONObject relationData = new JSONObject();
        CallResult verifyResult;
        // 下面是输入参数中，主表关联数据的验证。
        DeliveryOrder deliveryOrder = MyModelUtil.copyTo(deliveryOrderDto, DeliveryOrder.class);
        DeliveryOrder originalData;
        if (forUpdate && deliveryOrder != null) {
            originalData = deliveryOrderService.getById(deliveryOrder.getId());
            if (originalData == null) {
                return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
            }
            relationData.put("originalData", originalData);
        }
        // 处理主表的一对多关联 [DeliveryOrderItems]
        List<DeliveryOrderItems> deliveryOrderItemsList =
                MyModelUtil.copyCollectionTo(deliveryOrderItemsDtoList, DeliveryOrderItems.class);
        relationData.put("deliveryOrderItemsList", deliveryOrderItemsList);
        return ResponseResult.success(new Tuple2<>(deliveryOrder, relationData));
    }

}
