package com.iformall.controller;

import com.github.pagehelper.PageInfo;
import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.WxCUser;
import com.iformall.domain.po.WxCouponChannel;
import com.iformall.domain.po.WxOrder;
import com.iformall.domain.vo.WxOrderCouponPressVo;
import com.iformall.domain.vo.WxOrderCouponVo;
import com.iformall.enums.*;
import com.iformall.exception.MallinkException;
import com.iformall.service.WxCouponChannelService;
import com.iformall.service.WxOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.Map;

@RestController
@RequestMapping("/api/order/")
@Api(description = "订单相关接口")
public class WxOrderController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxCouponChannelService wxCouponChannelService;

    @Autowired
    private WxOrderService wxOrderService;

    @ApiOperation(value = "免费领取", notes = "{\"couponChannelId\":\"String\",\"couponId\":\"String\",\"formId\":\"String\"}")
    @PostMapping("freeCoupon")
    public ResultData freeCoupon(@RequestBody Map<String, String> paramMap) {
        //Assert.notNull(wxOrders.getName(), "角色名不能为空");
        //Assert.isTrue(!checkUnique(sysRole.getName(), null), "重复的角色名");
        String couponChannelIdStr = paramMap.get("couponChannelId");
        String couponIdStr = paramMap.get("couponId");
        String formId = paramMap.get("formId");
        if (StringUtils.isBlank(couponChannelIdStr)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponChannelId不能为空");
        }
        Long couponChannelId = 0L, couponId = 0L;
        try {
            couponChannelId = Long.valueOf(couponChannelIdStr);
        } catch (NumberFormatException e) {
            logger.error("couponChannelId convert error, " + couponChannelIdStr + ", e:" + e.getMessage());
            return new ResultData(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "couponChannelId: " + couponChannelIdStr + ", e:" + e.getMessage());
        }
        WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(couponChannelId);
        if (wxCouponChannel == null) {
            logger.error("couponChannelId convert error, " + couponChannelIdStr);
            return new ResultData(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "找不到发布的频道");
        }
        if (wxCouponChannel.getStatus() == EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode()) {
            logger.error("此券已下架:" + couponChannelIdStr);
            return new ResultData(ErrorCode.COUPON_CHANNEL_IS_TAKE_OFF.getCode(), "此券已下架");
        }
        if (StringUtils.isBlank(couponIdStr)) {
            couponId = wxCouponChannel.getCouponId();
        }

        WxOrder order = null;

        try {
            order = wxOrderService.saveFreeCouponOrder(getUserId(), couponChannelId, couponId, formId);
            return new ResultData(order);
        } catch (MallinkException e) {
            logger.error(e.getMessage());
            return new ResultData(e.getErrorCode(), e.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage());
            return new ResultData(ErrorCode.ORDER_IS_FAIL, e.getMessage());
        }
    }

    @ApiOperation(value = "下订单", notes = "{\"couponChannelId\":\"String\",\"couponId\":\"String\",\"press\":\"String\",\"orderGroupId\":\"String\",\"formId\":\"String\"}")
    @PostMapping("save")
    public ResultData saveOrder(@RequestBody Map<String, String> paramMap) {
        logger.info("OrderSave: " + paramMap.toString());
        //Assert.notNull(wxOrders.getName(), "角色名不能为空");
        //Assert.isTrue(!checkUnique(sysRole.getName(), null), "重复的角色名");
        String couponChannelIdStr = paramMap.get("couponChannelId");
        String couponIdStr = paramMap.get("couponId");
        String pressStr = paramMap.get("press");
        String orderGroupIdStr = paramMap.get("orderGroupId");
        String formId = paramMap.get("formId");

        if (StringUtils.isBlank(couponChannelIdStr)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponChannelId不能为空");
        }
        Long couponChannelId = 0L, couponId = 0L, orderGroupId = null;
        boolean isPress = false;

        if (StringUtils.isNotBlank(couponChannelIdStr)) {
            try {
                couponChannelId = Long.valueOf(couponChannelIdStr);
            } catch (NumberFormatException e) {
                logger.error("couponChannelId convert error, " + couponChannelIdStr + ", e:" + e.getMessage());
                return new ResultData(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "couponChannelId: " + couponChannelIdStr + ", e:" + e.getMessage());
            }
            WxCouponChannel wxCouponChannel = wxCouponChannelService.getById(couponChannelId);
            if (wxCouponChannel == null) {
                logger.error("couponChannelId convert error, " + couponChannelIdStr);
                return new ResultData(ErrorCode.SYS_PARAMETER_CAST_ERROR);
            }

            if (wxCouponChannel.getTargetAd().equals(EnumCouponChannelType.COUPON_CHANNEL_ID_TIMED.getCode())) {
                Date now = new Date();
                if (wxCouponChannel.getBeginTime().getTime() > now.getTime()) {
                    logger.error("此券活动未开始:" + couponChannelIdStr);
                    return new ResultData(ErrorCode.COUPON_CHANNEL_IS_NOT_STARTED);
                }
                if (wxCouponChannel.getEndTime().getTime() < now.getTime()) {
                    logger.error("此券活动已结束:" + couponChannelIdStr);
                    return new ResultData(ErrorCode.COUPON_CHANNEL_IS_END);
                }
            }

            if (wxCouponChannel.getStatus() == EnumCouponChannelStatus.STATUS_TAKE_OFFF.getCode()) {
                logger.error("此券已下架:" + couponChannelIdStr);
                return new ResultData(ErrorCode.COUPON_CHANNEL_IS_TAKE_OFF);
            }
            if (StringUtils.isBlank(couponIdStr)) {
                couponId = wxCouponChannel.getCouponId();
            }
        }
        if (couponId <= 0 && !StringUtils.isBlank(couponIdStr)) {
            try {
                couponId = Long.valueOf(couponIdStr);
            } catch (NumberFormatException e) {
                logger.error("couponId convert error, " + couponIdStr + ", e:" + e.getMessage());
                return new ResultData(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "couponId: " + couponIdStr + ", e:" + e.getMessage());
            }
        }

        if (couponId <= 0) {
            logger.error("couponChannelId或者couponId不能为空");
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "couponChannelId或者couponId不能为空");
        }

        if(pressStr != null) {
            try{
                isPress = Boolean.valueOf(pressStr);
            } catch (Exception e) {
                logger.error("press转换失败");
            }
        }

        if (orderGroupIdStr != null) {
            try {
                orderGroupId = Long.valueOf(orderGroupIdStr);
            } catch (Exception e) {
                logger.error("orderGroupId转换失败");
            }
        }

        WxCUser user = getUser();
        try {
            WxOrder order = wxOrderService.saveCouponOrder(user, couponChannelId, couponId, isPress, orderGroupId, formId);
            return new ResultData(order);
        } catch (MallinkException e) {
            logger.error(e.getMessage());
            return new ResultData(e.getErrorCode(), e.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage());
            return new ResultData(ErrorCode.ORDER_IS_FAIL, e.getMessage());
        }
    }

    @ApiOperation(value = "取消订单", notes = "{\"orderId\":\"string\"}")
    @PostMapping("cancel")
    public ResultData cancelOrder(@RequestBody Map<String, String> paramMap) {
        //Assert.notNull(wxOrders.getName(), "角色名不能为空");
        //Assert.isTrue(!checkUnique(sysRole.getName(), null), "重复的角色名");
        String orderIdStr = paramMap.get("orderId");
        if (StringUtils.isBlank(orderIdStr)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "orderId不能为空");
        }
        Long orderId = 0L;
        try {
            orderId = Long.valueOf(orderIdStr);
        } catch (NumberFormatException e) {
            logger.error(e.getMessage());
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL, "orderId: " + orderIdStr + ", e: " + e.getMessage());
        }
        try {
            WxOrder order = wxOrderService.getById(orderId);
            if (order != null) {
                wxOrderService.updateOrderStatus(order, EnumOrderStatus.ORDER_STATUS_OVERTIME_CANCEL);
            }
        } catch (Exception e) {
            logger.error("取消订单失败: " + e.getMessage());
            return new ResultData(ErrorCode.ORDER_IS_FAIL.getCode(), "取消订单失败: " + e.getMessage());
        }

        return new ResultData();
    }

    @ApiOperation(value = "订单已过期", notes = "{\"orderId\":\"string\"}")
    @PostMapping("expired")
    public ResultData expiredOrder(@RequestBody Map<String, String> paramMap) {
        //Assert.notNull(wxOrders.getName(), "角色名不能为空");
        //Assert.isTrue(!checkUnique(sysRole.getName(), null), "重复的角色名");
        String orderIdStr = paramMap.get("orderId");
        if (StringUtils.isBlank(orderIdStr)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "退款订单ID不能为空");
        }
        Long orderId = 0L;
        try {
            orderId = Long.valueOf(orderIdStr);
        } catch (NumberFormatException e) {
            logger.error(e.getMessage());
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "退款订单ID转换失败");
        }
        try {
            WxOrder order = wxOrderService.getById(orderId);
            if (order != null) {
                wxOrderService.updateOrderStatus(order, EnumOrderStatus.ORDER_STATUS_REFUND_SUCCESS);
            }
        } catch (Exception e) {
            logger.error("更新退款订单状态失败:" + e.getMessage());
            return new ResultData(ErrorCode.REFUND_ORDER_ERROR.getCode(), "更新退款订单状态失败:" + e.getMessage());
        }
        return new ResultData();
    }

    @ApiOperation("分页订单列表接口")
    @GetMapping("list")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true),
    })
    public ResultData list(@ModelAttribute WxOrder wxOrder, Integer pageNum, Integer pageSize) {
        // c端用户应该只能看到自己的订单
        if (wxOrder == null) wxOrder = new WxOrder();
        wxOrder.setcUserId(getUserId());
        wxOrder.setSortColumns(WxOrder.Field.UpdateDate_DESC);
        final PageInfo<WxOrderCouponVo> page = wxOrderService.listCUserVoAsPage(wxOrder, pageNum, pageSize);

        Date now = new Date();
        page.getList().stream().forEach(oc->{
            if (oc.getValidStartDate() != null && oc.getValidEndDate() != null ) {
                if (oc.getValidStartDate().getTime() > now.getTime()) {
                    oc.setValidStatus(EnumCouponOrderValidStatus.PREPARED.getCode());
                } else if (oc.getValidEndDate().getTime() < now.getTime()) {
                    oc.setValidStatus(EnumCouponOrderValidStatus.ENDED.getCode());
                } else {
                    oc.setValidStatus(EnumCouponChannelActivityStatus.STARTED.getCode());
                }
            }
        });


        return new ResultData(page);
    }

    @ApiOperation("订单详情接口")
    @GetMapping("detail")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true)
    })
    public ResultData detail(String orderId) {
        // c端用户应该只能看到自己的订单细节
        WxOrder wxOrder = new WxOrder();
        Long id = 0L;
        try {
            id = Long.valueOf(orderId);
        } catch (NumberFormatException e) {
            logger.error("parse orderId failed");
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "订单ID转换异常");
        }
        wxOrder.setId(id);
        wxOrder.setcUserId(getUserId());
        WxOrderCouponVo wxOrderCVo = wxOrderService.detailCUserVo(wxOrder);
        if (wxOrderCVo == null)
            return new ResultData(ErrorCode.ORDER_IS_NOT_FIND);

        Date now = new Date();

        if (wxOrderCVo.getValidStartDate() != null && wxOrderCVo.getValidEndDate() != null ) {
            if (wxOrderCVo.getValidStartDate().getTime() > now.getTime()) {
                wxOrderCVo.setValidStatus(EnumCouponOrderValidStatus.PREPARED.getCode());
            } else if (wxOrderCVo.getValidEndDate().getTime() < now.getTime()) {
                wxOrderCVo.setValidStatus(EnumCouponOrderValidStatus.ENDED.getCode());
            } else {
                wxOrderCVo.setValidStatus(EnumCouponChannelActivityStatus.STARTED.getCode());
            }
        }

        return new ResultData(wxOrderCVo);
    }

    @ApiOperation(value = "根据orderId查询接口", notes = "{\"orderId\":\"string\"}")
    @GetMapping("/findById")
    public ResultData findById(@RequestBody Map<String, String> paramMap) {
        String orderIdStr = paramMap.get("orderId");
        if (StringUtils.isBlank(orderIdStr)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "orderId不能为空");
        }
        Long orderId = 0L;
        try {
            orderId = Long.valueOf(orderIdStr);
        } catch (NumberFormatException e) {
            logger.error("parse orderId failed");
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "订单ID转换异常");
        }
        WxOrder order = null;
        try {
            order = wxOrderService.getById(orderId);
            if (order != null) {
                return new ResultData(Result.SUCCESS, "查询成功", order);
            } else {
                return new ResultData(ErrorCode.ORDER_IS_NOT_FIND);
            }
        } catch (Exception e) {
            logger.error("parse orderId failed");
            return new ResultData(ErrorCode.DB_FAIL.getCode(), "订单查询未成功,e:" + e.getMessage());
        }
    }

    @ApiOperation("我的砍价-分页列表接口")
    @GetMapping("pressOrderList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
    public ResultData pressOrderList(@ModelAttribute WxOrder wxOrder, Integer pageNum, Integer pageSize) {
        // c端用户应该只能看到自己的订单
        if (wxOrder == null) wxOrder = new WxOrder();
        wxOrder.setcUserId(getUserId());
        wxOrder.setSortColumns(WxOrder.Field.CreateDate_DESC);
        final PageInfo<WxOrderCouponPressVo> page = wxOrderService.listPressVoAsPage(wxOrder, pageNum, pageSize);
        return new ResultData(page);
    }

    @ApiOperation("砍价订单-详情接口")
    @GetMapping("pressOrderDetail")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", dataType = "String", paramType = "query", required = true)
    })
    public ResultData pressOrderDetail(String orderId) {
        // c端用户应该只能看到自己的订单细节
        WxOrder wxOrder = new WxOrder();
        if(StringUtils.isBlank(orderId)) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "订单ID不能为空");
        }
        Long id = 0L;
        try {
            id = Long.valueOf(orderId);
        } catch (NumberFormatException e) {
            logger.error("parse orderId failed");
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "订单ID转换异常");
        }
        wxOrder.setId(id);
        final WxOrderCouponPressVo orderCouponPressVo = wxOrderService.detailPressVo(wxOrder);
        if (orderCouponPressVo == null)
            return new ResultData(ErrorCode.ORDER_IS_NOT_FIND);
        return new ResultData(orderCouponPressVo);
    }


}
