package com.fzm.mall.server.front.order.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fzm.mall.server.front.annotation.ApiIdempotent;
import com.fzm.mall.server.front.asset.model.UserAsset;
import com.fzm.mall.server.front.base.PageVO;
import com.fzm.mall.server.front.base.ResponseVO;
import com.fzm.mall.server.front.constant.MallResponseEnum;
import com.fzm.mall.server.front.constant.PageConst;
import com.fzm.mall.server.front.enums.MessageSuffixEnum;
import com.fzm.mall.server.front.enums.QueueTTLTypeEnum;
import com.fzm.mall.server.front.enums.QueueTypeEnum;
import com.fzm.mall.server.front.goods.model.Category;
import com.fzm.mall.server.front.goods.model.vo.PageVo;
import com.fzm.mall.server.front.goods.service.ISkuService;
import com.fzm.mall.server.front.mq.MsgProducer;
import com.fzm.mall.server.front.order.model.Complaint;
import com.fzm.mall.server.front.order.model.Pay;
import com.fzm.mall.server.front.order.model.Refund;
import com.fzm.mall.server.front.order.model.po.NftOrderPo;
import com.fzm.mall.server.front.order.model.po.PayRestVO;
import com.fzm.mall.server.front.order.model.po.PreSaleOrderVo;
import com.fzm.mall.server.front.order.model.vo.*;
import com.fzm.mall.server.front.order.service.*;
import com.fzm.mall.server.front.redis.OrderRedis;
import com.fzm.mall.server.front.user.model.Header;
import com.fzm.mall.server.front.user.service.IRedisService;
import com.fzm.mall.server.front.user.service.IUserService;
import com.fzm.mall.server.front.util.Sha256Util;
import com.fzm.mall.server.front.valid.LongValid;
import io.netty.util.internal.StringUtil;
import io.swagger.annotations.ApiOperation;
import jdk.nashorn.internal.ir.annotations.Ignore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 用户购物订单表 前端控制器
 * </p>
 *
 * @author fzm
 * @since 2021-03-17
 */
@RestController
@RequestMapping("mall/order")
public class OrderController {

    @Autowired
    private IOrderService orderService;

    @Autowired
    private IRedisService redisService;

    @Autowired
    private IPayService payService;

    @Autowired
    private MsgProducer msgProducer;

    @Autowired
    private IConfigService configService;

    @Autowired
    private IRefundService refundService;

    @Autowired
    private OrderRedis orderRedis;

    @Autowired
    private IComplaintService complaintService;

    @Autowired
    private IDeliveryService deliveryService;

    @Autowired
    private ISkuService skuService;

