/**
 * Copyright (C) 2018-2022
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制，未经购买不得使用
 * 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 * 一经发现盗用、分享等行为，将追究法律责任，后果自负
 */
package co.yixiang.yshop.module.order.controller.app.order;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.pojo.CommonResult;
import co.yixiang.yshop.framework.security.core.annotations.PreAuthenticated;
import co.yixiang.yshop.module.express.dal.redis.express.ExpressRedisDAO;
import co.yixiang.yshop.module.express.kdniao.model.dto.KdniaoApiBaseDTO;
import co.yixiang.yshop.module.express.kdniao.model.dto.KdniaoApiDTO;
import co.yixiang.yshop.module.express.kdniao.model.vo.KdniaoApiVO;
import co.yixiang.yshop.module.express.kdniao.util.KdniaoUtil;
import co.yixiang.yshop.module.member.controller.app.user.vo.AppUserOrderCountVo;
import co.yixiang.yshop.module.order.controller.app.order.param.*;
import co.yixiang.yshop.module.order.controller.app.order.vo.AppConfirmOrderVo;
import co.yixiang.yshop.module.order.controller.app.order.vo.AppStoreOrderQueryVo;
import co.yixiang.yshop.module.order.dal.redis.order.AsyncOrderRedisDAO;
import co.yixiang.yshop.module.order.service.storeorder.AppStoreOrderService;
import com.egzosn.pay.spring.boot.core.PayServiceManager;
import com.egzosn.pay.web.support.HttpRequestNoticeParams;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

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

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.framework.common.pojo.CommonResult.success;
import static co.yixiang.yshop.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.PARAM_ERROR;
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.STORE_ORDER_NOT_EXISTS;

/**
 * <p>
 * 订单控制器
 * </p>
 *
 * @author hupeng
 * @since 2023-6-23
 */
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Tag(name = "用户 APP - 订单模块")
@RequestMapping("/order")
public class AppOrderController {

    private final AppStoreOrderService appStoreOrderService;
    private final AsyncOrderRedisDAO asyncOrderRedisDAO;
    private final PayServiceManager manager;

    @Resource
    private ExpressRedisDAO expressRedisDAO;




    @PreAuthenticated
    @PostMapping("/confirm")
    @Operation(summary = "订单确认")
    public CommonResult<AppConfirmOrderVo> confirm(@Validated @RequestBody AppConfirmOrderParam param) {
        Long uid = getLoginUserId();
        return success(appStoreOrderService.confirmOrder(uid, param.getCartId()));

    }

    /**
     * 计算订单金额
     */
    @PreAuthenticated
    @PostMapping("/computed/{key}")
    @Parameter(name = "key", description = "确认订单返回唯一的key", required = true)
    @Operation(summary = "计算订单金额")
    public CommonResult<Map<String, Object>> computedOrder(@Validated @RequestBody AppComputeOrderParam param,
                                                        @PathVariable String key) {
        Long uid = getLoginUserId();
        return success(appStoreOrderService.computedOrder(uid, key, param));
    }

    /**
     * 订单创建
     */
    @PreAuthenticated
    @PostMapping("/create/{key}")
    @Operation(summary = "订单创建")
    @Parameter(name = "key", description = "唯一的uni值或者订单号", required = true, example = "10      ")
    public CommonResult<Map<String, Object>> create(@Valid @RequestBody AppOrderParam param,
                                                 @PathVariable String key) {
        Long uid = getLoginUserId();
        return success(appStoreOrderService.createOrder(uid, key, param));
    }


    /**
     * 订单支付
     */
    @PreAuthenticated
    @PostMapping(value = "/pay")
    @Operation(summary = "订单支付")
    public CommonResult<Map<String, Object>> pay(@Valid @RequestBody AppPayParam param) {
        Long uid = getLoginUserId();
        return success(appStoreOrderService.pay(uid,param));
    }

    /**
     * 支付回调地址
     *
     * @param request   请求
     * @param detailsId 列表id
     * @return 支付是否成功
     */
    @RequestMapping(value = "payBack{detailsId}.json")
    public String payBack(HttpServletRequest request, @PathVariable String detailsId)  {
        return manager.payBack(detailsId, new HttpRequestNoticeParams(request));
    }


