/*
 * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.api.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.yami.shop.bean.app.dto.*;
import com.yami.shop.bean.enums.OrderStatus;
import com.yami.shop.bean.enums.RefundStatusEnum;
import com.yami.shop.bean.enums.RefundType;
import com.yami.shop.bean.model.*;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.dao.PointsRecordMapper;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.security.comment.dao.AppConnectMapper;
import com.yami.shop.security.comment.model.AppConnect;
import com.yami.shop.service.*;
import com.yami.shop.service.hb.IHBOrderService;
import com.yami.shop.utils.CullenUtils;
import com.yami.shop.wx.po.TraceWaybill;
import com.yami.shop.wx.po.TraceWaybillDetail;
import com.yami.shop.wx.po.TraceWaybillGoodsInfo;
import com.yami.shop.wx.service.impl.WxProviderServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("/p/myOrder")
//@RequestMapping("/myOrder")
@Api(tags = "我的订单接口")
@AllArgsConstructor
public class MyOrderController {

    private final OrderService orderService;
    private final MapperFacade mapperFacade;
    private final UserAddrOrderService userAddrOrderService;
    private final ProductService productService;
    private final SkuService skuService;
    private final ShopConfig shopConfig;
    private final MyOrderService myOrderService;
    private final ShopDetailService shopDetailService;
    private final OrderItemService orderItemService;
    private final IHBOrderService ihbOrderService;
    private final OrderRefundService orderRefundService;
    private final PointsRecordMapper pointsRecordMapper;
    private final OrderSettlementService orderSettlementService;
    private final AppConnectMapper appConnectMapper;
    private final DeliveryService deliveryService;


    @SuppressWarnings("all")
    @GetMapping("/queryTrace")
    @ApiOperation(value = "微信物流-queryTrace")
    public ResponseEntity<String> queryTrace(@RequestParam(value = "waybillToken") String waybillToken) {
        CullenUtils.validateDataThrowException(waybillToken==null,"waybillToken不能为空...");
        return ResponseEntity.ok(WxProviderServiceImpl.queryTrace(waybillToken));
    }

    @SuppressWarnings("all")
    @GetMapping("/getWaybillToken")
    @ApiOperation(value = "微信物流-获取waybill_token")
    public ResponseEntity<String> getWaybillToken(@RequestParam(value = "orderNumber") String orderNumber) {
        CullenUtils.validateDataThrowException(orderNumber==null,"订单号不能为空...");
        Order order = orderService.getOrderByOrderNumber(orderNumber);
        CullenUtils.validateDataThrowException(order==null,"订单不存在...");
        CullenUtils.validateDataThrowException(order.getDvyId()==null,"订单未发货...");
        AppConnect connect = appConnectMapper.getByUserId(SecurityUtils.getUser().getUserId(), 1);
        CullenUtils.validateDataThrowException(connect==null,"openid不存在...");
        UserAddrOrder userAddrOrder = userAddrOrderService.getById(order.getAddrOrderId());
        CullenUtils.validateDataThrowException(userAddrOrder==null,"收货地址不存在...");
        Delivery delivery = deliveryService.getById(order.getDvyId());
        CullenUtils.validateDataThrowException(delivery==null,"物流信息不存在...");
        List<OrderItem> orderItemList = orderItemService.getOrderItemsByOrderNumber(orderNumber);
        CullenUtils.validateDataThrowException(orderItemList.isEmpty(),"订单项不存在...");
        OrderSettlement settlement = orderSettlementService.getOne(new LambdaQueryWrapper<OrderSettlement>().eq(OrderSettlement::getOrderNumber, orderNumber));
        CullenUtils.validateDataThrowException(settlement==null,"订单结算不存在...");
        TraceWaybill traceWaybill = new TraceWaybill();
        traceWaybill.setOpenid(connect.getBizUserId());
        traceWaybill.setReceiverPhone(userAddrOrder.getMobile());
        traceWaybill.setDeliveryId(delivery.getDvyNo());
        traceWaybill.setWaybillId(order.getDvyFlowId());
        List<TraceWaybillGoodsInfo> goodsInfoList = Lists.newArrayList();
        orderItemList.forEach(item -> goodsInfoList.add(new TraceWaybillGoodsInfo(item.getProdName(),item.getPic())));
        traceWaybill.setGoodsInfo(new TraceWaybillDetail(goodsInfoList));
        traceWaybill.setTransId(settlement.getBizPayNo());
        return ResponseEntity.ok(WxProviderServiceImpl.traceWaybill(traceWaybill));
    }


    /**
     * 订单详情信息接口
     */
    @GetMapping("/orderDetail")
    @ApiOperation(value = "订单详情信息", notes = "根据订单号获取订单详情信息")
    @ApiImplicitParam(name = "orderNumber", value = "订单号", required = true, dataType = "String")
    public ResponseEntity<OrderShopDto> orderDetail(@RequestParam(value = "orderNumber", required = true) String orderNumber) {
        String userId = SecurityUtils.getUser().getUserId();
        OrderShopDto orderShopDto = new OrderShopDto();

        Order order = orderService.getOrderByOrderNumberAndUserId(orderNumber, userId, true);
        SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日$HH:mm");
        if (null != order.getPayTime()) {
            // 转换为 LocalDateTime 并增加 1 小时
            LocalDateTime delayedTime = order.getPayTime().toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime()
                    .plusHours(1);
            // 转换回 Date 类型
            Date delayedDate = Date.from(delayedTime.atZone(ZoneId.systemDefault()).toInstant());

            // 格式化延迟后的时间
            String format = sdf.format(delayedDate);
            String[] split = format.split("\\$");
            orderShopDto.setEstimatedTimeStr(split[0]);
            orderShopDto.setEstimatedTime(split[1]);
        }
        ShopDetail shopDetail;
        if (Objects.equals(order.getShopId(), Constant.PLATFORM_SHOP_ID)) {
            shopDetail = new ShopDetail();
            shopDetail.setShopName(Constant.PLATFORM_SHOP_NAME);
        } else {
            shopDetail = shopDetailService.getShopDetailByShopId(order.getShopId());
        }
        UserAddrOrder userAddrOrder = userAddrOrderService.getById(order.getAddrOrderId());

        UserAddrDto userAddrDto = mapperFacade.map(userAddrOrder, UserAddrDto.class);
        List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderNumber);

        //计算订单使用积分
        Integer score = 0;
        List<OrderItemDto> orderItemDtoList = mapperFacade.mapAsList(orderItems, OrderItemDto.class);
        //加上运费
        orderShopDto.setOrderScore(score);
        orderShopDto.setShopId(shopDetail.getShopId());
        orderShopDto.setDvyType(order.getDvyType());
        orderShopDto.setShopName(shopDetail.getShopName());
        orderShopDto.setActualTotal(order.getActualTotal());
        orderShopDto.setUserAddrDto(userAddrDto);
        orderShopDto.setPayType(order.getPayType());
        orderShopDto.setTransfee(order.getFreightAmount());