    @ApiOperation(value = "下单")
    @PostMapping("/createOrder")
    public ResponseVO<String> createOrder(@Ignore @RequestAttribute Header header, @RequestBody OrderVo orderVo) {
        //校验商品是否是这家店的
        Boolean result = skuService.checkOrder(orderVo);
        if(!result){
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
        String pid = "";
        try {
            pid = orderService.createOrder(header.getUid(), orderVo, header.getType());
        } catch (Exception e) {
            String msg = e.getMessage();
            if (("商品不存在或下架").equals(msg)) {
                return new ResponseVO<>(MallResponseEnum.GOODS_NOT_BUY);
            } else if (("库存不足!!!").equals(msg)) {
                return new ResponseVO<>(MallResponseEnum.GOOD_STOCK_NOT_ENOUGH);
            } else if (("存在无效优惠券!!!").equals(msg)) {
                return new ResponseVO<>(MallResponseEnum.GOOD_COUPON_NOT_EXIST);
            } else if (("一个商品只能使用一个优惠券!!!").equals(msg)) {
                return new ResponseVO<>(MallResponseEnum.GOOD_COUPON_NOT_EXIST);
            } else if (("商品数量错误").equals(msg)) {
                return new ResponseVO<>(MallResponseEnum.GOOD_NUM_ERR);
            } else if (("当前地区不支持快递").equals(msg)) {
                return new ResponseVO<>(MallResponseEnum.NOT_SUPPORT_MAIL);
            } else {
                e.printStackTrace();
                //数据库异常
                return new ResponseVO<>(MallResponseEnum.DB_ERROR);
            }
        }

        return new ResponseVO<>(MallResponseEnum.SUCCESS, pid);
    }

    @ApiOperation(value = "盲盒下单")
    @PostMapping("/blindBox/createOrder")
    public ResponseVO<String> blindBoxCreateOrder(@Ignore @RequestAttribute Header header, @RequestBody @Valid OrderBlindBoxVo orderVo) {
        /**
         * 參數校驗
         */
        if(ObjectUtils.isEmpty(orderVo.getDelivery()) || StringUtils.isEmpty(orderVo.getGoodsId())){
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }

        String pid = "";
        try {
            pid = orderService.blindBoxCreateOrder(header.getUid(), header.getType(), orderVo);
        } catch (Exception e) {
            String msg = e.getMessage();
            if (("商品不存在或下架").equals(msg)) {
                return new ResponseVO<>(MallResponseEnum.GOODS_NOT_BUY);
            } else if (("库存不足!!!").equals(msg)) {
                return new ResponseVO<>(MallResponseEnum.GOOD_STOCK_NOT_ENOUGH);
            } else if (("存在无效优惠券!!!").equals(msg)) {
                return new ResponseVO<>(MallResponseEnum.GOOD_COUPON_NOT_EXIST);
            } else if (("一个商品只能使用一个优惠券!!!").equals(msg)) {
                return new ResponseVO<>(MallResponseEnum.GOOD_COUPON_NOT_EXIST);
            } else if (("商品数量错误").equals(msg)) {
                return new ResponseVO<>(MallResponseEnum.GOOD_NUM_ERR);
            } else if (("当前地区不支持快递").equals(msg)) {
                return new ResponseVO<>(MallResponseEnum.NOT_SUPPORT_MAIL);
            }else if("活动火爆".equals(msg)){
                return new ResponseVO<>(MallResponseEnum.HOT_ACTIVITY);
            } else{
                e.printStackTrace();
                //数据库异常
                return new ResponseVO<>(MallResponseEnum.DB_ERROR);
            }
        }

        return new ResponseVO<>(MallResponseEnum.SUCCESS, pid);
    }


    @ApiOperation(value = "支付 参数 pid")
    @PostMapping("/pay")
    public ResponseVO<String> pay(@Ignore @RequestAttribute Header header, @RequestBody PayVo payVo) {
        String pid = payVo.getPid();
        if (StringUtil.isNullOrEmpty(payVo.getPayPassword())) {
            if(StringUtil.isNullOrEmpty(payVo.getVerificationCode())){
                return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
            }else {
                String key = redisService.getKey(header.getAccount() + MessageSuffixEnum.BUY_GOODS_SUFFIX);
                if(StringUtil.isNullOrEmpty(key)){
                    return  new ResponseVO<String>(MallResponseEnum.CODE_NOT_SEND);
                }
                if(!key.equals(payVo.getVerificationCode())){
                    return  new ResponseVO<String>(MallResponseEnum.CODE_ERR);
                }
            }
        }else{
            if (StringUtil.isNullOrEmpty(header.getPayPassword())) {
                return new ResponseVO<>(MallResponseEnum.NOT_SET_PAY_PASSWORD);
            }
            if (!Sha256Util.sha256String(payVo.getPayPassword()).equals(header.getPayPassword())) {
                return new ResponseVO<>(MallResponseEnum.PAY_PASSWORD_ERR);
            }
        }
        if (!redisService.setNx(header.getUid() + "_pay")) {
            return new ResponseVO<>(MallResponseEnum.OPERATION_OFTEN);
        }

        int i = payService.pay(header.getUid(), pid);
        if (i == 1) {
            //发送消息队列
            msgProducer.send(pid, QueueTypeEnum.ORDER_PAY);
            return new ResponseVO(MallResponseEnum.SUCCESS);
            //资产不足
        } else if (i == 0) {
            return new ResponseVO(MallResponseEnum.ASSET_NOT_ENOUGH);
        } else if (i == -1) {
            return new ResponseVO(MallResponseEnum.ORDER_NOT_PAY);
        } else {
            return new ResponseVO(MallResponseEnum.DB_ERROR);
        }

    }

    @ApiOperation(value = "获取支付订单 参数 pid")
    @PostMapping("/getPay")
    public ResponseVO<Pay> getPay(@Ignore @RequestAttribute Header header, @RequestBody JSONObject data) {
        Pay pay = payService.getByPidAndUid(data.getString("pid"), header.getUid());
        return new ResponseVO<>(MallResponseEnum.SUCCESS, pay);
    }

    @ApiOperation(value = "申请退款")
    @PostMapping("/applyReturn")
    public ResponseVO<Pay> applyReturn(@Ignore @RequestAttribute Header header, @RequestBody ReturnMoneyVo returnMoneyVo) {
        String oid = returnMoneyVo.getOrderId();
        Refund refund = refundService.getByOid(returnMoneyVo.getOrderId());
        if (refund != null) {
            return new ResponseVO<>(MallResponseEnum.NOT_SUPPORT_RETURN_MONEY_TWO);
        }
        int i = 0;
        try {
            i = orderService.applyReturn(header.getUid(), oid);
        } catch (Exception e) {
            return new ResponseVO<>(MallResponseEnum.ASSET_NOT_ENOUGH);
        }

        if (i == 1) {
            refund = new Refund();
            refund.setOid(oid);
            refund.setReturnReason(returnMoneyVo.getReturnReason());
            refund.setReturnTime(System.currentTimeMillis());
            refund.setReturnIndex("");
            refund.setReturnType(returnMoneyVo.getReturnType());
            refund.setReturnImg(returnMoneyVo.getReturnImg() == null ? "" : returnMoneyVo.getReturnImg().toJSONString());
            refundService.save(refund);
            orderRedis.delListOrderDetail(returnMoneyVo.getOrderId());
            orderRedis.delOrder(returnMoneyVo.getOrderId());
        } else {
            return new ResponseVO<>(MallResponseEnum.NOT_SUPPORT_RETURN_MONEY);
        }
        return new ResponseVO<>(MallResponseEnum.SUCCESS);
    }

    @ApiIdempotent
    @ApiOperation(value = "取消支付 参数 pid")
    @PostMapping("/closePay")
    public ResponseVO<Pay> closePay(@Ignore @RequestAttribute Header header, @RequestBody JSONObject data) {
        String pid = data.getString("pid");
        Pay byPidAndUid = payService.getByPidAndUid(pid, header.getUid());
        if (byPidAndUid == null) {
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
        String oidsJson = byPidAndUid.getOidsJson();
        JSONArray oids = JSON.parseArray(oidsJson);
        for (Object oid : oids) {
            orderService.close(oid);
            orderRedis.delListOrderDetail(oid.toString());
            orderRedis.delOrder(oid.toString());

        }

        return new ResponseVO<>(MallResponseEnum.SUCCESS);
    }

    @ApiOperation(value = "撤销退款 参数 oid")
    @PostMapping("/revokeReturn")
    public ResponseVO<Pay> revokeReturn(@Ignore @RequestAttribute Header header, @RequestBody JSONObject data) {
        String oid = data.getString("oid");
        int i = 0;
        try {
            i = orderService.revokeReturn(header.getUid(), oid);
        } catch (Exception e) {
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }

        if (i == 1) {
            orderRedis.delListOrderDetail(oid.toString());
            orderRedis.delOrder(oid.toString());
            return new ResponseVO<>(MallResponseEnum.SUCCESS);
        } else {
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
    }

    @ApiOperation(value = "退款详情 参数 oid")
    @PostMapping("/returnMoneyDetail")
    public ResponseVO<ReturnMoneyDetail> returnMoneyDetail(@Ignore @RequestAttribute Header header, @RequestBody JSONObject data) {
        String oid = data.getString("oid");
        ReturnMoneyDetail returnMoneyDetail = orderService.getReturnMoneyDetail(oid);
        if (returnMoneyDetail == null) {
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
        return new ResponseVO<>(MallResponseEnum.SUCCESS, returnMoneyDetail);
    }

    @ApiOperation(value = "订单投诉")
    @PostMapping("/addComplaint")
    public ResponseVO<String> addComplaint(@Ignore @RequestAttribute Header header, @RequestBody ComplaintVo complaint) {
        String uid = header.getUid();
        if (!redisService.setNx(uid + "_AddComplaint")) {
            return new ResponseVO<>(MallResponseEnum.OPERATION_OFTEN);
        }
        if (StringUtil.isNullOrEmpty(complaint.getOrderId()) || complaint.getOrderType() == null) {
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
        if(complaint.getOrderType() == 1){
            Integer count = orderService.getCountByUidAndOid(uid,complaint.getOrderId());
            if(count == 0){
                return  new ResponseVO<>(MallResponseEnum.OID_ERR);
            }
        }else if(complaint.getOrderType() == 2){
            Integer count = deliveryService.getCountByUidAndOid(uid,complaint.getOrderId());
            if(count == 0){
                return  new ResponseVO<>(MallResponseEnum.OID_ERR);
            }
        }else{
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
        System.out.println("addComplaint:"+complaint.getOrderType());
        int i = complaintService.addComplaint(uid, complaint);
        if (i == 1) {
            return new ResponseVO<>(MallResponseEnum.SUCCESS);
        } else {
            return new ResponseVO<>(MallResponseEnum.AREADLY_SUPPORT);
        }
    }

    @ApiOperation(value = "订单投诉列表")
    @PostMapping("/complaintList")
    public ResponseVO<PageVO<Complaint>> complaintList(@Ignore @RequestAttribute Header header, @RequestBody PageVo pageVo) {
        Integer page = pageVo.getPage();
        Integer size = pageVo.getSize();
        if (!LongValid.positiveLong(page.toString())) {
            page = 1;
        }
        if (!LongValid.positiveLong(size.toString())) {
            size = 10;
        }
        pageVo.setPage(page);
        pageVo.setSize(size);
        String uid = header.getUid();
        PageVO<Complaint> list = complaintService.complaintList(uid, pageVo);
        return new ResponseVO<>(MallResponseEnum.SUCCESS, list);
    }

    @ApiOperation(value = "订单投诉详情")
    @PostMapping("/complaintById")
    public ResponseVO<Complaint> complaintById(@Ignore @RequestAttribute Header header, @RequestBody JSONObject obj) {
        String id = obj.getString("id");
        String uid = header.getUid();
        Complaint complaint = complaintService.complaintById(uid, id);
        return new ResponseVO<>(MallResponseEnum.SUCCESS, complaint);
    }

    @ApiOperation(value = "是否设置过支付密码")
    @PostMapping("/isSetPayPassword")
    public ResponseVO<Boolean> pay(@Ignore @RequestAttribute Header header) {
        Boolean b = false;
        if(!StringUtil.isNullOrEmpty(header.getPayPassword())){
            b = true;
        }
        return new ResponseVO<>(MallResponseEnum.SUCCESS,b);
    }
    @ApiOperation(value = "预售定金下单")
    @PostMapping("/preSaleCreateOrder")
    public ResponseVO<String> preSaleCreateOrder(@Ignore @RequestAttribute Header header, @RequestBody PreSaleOrderVo preSaleOrderVo) {
        if(preSaleOrderVo == null||preSaleOrderVo.getNumber()==null||preSaleOrderVo.getNumber()<=0){
            return  new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
        //spu
        String pid = "";
        try{
            pid = orderService.createPreSaleOrder(header.getUid(),preSaleOrderVo);
        }catch (Exception e){
            System.err.println("error:"+e.toString());
        }
        System.err.println("pid:"+pid);
        return new ResponseVO<>(MallResponseEnum.SUCCESS, pid);
    }

    @ApiOperation(value = "支付定金  param ： pid")
    @PostMapping("/payDeposit")
    public ResponseVO<String> payDeposit(@Ignore @RequestAttribute Header header, @RequestBody  PayVo payVo) {
        String pid = payVo.getPid();
        if (StringUtil.isNullOrEmpty(header.getPayPassword())) {
            return new ResponseVO<>(MallResponseEnum.NOT_SET_PAY_PASSWORD);
        }
        if (StringUtil.isNullOrEmpty(payVo.getPayPassword())) {
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
        if (!Sha256Util.sha256String(payVo.getPayPassword()).equals(header.getPayPassword())) {
            return new ResponseVO<>(MallResponseEnum.PAY_PASSWORD_ERR);
        }
        if (!redisService.setNx(header.getUid() + "_pay")) {
            return new ResponseVO<>(MallResponseEnum.OPERATION_OFTEN);
        }

        int i = payService.payDeposit(header.getUid(), pid);
        if (i == 1) {
            //发送消息队列
            //msgProducer.send(pid, QueueTypeEnum.ORDER_PAY);
            return new ResponseVO(MallResponseEnum.SUCCESS);
            //资产不足
        } else if (i == 0) {
            return new ResponseVO(MallResponseEnum.ASSET_NOT_ENOUGH);
        } else if (i == -1) {
            return new ResponseVO(MallResponseEnum.ORDER_NOT_PAY);
        } else {
            return new ResponseVO(MallResponseEnum.DB_ERROR);
        }
    }

    @ApiOperation(value = "支付尾款")
    @PostMapping("/payRest")
    public ResponseVO<String> payRest(@Ignore @RequestAttribute Header header, @RequestBody PayRestVO payRestVO) {
        String pid = payRestVO.getPid();
        if (StringUtil.isNullOrEmpty(header.getPayPassword())) {
            return new ResponseVO<>(MallResponseEnum.NOT_SET_PAY_PASSWORD);
        }
        if (StringUtil.isNullOrEmpty(payRestVO.getPayPassword())) {
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
        if (!Sha256Util.sha256String(payRestVO.getPayPassword()).equals(header.getPayPassword())) {
            return new ResponseVO<>(MallResponseEnum.PAY_PASSWORD_ERR);
        }
        if (!redisService.setNx(header.getUid() + "_pay")) {
            return new ResponseVO<>(MallResponseEnum.OPERATION_OFTEN);
        }

        int i = payService.payRest(header.getUid(), payRestVO);
        if (i == 1) {
            //发送消息队列
            msgProducer.send(pid, QueueTypeEnum.ORDER_PAY);
            return new ResponseVO(MallResponseEnum.SUCCESS);
            //资产不足
        } else if (i == 0) {
            return new ResponseVO(MallResponseEnum.ASSET_NOT_ENOUGH);
        } else if (i == -1) {
            return new ResponseVO(MallResponseEnum.ORDER_NOT_PAY);
        }else if(i == -2){
            return new ResponseVO(MallResponseEnum.ONLY_SUPPORT_MAIL);
        }else if(i == -3){
            return new ResponseVO(MallResponseEnum.COUPON_ERR);
        }else{
            return new ResponseVO(MallResponseEnum.DB_ERROR);
        }
    }

   /* @ApiOperation(value = "nft下单")
    @PostMapping("/newCreateOrder")
    public ResponseVO<String> newCreateOrder(@Ignore @RequestAttribute Header header, @RequestBody List<NftOrderPo> nftOrderPos) {
        String pid = "";
        try {
            pid = orderService.createNftOrder(header.getUid(), nftOrderPos);
            msgProducer.sendTTL(pid, QueueTTLTypeEnum.ORDER_CLOSE_TTL, configService.getConfig().getOrderCloseLimit());
        } catch (Exception e) {

        }
        return new ResponseVO<>(MallResponseEnum.SUCCESS, pid);
    }*/
}