    /**
     * 订单列表
     */
    @PreAuthenticated
    @GetMapping("/list")
    @Operation(summary = "订单列表")
    @Parameters({
            @Parameter(name = "type", description = "商品状态,-1全部 默认为0未支付 1待发货 2待收货 3待评价 4已完成 5退款中 6已退款 7退款",
                    required = true, example = "1"),
            @Parameter(name = "page", description = "页码,默认为1",
                    required = true, example = "1"),
            @Parameter(name = "limit", description = "页大小,默认为10",
                    required = true, example = "10      ")
    })
    public CommonResult<List<AppStoreOrderQueryVo>> orderList(@RequestParam(value = "type", defaultValue = "0") int type,
                                       @RequestParam(value = "page", defaultValue = "1") int page,
                                       @RequestParam(value = "limit", defaultValue = "10") int limit) {
        Long uid = getLoginUserId();
        return success(appStoreOrderService.orderList(uid, type, page, limit));
    }


    /**
     * 订单详情
     */
    @PreAuthenticated
    @GetMapping("/detail/{key}")
    @Operation(summary = "订单详情")
    @Parameter(name = "key", description = "唯一的uni值或者订单号", required = true, example = "10      ")
    public CommonResult<AppStoreOrderQueryVo> detail(@PathVariable String key) {
        Long uid = getLoginUserId();
        if (StrUtil.isEmpty(key)) {
            throw exception(PARAM_ERROR);
        }
        AppStoreOrderQueryVo storeOrder = appStoreOrderService.getOrderInfo(key, uid);
        if (ObjectUtil.isNull(storeOrder)) {
            throw exception(STORE_ORDER_NOT_EXISTS);
        }
        return success(appStoreOrderService.handleOrder(storeOrder));
    }


    /**
     * 订单收货
     */
    @PreAuthenticated
    @PostMapping("/take")
    @Operation(summary = "订单收货")
    public CommonResult<Boolean> orderTake(@Validated @RequestBody AppDoOrderParam param) {
        Long uid = getLoginUserId();
        appStoreOrderService.takeOrder(param.getUni(), uid);
        return success(true);
    }




    /**
     * 订单评价
     */
    @PreAuthenticated
    @PostMapping("/comments")
    @Operation(summary = "订单评价")
    public CommonResult<Boolean> comments(@Valid @RequestBody List<AppProductReplyParam> param) {
        Long uid = getLoginUserId();
        if (param.size() > 0) {
            for (AppProductReplyParam productReplyParam : param) {
                appStoreOrderService.orderComment(uid, productReplyParam.getUnique(),
                        productReplyParam.getComment(),
                        productReplyParam.getPics(), productReplyParam.getProductScore(), productReplyParam.getServiceScore());
            }

        }
        return success(true);
    }


    /**
     * 订单删除
     */
    @PreAuthenticated
    @PostMapping("/del")
    @Operation(summary = "订单删除")
    public CommonResult<Boolean> orderDel(@Validated @RequestBody AppDoOrderParam param) {
        Long uid = getLoginUserId();
        appStoreOrderService.removeOrder(param.getUni(), uid);
        return success(true);
    }




    /**
     * 订单取消   未支付的订单回退积分,回退优惠券,回退库存
     */
    @PreAuthenticated
    @PostMapping("/cancel")
    @Operation(summary = "订单取消")
    public CommonResult<Boolean> cancelOrder(@Validated @RequestBody AppHandleOrderParam param) {
        Long uid = getLoginUserId();
        appStoreOrderService.cancelOrder(param.getId(), uid);
        return success(true);
    }

    /**
     * 个人中心订单统计
     */
    @PreAuthenticated
    @PostMapping("/user_count")
    @Operation(summary = "个人中心订单统计")
    public CommonResult<AppUserOrderCountVo> countOrder() {
        Long uid = getLoginUserId();
        AppUserOrderCountVo appUserOrderCountVo = asyncOrderRedisDAO.get(uid);
        return success(appUserOrderCountVo);
    }



    /**
     * 获取物流信息
     */
    @PreAuthenticated
    @PostMapping("/order/express")
    @Operation(summary = "获取物流信息")
    public CommonResult<KdniaoApiVO> express(@RequestBody AppExpressParam appExpressParam) {

        KdniaoApiBaseDTO kdniaoApiBaseDTO = expressRedisDAO.get();
        KdniaoApiDTO params = new KdniaoApiDTO();
        params.setLogisticCode(appExpressParam.getLogisticCode());
        params.setShipperCode(appExpressParam.getShipperCode());
        params.setApiKey(kdniaoApiBaseDTO.getApiKey());
        params.setEBusinessID(kdniaoApiBaseDTO.getEBusinessID());
        //此处注意 这个地方分收费与免费当 目前用当免费免费当只支持圆通 申通 百世 如果是收费当 改里面RequestType参数 函数里有说明
        return success(KdniaoUtil.getLogisticInfo(params));

    }





}