//        Math.abs
        Long l = pointsRecordMapper.statisticsPoint(userId, order.getChannelId());
        //当前剩余总可用的积分
        orderShopDto.setTotalAvailableScore(l);
        if (null != order.getOffsetPoints()) {
            //当前订单抵扣的积分转换成钱
            orderShopDto.setReduceAmount(Arith.div(Double.valueOf(order.getOffsetPoints()), 100));
            //当前订单使用了多少积分
            orderShopDto.setTotalUsableScore(Double.valueOf(order.getOffsetPoints()));
        }
        orderShopDto.setCreateTime(order.getCreateTime());
        orderShopDto.setRemarks(order.getRemarks());
        orderShopDto.setOrderType(order.getOrderType());
        orderShopDto.setStatus(order.getHbOrderStatus());
        // 付款时间
        orderShopDto.setPayTime(order.getPayTime());
        // 发货时间
        orderShopDto.setDvyTime(order.getDvyTime());
        // 完成时间
        orderShopDto.setFianllyTime(order.getFinallyTime());
        // 取消时间
        orderShopDto.setCancelTime(order.getCancelTime());
        orderShopDto.setCancelReason(order.getCancelReason());
        // 更新时间
        orderShopDto.setUpdateTime(order.getUpdateTime());

        List<OrderRefund> orderRefunds = orderRefundService.getProcessingOrderRefundByOrderId(order.getOrderId());

        // 可以退款的状态，并在退款时间内
        if (order.getHbOrderStatus() > OrderStatus.UNPAY.value() && order.getHbOrderStatus() < OrderStatus.CLOSE.value() && orderRefundService.checkRefundDate(order)) {
            orderShopDto.setCanRefund(true);
            // 有没有正在退款中的订单
            if (CollectionUtil.isEmpty(orderRefunds)) {
                orderShopDto.setCanAllRefund(true);
            }
        }

        for (OrderRefund orderRefund : orderRefunds) {

            // 整单退款
            if (Objects.equals(RefundType.ALL.value(), orderRefund.getRefundType())) {
                orderShopDto.setCanRefund(false);
                // 统一的退款单号
                for (OrderItemDto orderItemDto : orderItemDtoList) {
                    orderItemDto.setRefundSn(orderRefund.getRefundSn());
                }
                break;
            }
            // 单项退款，每个单号都不一样
            for (OrderItemDto orderItemDto : orderItemDtoList) {
                if (Objects.equals(orderItemDto.getOrderItemId(), orderRefund.getOrderItemId())) {
                    orderItemDto.setRefundSn(orderRefund.getRefundSn());

                }
            }
        }

        orderShopDto.setOrderItemDtos(orderItemDtoList);
        double total = 0.0;
        Integer totalNum = 0;
        for (OrderItemDto orderItem : orderShopDto.getOrderItemDtos()) {
            total = Arith.add(total, orderItem.getProductTotalAmount());
            totalNum += orderItem.getProdCount();
            orderItem.setRefundCount(orderItemService.refundCount(orderItem.getOrderItemId()));
        }
        orderShopDto.setTotal(total);
        orderShopDto.setTotalNum(totalNum);
        orderShopDto.setCommSts(order.getCommSts());
        orderShopDto.setDvyFlowId(order.getDvyFlowId());
        Delivery delivery = deliveryService.getById(order.getDvyId());
        if (delivery!=null){
            orderShopDto.setDvyName(delivery.getDvyName());
        }
        return ResponseEntity.ok(orderShopDto);
    }


    /**
     * 订单列表接口
     */
    @GetMapping("/myOrder")
    @ApiOperation(value = "订单列表信息", notes = "根据订单状态获取订单列表信息，状态为0时获取所有订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "status", value = "订单状态 1:待付款 2:待发货 3:待收货 4:待评价 5:成功 6:失败", required = false, dataType = "Integer"),
    })
    public ResponseEntity<IPage<MyOrderDto>> myOrder(@ModelAttribute PageParam<MyOrderDto> page,
                                                     @RequestParam(value = "status", required = false) Integer status,
                                                     @RequestParam(value = "dvyType", required = false) Integer dvyType
    ) {
        String userId = SecurityUtils.getUser().getUserId();
        IPage<MyOrderDto> myOrderDtoIpage = myOrderService.pageMyOrderByUserIdAndStatus(page, userId, status, dvyType);
        return ResponseEntity.ok(myOrderDtoIpage);
    }

    /**
     * 获取订单项信息
     */
    @GetMapping("/getOrderItem")
    public ResponseEntity<OrderItem> getOrderItem(@RequestParam(value = "orderItemId") Long orderItemId) {
        String imgDomainName = shopConfig.getDomain().getResourcesDomainName();
        OrderItem orderItem = orderItemService.getById(orderItemId);
        orderItem.setPic(orderItem.getPic() != null ? imgDomainName + "/" + orderItem.getPic() : null);
        return ResponseEntity.ok(orderItem);
    }

    /**
     * 获取订单项信息
     */
    @GetMapping("/getOrderItems")
    public ResponseEntity<List<OrderItem>> getOrderItems(@RequestParam(value = "orderNumber") Long orderNumber) {
        String imgDomainName = shopConfig.getDomain().getResourcesDomainName();
        List<OrderItem> orderItems = orderItemService.list(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderNumber, orderNumber));
        for (OrderItem orderItem : orderItems) {
            orderItem.setPic(orderItem.getPic() != null ? imgDomainName + "/" + orderItem.getPic() : null);
        }
        return ResponseEntity.ok(orderItems);
    }

    /**
     * 订单评价列表接口
     */
    @GetMapping("/myOrderComment")
    @ApiOperation(value = "订单评价列表接口", notes = "根据订单评价状态获取订单列表信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "commStatus", value = "订单状态 0:待评价 1已评价", required = false, dataType = "Integer")
    })
    public ResponseEntity<IPage<MyOrderDto>> myOrderComment(@RequestParam(value = "commStatus") Integer commStatus, PageParam<MyOrderDto> page) {
        String userId = SecurityUtils.getUser().getUserId();
        IPage<MyOrderDto> myOrderDtoIpage = myOrderService.myOrderComment(page, userId, commStatus);
        return ResponseEntity.ok(myOrderDtoIpage);
    }

    /**
     * 订单项评价列表接口
     */
    @GetMapping("/myOrderItemsComment")
    @ApiOperation(value = "订单项评价列表接口", notes = "根据订单评价状态获取订单列表信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "commStatus", value = "订单状态 0:待评价 1已评价", required = false, dataType = "Integer")
    })
    public ResponseEntity<IPage<MyOrderItemDto>> myOrderItemsComment(@RequestParam(value = "commStatus") Integer commStatus, PageParam<MyOrderItemDto> page) {
        String userId = SecurityUtils.getUser().getUserId();
        IPage<MyOrderItemDto> myOrderDtoIpage = myOrderService.myOrderItemsComment(page, userId, commStatus);
        return ResponseEntity.ok(myOrderDtoIpage);
    }

    /**
     * 订单列表查询接口
     */
    @GetMapping("/myOrderSearch")
    @ApiOperation(value = "订单列表信息查询", notes = "根据订单编号或者订单中商品名称搜索")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "status", value = "订单状态 1:待付款 2:待发货 3:待收货 4:待评价 5:成功 6:失败", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "orderName", value = "订单编号或者订单中商品名称", required = false, dataType = "String"),
            @ApiImplicitParam(name = "orderTimeStatus", value = "0全部订单 1最近七天 2最近三个月 3三个月之前 订单", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "orderType", value = "0全部订单 1拼团订单 2秒杀订单 3普通订单", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "orderNumber", value = "订单编号", required = false, dataType = "String")
    })
    public ResponseEntity<IPage<MyOrderDto>> myOrderSearch(@RequestParam(value = "status") Integer status,
                                                           @RequestParam(value = "orderName") String orderName,
                                                           @RequestParam(value = "orderTimeStatus") Integer orderTimeStatus,
                                                           @RequestParam(value = "orderType") Integer orderType,
                                                           @RequestParam(value = "orderNumber") String orderNumber,
                                                           PageParam<MyOrderDto> page) {
        String userId = SecurityUtils.getUser().getUserId();
        IPage<MyOrderDto> myOrderDtoIpage = myOrderService.pageMyOrderByParams(page, userId, status, orderName, orderTimeStatus, orderType, orderNumber);
        return ResponseEntity.ok(myOrderDtoIpage);
    }


    /**
     * 取消订单
     */
    @PutMapping("/cancel/{orderNumber}")
    @ApiOperation(value = "根据订单号取消订单", notes = "根据订单号取消订单")
    @ApiImplicitParam(name = "orderNumber", value = "订单号", required = true, dataType = "String")
    public ResponseEntity<String> cancel(@PathVariable("orderNumber") String orderNumber) {
        String userId = SecurityUtils.getUser().getUserId();
        Order order = orderService.getOrderByOrderNumberAndUserId(orderNumber, userId, true);
        if (!Objects.equals(order.getHbOrderStatus(), OrderStatus.UNPAY.value())) {
            throw new GlobalException("订单已支付，无法取消订单");
        }
        List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderNumber);
        order.setOrderItems(orderItems);
        // 取消订单
        orderService.cancelOrders(Collections.singletonList(order),"用户主动取消");
        // 清除缓存
        for (OrderItem orderItem : orderItems) {
            productService.removeProductCacheByProdId(orderItem.getProdId());
            skuService.removeSkuCacheBySkuId(orderItem.getSkuId(), orderItem.getProdId());
        }
        return ResponseEntity.ok().build();
    }


    /**
     * 确认收货
     */
    @PutMapping("/receipt/{orderNumber}")
    @ApiOperation(value = "根据订单号确认收货", notes = "根据订单号确认收货")
    public ResponseEntity<String> receipt(@PathVariable("orderNumber") String orderNumber) {
        String userId = SecurityUtils.getUser().getUserId();
//        String userId = "36726893042d492aba446439c5f00584";
        Order order = orderService.getOrderByOrderNumberAndUserId(orderNumber, userId, true);
        if (Objects.equals(order.getDvyType(), 1)) {
            CullenUtils.validateDataThrowException(Objects.equals(order.getHbOrderStatus(), 0), "订单未支付");
            CullenUtils.validateDataThrowException(Objects.equals(order.getHbOrderStatus(), 1), "订单未发货，无法确认收货");
        } else {
            if (!Objects.equals(order.getHbOrderStatus(), OrderStatus.CONSIGNMENT.value())) {
                throw new GlobalException("订单未发货，无法确认收货");
            }
            if (Objects.equals(order.getRefundStatus(), RefundStatusEnum.APPLY.value())) {
                throw new GlobalException("订单退款中，无法确认收货");
            }
        }

        List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderNumber);
        order.setOrderItems(orderItems);
        // 确认收货
        orderService.receiptOrder(Collections.singletonList(order));

        //海博订单完成
        ihbOrderService.changeOrderStatus(order.getOrderNumber(), OrderStatus.SUCCESS.value());

        return ResponseEntity.ok().build();
    }

    /**
     * 删除订单
     */
    @DeleteMapping("/{orderNumber}")
    @ApiOperation(value = "根据订单号删除订单", notes = "根据订单号删除订单")
    @ApiImplicitParam(name = "orderNumber", value = "订单号", required = true, dataType = "String")
    public ResponseEntity<String> delete(@PathVariable("orderNumber") String orderNumber) {
        String userId = SecurityUtils.getUser().getUserId();

        Order order = orderService.getOrderByOrderNumberAndUserId(orderNumber, userId, true);

//        if (!Objects.equals(order.getHbOrderStatus(), OrderStatus.SUCCESS.value()) && !Objects.equals(order.getHbOrderStatus(), OrderStatus.CLOSE.value())) {
//            throw new GlobalException("订单未完成或未关闭，无法删除订单");
//        }
        if (!Objects.equals(order.getHbOrderStatus(), OrderStatus.CLOSE.value())) {
            throw new GlobalException("订单未取消，无法删除订单");
        }

        // 删除订单
        orderService.deleteOrders(Collections.singletonList(order));

        return ResponseEntity.ok("删除成功");
    }


//    /**
//     * 获取我的订单订单数量
//     */
//    @GetMapping("/orderCount")
//    @ApiOperation(value = "获取我的订单订单数量", notes = "获取我的订单订单数量")
//    public ResponseEntity<OrderCountData> getOrderCount() {
//        String userId = SecurityUtils.getUser().getUserId();
//        OrderCountData orderCountMap = orderService.getOrderCount(userId);
//        return ResponseEntity.ok(orderCountMap);
//    }


}
