package cn.newfeifan.mall.module.trade.controller.app.order;

import cn.newfeifan.mall.framework.common.pojo.CommonResult;
import cn.newfeifan.mall.framework.common.pojo.PageResult;
import cn.newfeifan.mall.framework.security.core.annotations.PreAuthenticated;
import cn.newfeifan.mall.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
import cn.newfeifan.mall.module.pay.controller.admin.order.vo.PayOrderRespVO;
import cn.newfeifan.mall.module.pay.convert.order.PayOrderConvert;
import cn.newfeifan.mall.module.pay.dal.dataobject.order.PayOrderDO;
import cn.newfeifan.mall.module.pay.dal.mysql.order.PayOrderMapper;
import cn.newfeifan.mall.module.pay.enums.order.PayOrderStatusEnum;
import cn.newfeifan.mall.module.pay.service.fuyouorder.FuYouPayOrderService;
import cn.newfeifan.mall.module.pay.service.order.PayOrderService;
import cn.newfeifan.mall.module.trade.controller.app.order.vo.*;
import cn.newfeifan.mall.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
import cn.newfeifan.mall.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
import cn.newfeifan.mall.module.trade.convert.order.TradeOrderConvert;
import cn.newfeifan.mall.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
import cn.newfeifan.mall.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.newfeifan.mall.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.newfeifan.mall.module.trade.enums.order.TradeOrderStatusEnum;
import cn.newfeifan.mall.module.trade.framework.order.config.TradeOrderProperties;
import cn.newfeifan.mall.module.trade.service.aftersale.AfterSaleService;
import cn.newfeifan.mall.module.trade.service.delivery.DeliveryExpressService;
import cn.newfeifan.mall.module.trade.service.order.TradeOrderQueryService;
import cn.newfeifan.mall.module.trade.service.order.TradeOrderUpdateService;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;

import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.newfeifan.mall.framework.common.pojo.CommonResult.success;
import static cn.newfeifan.mall.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.newfeifan.mall.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.newfeifan.mall.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND;

@Tag(name = "用户 App - 交易订单")
@RestController
@RequestMapping("/trade/order")
@Validated
@Slf4j
public class AppTradeOrderController {

    @Resource
    private TradeOrderUpdateService tradeOrderUpdateService;
    @Resource
    private TradeOrderQueryService tradeOrderQueryService;
    @Resource
    private DeliveryExpressService deliveryExpressService;

    @Resource
    private AfterSaleService afterSaleService;

    @Resource
    private TradeOrderProperties tradeOrderProperties;

    //add by Ben
    @Resource
    private PayOrderMapper payOrderMapper;
    //add by Ben
    @Resource
    private PayOrderService payOrderService;

    @Resource
    private FuYouPayOrderService fuYouPayOrderService;

    @GetMapping("/getPayOrderByStatus2")
    @Operation(summary = "获得支付订单2")
    @Parameter(name = "id", description = "支付订单编号", required = true, example = "1024")
    public CommonResult<PayOrderRespVO> getPayOrderByStatus2(@RequestParam("id") Long id) {
        log.info("getPayOrderByStatus2:=========id:{}",id);
        PayOrderDO oldPayOrderDO = payOrderMapper.selectById(id);
        log.info("getPayOrderByStatus2:oldPayOrderDO===========:{}",oldPayOrderDO);
        PayOrderDO newPayOrderDO = payOrderService.getOrderByStatus(oldPayOrderDO);

        return getPayOrderRespVOCommonResult(id, newPayOrderDO, oldPayOrderDO);
    }

    @GetMapping("/getPayOrderByStatus3")
    @Operation(summary = "获得支付订单2")
    @Parameter(name = "id", description = "支付订单编号", required = true, example = "1024")
    public CommonResult<PayOrderRespVO> getPayOrderByStatus3(@RequestParam("id") Long id) {
        log.info("getPayOrderByStatus3:=========id:{}",id);
        return null;
    }

    @PostMapping("/getFuYouPayOrderByStatus")
    @Operation(summary = "查询富友支付订单状态")
    @Parameter(name = "payOrderNo", description = "支付订单编号", required = true, example = "16103-202407151500201")
    public CommonResult<PayOrderRespVO> getFuYouPayOrderByStatus(@RequestParam("payOrderNo") String payOrderNo) {
        log.info("getPayOrderByStatus2:=========id:{}",payOrderNo);
        PayOrderDO oldPayOrderDO = payOrderMapper.selectByPayOrderNo(payOrderNo);

        // 若查无此订单
        if(oldPayOrderDO == null){
            throw exception(PAY_ORDER_NOT_FOUND);
        }

        PayOrderDO newPayOrderDO = fuYouPayOrderService.getPayOrderByStatus(oldPayOrderDO);

        return getPayOrderRespVOCommonResult(oldPayOrderDO.getId(), newPayOrderDO, oldPayOrderDO);
    }

