package com.softwarebr.nunu.web.api;

import com.brframework.commondb.core.ControllerPageHandle;
import com.brframework.commonsecurity.core.SecurityContextHolder;
import com.brframework.commonweb.json.JSONResult;
import com.brframework.commonweb.json.Page;
import com.brframework.commonweb.json.PageParam;
import com.softwarebr.nunu.domain.Calculation;
import com.softwarebr.nunu.domain.OrderOnlinePay;
import com.softwarebr.nunu.domain.WxPayOrder;
import com.softwarebr.nunu.entity.train.Activity;
import com.softwarebr.nunu.entity.user.Order;
import com.softwarebr.nunu.entity.user.RefundInfo;
import com.softwarebr.nunu.json.api.order.*;
import com.softwarebr.nunu.service.oper.AreaService;
import com.softwarebr.nunu.service.train.ActivityService;
import com.softwarebr.nunu.service.user.OrderService;
import com.softwarebr.nunu.service.user.RefundInfoService;
import com.softwarebr.nunu.util.AmountConversionUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Map;

/**
 * @author lilin
 * @date 2020-02-27 12:00:43
 */

@RestController
@Api(tags = "订单")
@RequestMapping("/api")
public class ApiOrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private RefundInfoService refundInfoService;

    @Autowired
    private ActivityService activityService;

    @Autowired
    private AreaService areaService;


    @ApiOperation(value = "确认订单")
    @PutMapping("access/v1/order/create")
    public JSONResult<OrderResult> orderCreateV1(@Valid @RequestBody OrderParam param) {
        Long memberId = Long.valueOf(SecurityContextHolder.getSubject().getId());
        OrderResult orderResult = ControllerPageHandle.convertTo(orderService.confirmOrder(memberId, param.getOrderNo(), param.getActivityId(), param.getOrderAmount()), OrderResult.class);
        handleOrderResult(orderResult);
        return JSONResult.ok(orderResult);
    }

    @ApiOperation(value = "金额计算")
    @GetMapping("v1/order/calculation/{activityId}/{orderAmount}")
    public JSONResult<Calculation> orderCalculationV1(@ApiParam("活动Id") @PathVariable Long activityId,
                                                      @ApiParam("订票数量") @PathVariable Integer orderAmount) {
        Calculation calculation = orderService.calculationOrder(activityId, orderAmount);
        calculation.setPrice(AmountConversionUtil.out(calculation.getPrice()));
        calculation.setTotalPrice(AmountConversionUtil.out(calculation.getTotalPrice()));
        return JSONResult.ok(calculation);
    }

    @ApiOperation(value = "在线支付")
    @GetMapping("access/v1/order/pay/{orderNo}/{payType}")
    public JSONResult<OrderOnlinePay> orderPayV1(@ApiParam("订单号") @PathVariable String orderNo,
                                                 @ApiParam("支付方式(1微信 2支付宝)") @PathVariable Integer payType) {
        OrderOnlinePay onlinePay = orderService.onlinePayOrder(orderNo, payType);
        return JSONResult.ok(onlinePay);
    }


    @ApiOperation(value = "支付成功")
    @GetMapping("access/v1/order/pay/success/{orderNo}")
    public JSONResult orderPaySuccessV1(@ApiParam("订单号") @PathVariable String orderNo) {
        orderService.onlinePaySuccess(orderNo);
        return JSONResult.ok();
    }

    @ApiOperation(value = "申请退款")
    @PutMapping("access/v1/apply/refund")
    public JSONResult<RefundInfoResult> orderCreateV1(@Valid @RequestBody RefundInfoParam param) {
        Long memberId = Long.valueOf(SecurityContextHolder.getSubject().getId());
        RefundInfo refundInfo = refundInfoService.refundInfoSave(memberId, param.getOrderId(), param.getReason(), param.getVoucherPicture());
        return JSONResult.ok(ControllerPageHandle.convertTo(refundInfo, RefundInfoResult.class));
    }

    @ApiOperation(value = "我的订单")
    @GetMapping("access/v1/order/page")
    public JSONResult<Page<OrderResult>> orderPageV1(PageParam page, OrderQueryParam param) {
        Long memberId = Long.valueOf(SecurityContextHolder.getSubject().getId());
        param.setMemberId(memberId);
        Page<OrderResult> orderResultPage = ControllerPageHandle.jpaPageConvertToPage(orderService.page(page, param), page, OrderResult.class);
        orderResultPage.getList().forEach(o -> handleOrderResult(o));
        return JSONResult.ok(orderResultPage);
    }

    @ApiOperation(value = "订单详情")
    @GetMapping("access/v1/order/details/{id}")
    public JSONResult<OrderResult> orderDetailsV1(@ApiParam("订单Id") @PathVariable Long id) {
        OrderResult orderResult = ControllerPageHandle.convertTo(orderService.accessObject(id), OrderResult.class);
        handleOrderResult(orderResult);
        return JSONResult.ok(orderResult);
    }


    @ApiOperation(value = "h5退款售后")
    @GetMapping("access/v1/refund/page")
    public JSONResult<Page<RefundInfoResult>> refundPageV1(PageParam page, RefundQueryParam param) {
        Long memberId = Long.valueOf(SecurityContextHolder.getSubject().getId());
        param.setMemberId(memberId);
        Page<RefundInfoResult> resultPage = ControllerPageHandle.jpaPageConvertToPage(refundInfoService.page(page, param), page, RefundInfoResult.class);
        resultPage.getList().forEach(r->handleRefundResult(r));
        return JSONResult.ok(resultPage);
    }

    @ApiOperation(value = "h5退款售后->退款详情")
    @GetMapping("access/v1/refund/details/{id}")
    public JSONResult<RefundInfoResult> refundDetailsV1(@ApiParam("退款订单Id") @PathVariable Long id) {
        RefundInfoResult refundInfoResult = ControllerPageHandle.convertTo(refundInfoService.accessObject(id), RefundInfoResult.class);
        handleRefundResult(refundInfoResult);
        return JSONResult.ok(refundInfoResult);
    }

    /**
     * 退款订单数据处理
     *
     * @param refundResult
     */
    private void handleRefundResult(RefundInfoResult refundResult) {
        Activity activity = activityService.accessObject(refundResult.getActivityId());
        Order order = orderService.accessObject(refundResult.getOrderId());
        Map<Integer, String> typeMap = activityService.activityType(activity.getCategory());
        refundResult.setAddress(areaService.addressSplicing(activity.getProvinceId(), activity.getCityId(), activity.getAreaId()));
        refundResult.setStartDate(activity.getStartDate());
        refundResult.setEndDate(activity.getEndDate());
        refundResult.setName(activity.getName());
        refundResult.setTypeTitle(typeMap.get(activity.getType()));
        refundResult.setTotalPrice(AmountConversionUtil.out(refundResult.getTotalPrice()));
        refundResult.setOrderNo(order.getOrderNo());
        refundResult.setOrderAmount(order.getOrderAmount());
    }


    /**
     * 订单数据处理
     *
     * @param orderResult
     */
    private void handleOrderResult(OrderResult orderResult) {
        Activity activity = activityService.accessObject(orderResult.getActivityId());
        Map<Integer, String> typeMap = activityService.activityType(activity.getCategory());
        orderResult.setAddress(areaService.addressSplicing(activity.getProvinceId(), activity.getCityId(), activity.getAreaId()));
        orderResult.setStartDate(activity.getStartDate());
        orderResult.setEndDate(activity.getEndDate());
        orderResult.setName(activity.getName());
        orderResult.setCategoryTitle(activity.getCategory().equals(Activity.CATEGORY_INNOVATE) ? "创新活动" : "培训活动");
        orderResult.setTypeTitle(typeMap.get(activity.getType()));
        orderResult.setPrice(AmountConversionUtil.out(orderResult.getPrice()));
        orderResult.setTotalPrice(AmountConversionUtil.out(orderResult.getTotalPrice()));
        orderResult.setCoverUri(activity.getCoverUri());
        if (orderResult.getOrderStatus().equals(Order.ORDER_STATUS_REFUNDING)
                || orderResult.getOrderStatus().equals(Order.ORDER_STATUS_REFUNDED)
                || orderResult.getOrderStatus().equals(Order.ORDER_STATUS_REJECTED)) {
            RefundInfo refundInfo = refundInfoService.getRefundInfoByOrderId(orderResult.getId());
            orderResult.setVerify(refundInfo.getVerify());
            orderResult.setVerifyRemark(refundInfo.getVerifyRemark());
            orderResult.setRefundDate(refundInfo.getCreateDate());
            orderResult.setReason(refundInfo.getReason());
        }
    }

}