    @NotNull
    private CommonResult<PayOrderRespVO> getPayOrderRespVOCommonResult(Long id, PayOrderDO newPayOrderDO, PayOrderDO oldPayOrderDO) {
        CommonResult<PayOrderRespVO> success = success(PayOrderConvert.INSTANCE.convert(newPayOrderDO));

        //如果在上一行代码，把支付订单状态从“待支付”，改为“已支付”，则证明订单支付成功，则改trade_order表状态为待发货，并且分配积分
        if(oldPayOrderDO.getStatus().equals(PayOrderStatusEnum.WAITING.getStatus())
                &&
                newPayOrderDO.getStatus().equals(PayOrderStatusEnum.SUCCESS.getStatus())
        )
        {
            //只有支付订单id参数payOrderId是有用的。
            List list = tradeOrderUpdateService.updateOrderPaid(id);
            Object jfObj = list.get(0);
            Object sjObj = list.get(1);

            Long jf = (Long)jfObj;//待确权积分
            Double sj = (Double)sjObj;//待确权身价

            success.getData().setJf(jf);
            success.getData().setSj(sj);
        }

        log.info("getPayOrderByStatus2:success===========:{}",success);
        return success;
    }


    /**
     * add by Ben
     * 待支付订单，点支付时的新增方法
     * @param tradeOrderId 订单id
     * @return 支付订单
     */
    @GetMapping("/getPayOrder")
    @Operation(summary = "获得待支付列表的待支付订单")
    @Parameter(name = "tradeOrderId", description = "订单编号", required = true, example = "102")
    public CommonResult<PayOrderRespVO> getPayOrder(@RequestParam("tradeOrderId") Long tradeOrderId) {

        PayOrderDO payOrder = tradeOrderUpdateService.getPayOrder(tradeOrderId);

        return success(PayOrderConvert.INSTANCE.convert(payOrder));
    }

    @GetMapping("/settlement")
    @Operation(summary = "获得订单结算信息")
    @PreAuthenticated
    public CommonResult<AppTradeOrderSettlementRespVO> settlementOrder(@Valid AppTradeOrderSettlementReqVO settlementReqVO) {
        return success(tradeOrderUpdateService.settlementOrder(getLoginUserId(), settlementReqVO));
    }

    @PostMapping("/create")
    @Operation(summary = "创建订单")
    @PreAuthenticated
    public CommonResult<AppTradeOrderCreateRespVO> createOrder(@Valid @RequestBody AppTradeOrderCreateReqVO createReqVO) {
        TradeOrderDO order = tradeOrderUpdateService.createOrder(getLoginUserId(), createReqVO);
        return success(new AppTradeOrderCreateRespVO().setId(order.getId()).setPayOrderId(order.getPayOrderId()));
    }

    @PostMapping("/update-paid")
    @Operation(summary = "更新订单为已支付") // 由 pay-module 支付服务，进行回调，可见 PayNotifyJob
    public CommonResult<Boolean> updateOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) {
        log.error("============进入支付回调===================");
        tradeOrderUpdateService.updateOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()),
                notifyReqDTO.getPayOrderId());
        return success(true);
    }

    @GetMapping("/get-detail")
    @Operation(summary = "获得交易订单")
    @Parameter(name = "id", description = "交易订单编号")
    @PreAuthenticated
    public CommonResult<AppTradeOrderDetailRespVO> getOrder(@RequestParam("id") Long id) {
        // 查询订单
        TradeOrderDO order = tradeOrderQueryService.getOrder(getLoginUserId(), id);
        if (order == null) {
            return success(null);
        }

        // 查询订单项
        List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(order.getId());
        // 查询物流公司
        DeliveryExpressDO express = order.getLogisticsId() != null && order.getLogisticsId() > 0 ?
                deliveryExpressService.getDeliveryExpress(order.getLogisticsId()) : null;
        // 最终组合
        CommonResult<AppTradeOrderDetailRespVO> rs=
                success(TradeOrderConvert.INSTANCE.convert02(order, orderItems, tradeOrderProperties, express));

        //设置订单支付的积分
        rs.getData().setPayIntegral(order.getPayIntegral());
        tradeOrderQueryService.setSpuType(rs.getData().getItems());

        return rs;
    }

    @GetMapping("/get-express-track-list")
    @Operation(summary = "获得交易订单的物流轨迹")
    @Parameter(name = "id", description = "交易订单编号")
    @PreAuthenticated
    public CommonResult<List<AppOrderExpressTrackRespDTO>> getOrderExpressTrackList(@RequestParam("id") Long id) {
        List<AppOrderExpressTrackRespDTO> data = TradeOrderConvert.INSTANCE.convertList02(
                tradeOrderQueryService.getExpressTrackList(id, getLoginUserId()));
        return success(data);
    }

    @GetMapping("/page")
    @Operation(summary = "获得交易订单分页")
    @PreAuthenticated
    public CommonResult<PageResult<AppTradeOrderPageItemRespVO>> getOrderPage(AppTradeOrderPageReqVO reqVO) {
        // 查询订单
        PageResult<TradeOrderDO> pageResult = tradeOrderQueryService.getOrderPage(getLoginUserId(), reqVO);
        // 查询订单项
        List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(
                convertSet(pageResult.getList(), TradeOrderDO::getId));
        // 最终组合
        PageResult<AppTradeOrderPageItemRespVO> data = TradeOrderConvert.INSTANCE.convertPage02(pageResult, orderItems);
        for (AppTradeOrderPageItemRespVO appTradeOrderPageItemRespVO : data.getList()) {
            tradeOrderQueryService.setSpuType(appTradeOrderPageItemRespVO.getItems());
        }
        return success(data);
    }

    @GetMapping("/get-count")
    @Operation(summary = "获得交易订单数量")
    @PreAuthenticated
    public CommonResult<Map<String, Long>> getOrderCount() {
        Map<String, Long> orderCount = Maps.newLinkedHashMapWithExpectedSize(5);
        // 全部
        orderCount.put("allCount", tradeOrderQueryService.getOrderCount(getLoginUserId(), null, null));
        // 待付款（未支付）
        orderCount.put("unpaidCount", tradeOrderQueryService.getOrderCount(getLoginUserId(),
                TradeOrderStatusEnum.UNPAID.getStatus(), null));
        // 待发货
        orderCount.put("undeliveredCount", tradeOrderQueryService.getOrderCount(getLoginUserId(),
                TradeOrderStatusEnum.UNDELIVERED.getStatus(), null));
        // 待收货
        orderCount.put("deliveredCount", tradeOrderQueryService.getOrderCount(getLoginUserId(),
                TradeOrderStatusEnum.DELIVERED.getStatus(), null));
        // 待评价
        orderCount.put("uncommentedCount", tradeOrderQueryService.getOrderCount(getLoginUserId(),
                TradeOrderStatusEnum.COMPLETED.getStatus(), false));
        // 售后数量
        orderCount.put("afterSaleCount", afterSaleService.getApplyingAfterSaleCount(getLoginUserId()));
        return success(orderCount);
    }

    @PutMapping("/receive")
    @Operation(summary = "确认交易订单收货")
    @Parameter(name = "id", description = "交易订单编号")
    @PreAuthenticated
    public CommonResult<Boolean> receiveOrder(@RequestParam("id") Long id) {
        tradeOrderUpdateService.receiveOrderByMember(getLoginUserId(), id);
        return success(true);
    }

    @DeleteMapping("/cancel")
    @Operation(summary = "取消交易订单")
    @Parameter(name = "id", description = "交易订单编号")
    @PreAuthenticated
    public CommonResult<Boolean> cancelOrder(@RequestParam("id") Long id) {
        tradeOrderUpdateService.cancelOrderByMember(getLoginUserId(), id);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除交易订单")
    @Parameter(name = "id", description = "交易订单编号")
    @PreAuthenticated
    public CommonResult<Boolean> deleteOrder(@RequestParam("id") Long id) {
        tradeOrderUpdateService.deleteOrder(getLoginUserId(), id);
        return success(true);
    }

    // ========== 订单项 ==========

    @GetMapping("/item/get")
    @Operation(summary = "获得交易订单项")
    @Parameter(name = "id", description = "交易订单项编号")
    @PreAuthenticated
    public CommonResult<AppTradeOrderItemRespVO> getOrderItem(@RequestParam("id") Long id) {
        TradeOrderItemDO item = tradeOrderQueryService.getOrderItem(getLoginUserId(), id);
        return success(TradeOrderConvert.INSTANCE.convert03(item));
    }

    @PostMapping("/item/create-comment")
    @Operation(summary = "创建交易订单项的评价")
    @PreAuthenticated
    public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) {
        return success(tradeOrderUpdateService.createOrderItemCommentByMember(getLoginUserId(), createReqVO));
    }

}
