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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fzm.mall.server.front.asset.model.po.qo.OrderQO;
import com.fzm.mall.server.front.asset.model.vo.order.OrderPageVo;
import com.fzm.mall.server.front.base.PageVO;
import com.fzm.mall.server.front.base.ResponseVO;
import com.fzm.mall.server.front.constant.*;
import com.fzm.mall.server.front.enums.QueueTypeEnum;
import com.fzm.mall.server.front.goods.model.vo.SkuVo;
import com.fzm.mall.server.front.goods.service.IDistributionTemplateService;
import com.fzm.mall.server.front.goods.service.IGoodSkuService;
import com.fzm.mall.server.front.mq.MsgProducer;
import com.fzm.mall.server.front.order.model.Delivery;
import com.fzm.mall.server.front.order.model.DeliveryRefund;
import com.fzm.mall.server.front.order.model.po.DeliveryPO;
import com.fzm.mall.server.front.order.model.vo.*;
import com.fzm.mall.server.front.order.service.IDeliveryRefundService;
import com.fzm.mall.server.front.order.service.IDeliveryService;
import com.fzm.mall.server.front.user.model.Header;
import com.fzm.mall.server.front.user.service.CoinService;
import com.fzm.mall.server.front.user.service.IRedisService;
import com.fzm.mall.server.front.util.CheckUtil;
import com.fzm.mall.server.front.util.OrderUtil;
import com.fzm.mall.server.front.util.Sha256Util;
import com.fzm.mall.server.front.valid.IdValid;
import com.fzm.mall.server.front.valid.LongValid;
import com.fzm.mall.server.front.valid.TypeValid;
import io.netty.util.internal.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import jdk.nashorn.internal.ir.annotations.Ignore;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

/**
 * @author tdz
 * @date 2021/04/13 11:17
 */
@Api(tags = "商品提货接口", description = "用户使用Token进行提货等")
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping(value = "/mall/delivery", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class DeliveryController {
    private final IDeliveryService deliveryService;
    private final IDeliveryRefundService deliveryRefundService;
    private final IGoodSkuService goodSkuService;
    private final IDistributionTemplateService distributionTemplateService;
    private final IRedisService redisService;


    @ApiOperation(value = "查询指定订单")
    @PostMapping("/getByOid")
    public ResponseVO<DeliveryVO> delivery(@RequestBody JSONObject json) {
        String deliveryId = json.getString("deliveryId");
        DeliveryVO delivery = deliveryService.delivery(deliveryId);
        return new ResponseVO<>(MallResponseEnum.SUCCESS, delivery);
    }

    @ApiOperation(value = "用积分支付提货单邮费")
    @PostMapping("/payPostfeeByCoin")
    public ResponseVO<String> payPostfeeByCoin(@Ignore @RequestAttribute Header header, @RequestBody DeliveryVO deliveryVO) {
        if (StringUtil.isNullOrEmpty(header.getPayPassword())) {
            return new ResponseVO<>(MallResponseEnum.NOT_SET_PAY_PASSWORD);
        }
        if (!Sha256Util.sha256String(deliveryVO.getPayPassword()).equals(header.getPayPassword())) {
            return new ResponseVO<>(MallResponseEnum.PAY_PASSWORD_ERR);
        }
        String uid = header.getUid();
        if (!redisService.setNx(uid + "_payPostfeeByCoin")) {
            return new ResponseVO<>(MallResponseEnum.OPERATION_OFTEN);
        }
        //生成付款记录
        //deliveryVO.setOrderDeliveryId(OrderUtil.getDeliveryId());
        deliveryVO.setUid(uid);
        deliveryVO.setDeliveryState(0);
        String payId = OrderUtil.getPayId();
        deliveryVO.setPayId(payId);
        HashMap<String, Object> map = new HashMap<>();
        map.put("delivery", deliveryVO);
        int i = deliveryService.payPostfeeByCoin(map);
        try {
            if (i == 1) {
                redisService.del(uid + "_payPostfeeByCoin");
                return new ResponseVO(MallResponseEnum.SUCCESS, payId);
                //资产不足
            } 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);
            }
        } catch (Exception e) {
            redisService.del(uid + "_payPostfeeByCoin");
            if (StringUtil.isNullOrEmpty(e.getMessage())) {
                log.error(e.toString());
                return new ResponseVO<>(MallResponseEnum.DB_ERROR);
            }
            if (e.getMessage().contains("资产不足")) {
                return new ResponseVO<>(MallResponseEnum.ASSET_NOT_ENOUGH);
            }
        }
        return new ResponseVO(MallResponseEnum.SUCCESS, payId);

    }

    @ApiOperation(value = "快递提货")
    @PostMapping("/pickup")
    public ResponseVO<JSONObject> pickup(@ApiIgnore @RequestAttribute Header header, @RequestBody DeliveryVO deliveryVO) {
        String uid = header.getUid();
        String province = deliveryVO.getProvince();
        String skuId = deliveryVO.getSkuId();
        SkuVo sku = goodSkuService.getSkuVoBySkuId(skuId);
        if (sku == null) {
            //商品不存在或下架
            return new ResponseVO<>(MallResponseEnum.GOODS_NOT_BUY);
        }
        Integer num = deliveryVO.getNumber();
        //快递模板id
        String templateId = sku.getTemplateId();
        //总价格
        BigDecimal allPrice = sku.getOriginalPrice().multiply(new BigDecimal(num));
        //总重量
        BigDecimal allWeight = sku.getWeight().multiply(new BigDecimal(num));
        BigDecimal postFee = distributionTemplateService.getPrice(templateId, province, allPrice, num, allWeight);
        Object[] objects = new Object[]{
                province, deliveryVO.getCity(), deliveryVO.getCounty(), deliveryVO.getStreet(), deliveryVO.getDetailAddr()
        };
        StringBuffer sb = new StringBuffer();
        for (Object obj : objects) {
            sb.append(obj).append(",");
        }
        String address = sb.substring(0, sb.length() - 1);
        Delivery delivery = new Delivery();
        BeanUtils.copyProperties(deliveryVO, delivery);
        delivery.setOrderDeliveryId(OrderUtil.getDeliveryId());
        delivery.setUid(uid);
        delivery.setMerchantId(sku.getMerchantId());
        delivery.setGoodsId(sku.getGoodsId());
        delivery.setSkuId(sku.getSkuId());
        delivery.setCoin(sku.getCoinName());
        delivery.setName(sku.getName());
        delivery.setAddress(address);
        delivery.setPostFee(postFee);
        delivery.setNote("");
        delivery.setDeliveryState(0);
        HashMap<String, Object> map = new HashMap<>();
        map.put("delivery", delivery);
        map.put("ip", header.getIp());
        map.put("num", num);
        map.put("coin", sku.getCoinName());
        map.put("postFee", postFee);
        map.put("payType", deliveryVO.getPayType());
        JSONObject object = new JSONObject();
        try {
            if (!redisService.setNx(uid + "deliveryPostfee")) {
                return new ResponseVO<>(MallResponseEnum.OPERATION_OFTEN);
            }
            object = deliveryService.payDeliveryFee(map);
            redisService.del(uid + "deliveryPostfee");
        } catch (Exception e) {
            redisService.del(uid + "deliveryPostfee");
            if (StringUtil.isNullOrEmpty(e.getMessage())) {
                log.error(e.toString());
                return new ResponseVO<>(MallResponseEnum.DB_ERROR);
            }
            if (e.getMessage().contains("新增提货记录失败")) {
                return new ResponseVO<>(MallResponseEnum.DELIVERY_SAVE_FAILED);
            }
        }
        return new ResponseVO<>(MallResponseEnum.SUCCESS, object);
    }

    @ApiOperation(value = "分页查询用户提货申请")
    @PostMapping("/select")
    public ResponseVO<PageVO<DeliveryVO>> pageDelivery(@RequestBody OrderPageVo orderPageVo, @ApiIgnore @RequestAttribute Header header) {
        String searchKey = orderPageVo.getSearchKey();
        String state = orderPageVo.getOrderState();
        String assessState = orderPageVo.getAssessState();
        String page = orderPageVo.getPage();
        String size = orderPageVo.getSize();
        if (!LongValid.positiveLong(page)) {
            page = PageConst.DEFAULT_PAGE;
        }
        if (!LongValid.positiveLong(size)) {
            size = PageConst.DEFAULT_SIZE;
        }
        OrderQO orderQO = OrderQO.builder().assessState(assessState).type(0).uid(header.getUid()).orderState(state).searchKey(searchKey).page(Integer.valueOf(page)).size(Integer.valueOf(size)).build().init();
        PageVO<DeliveryVO> pageDelivery = deliveryService.pageDelivery(orderQO);
        return new ResponseVO<>(MallResponseEnum.SUCCESS, pageDelivery);
    }

    @ApiOperation(value = "分页查询售后订单")
    @PostMapping("/selectAfterSale")
    public ResponseVO<PageVO<DeliveryVO>> pageAfterSaleDelivery(@RequestBody OrderPageVo orderPageVo, @ApiIgnore @RequestAttribute Header header) {
        String page = orderPageVo.getPage();
        String size = orderPageVo.getSize();
        if (!LongValid.positiveLong(page)) {
            page = PageConst.DEFAULT_PAGE;
        }
        if (!LongValid.positiveLong(size)) {
            size = PageConst.DEFAULT_SIZE;
        }
        OrderQO orderQO = OrderQO.builder().type(0).uid(header.getUid()).page(Integer.valueOf(page)).size(Integer.valueOf(size)).build().init();
        PageVO<DeliveryVO> pageDelivery = deliveryService.pageAfterSaleDelivery(orderQO);
        return new ResponseVO<>(MallResponseEnum.SUCCESS, pageDelivery);
    }

    @ApiOperation(value = "提货单确认收货  参数：类型 string  name：orderDeliveryId")
    @PostMapping("/confirmReceipt")
    public ResponseVO<String> confirmReceipt(@ApiIgnore @RequestAttribute Header header, @RequestBody JSONObject data) {
        String orderDeliveryId = data.getString("orderDeliveryId");
        String uid = header.getUid();
        deliveryService.finish(uid, orderDeliveryId);
        return new ResponseVO<>(MallResponseEnum.SUCCESS);
    }

    @ApiOperation(value = "查询提货订单物流  参数：类型 string  name：orderDeliveryId" +
            "//快递状态 1 暂无记录 2 在途中 3 派送中 4 已签收 (完结状态) 5 用户拒签 6 疑难件 7 无效单 (完结状态) 8 超时单 9 签收失败 10 退回")
    @PostMapping("/queryLogistics")
    public ResponseVO<WuliuAddrVo> queryLogistics(@ApiIgnore @RequestAttribute Header header, @RequestBody JSONObject data) {
        String orderDeliveryId = data.getString("orderDeliveryId");
        DeliveryPO delivery = deliveryService.goodDelivery(orderDeliveryId);
        String expressDetail = deliveryService.queryLogistics(orderDeliveryId);
        WuliuAddrVo wuliuAddrVo = new WuliuAddrVo();
        wuliuAddrVo.setWuliu(expressDetail);
        wuliuAddrVo.setAddr(delivery.getAddress());
        wuliuAddrVo.setDeliveryTime(delivery.getDeliveryTime());
        wuliuAddrVo.setCreateTime(delivery.getCreateTime());
        return new ResponseVO<>(MallResponseEnum.SUCCESS, wuliuAddrVo);
    }

    @ApiOperation(value = "申请退货  参数：类型 string  name：orderDeliveryId")
    @PostMapping("/applyReturn")
    public ResponseVO<String> applyReturn(@ApiIgnore @RequestAttribute Header header, @RequestBody ReturnGoodsVo returnGoodsVo) {
        if (returnGoodsVo.getReturnReason().length() > 255) {
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
        DeliveryRefund byUidAndOrderDeliveryId = deliveryRefundService.getByUidAndOrderDeliveryId(header.getUid(), returnGoodsVo.getOrderDeliveryId());
        if (byUidAndOrderDeliveryId != null) {
            return new ResponseVO<>(MallResponseEnum.NOT_SUPPORT_RETURN_GOODS_TWO);
        }
        Integer status = deliveryService.getStatus(returnGoodsVo.getOrderDeliveryId());
        int i = deliveryService.returnGoods(header.getUid(), returnGoodsVo.getOrderDeliveryId());
        if (i == 1) {
            DeliveryRefund deliveryRefund = new DeliveryRefund();
            deliveryRefund.setOrderDeliveryId(returnGoodsVo.getOrderDeliveryId());
            deliveryRefund.setReturnReason(returnGoodsVo.getReturnReason());
            deliveryRefund.setReturnTime(System.currentTimeMillis());
            deliveryRefund.setReturnState(status);
            deliveryRefund.setUid(header.getUid());
            deliveryRefund.setReturnImg(returnGoodsVo.getReturnImg() == null ? "" : returnGoodsVo.getReturnImg().toJSONString());
            deliveryRefund.setReturnType(returnGoodsVo.getReturnType());
            deliveryRefundService.save(deliveryRefund);
            return new ResponseVO<>(MallResponseEnum.SUCCESS);
        } else {
            return new ResponseVO<>(MallResponseEnum.NOT_SUPPORT_RETURN_GOODS);
        }
    }

    @ApiOperation(value = "退货快递单号  参数：类型 string  name：orderDeliveryId")
    @PostMapping("/addExpressNo")
    public ResponseVO<String> addExpressNo(@ApiIgnore @RequestAttribute Header header, @RequestBody ReturnGoodsVo returnGoodsVo) {
        Delivery delivery = deliveryService.getByUidAndOrderDeliveryId(header.getUid(), returnGoodsVo.getOrderDeliveryId());
        DeliveryRefund deliveryRefund = deliveryRefundService.getByUidAndOrderDeliveryId(header.getUid(), returnGoodsVo.getOrderDeliveryId());
        if (delivery == null || deliveryRefund == null || delivery.getDeliveryState() != 8 || deliveryRefund.getState() != 2) {
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
        deliveryRefund.setReturnExpressNo(returnGoodsVo.getReturnExpressNo());
        deliveryRefund.setReturnExpressName(returnGoodsVo.getSimpleName());
        deliveryRefund.setState(3);
        deliveryRefund.setReturnTime(System.currentTimeMillis());
        deliveryRefundService.updateById(deliveryRefund);
        return new ResponseVO<>(MallResponseEnum.SUCCESS);
    }

    @ApiOperation(value = "获取快递公司  参数：类型 string  name：searchKey")
    @PostMapping("/getExpress")
    public ResponseVO<List<ExpressVo>> getExpress(@RequestBody JSONObject data) {
        String searchKey = data.getString("searchKey");
        searchKey = "%" + searchKey + "%";
        List<ExpressVo> list = deliveryRefundService.getExpress(searchKey);
        return new ResponseVO<>(MallResponseEnum.SUCCESS, list);
    }


    @ApiOperation(value = "退货详情  参数：类型 string  name：orderDeliveryId")
    @PostMapping("/returnGoodsDetail")
    public ResponseVO<ReturnGoodsDetail> returnGoodsDetail(@ApiIgnore @RequestAttribute Header header, @RequestBody JSONObject data) {
        String orderDeliveryId = data.getString("orderDeliveryId");
        ReturnGoodsDetail returnGoodsDetail = deliveryRefundService.getDetail(orderDeliveryId);
        if (returnGoodsDetail == null) {
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
        return new ResponseVO<>(MallResponseEnum.SUCCESS, returnGoodsDetail);
    }


    @ApiOperation(value = "取消退货  参数：类型 string  name：orderDeliveryId")
    @PostMapping("/revokeReturn")
    public ResponseVO<String> revokeReturn(@ApiIgnore @RequestAttribute Header header, @RequestBody JSONObject data) {
        String orderDeliveryId = data.getString("orderDeliveryId");
        int i = deliveryRefundService.revokeReturn(header.getUid(), orderDeliveryId);
        if (i == 1) {
            return new ResponseVO<>(MallResponseEnum.SUCCESS);
        } else {
            return new ResponseVO<>(MallResponseEnum.PARAMETER_ERR);
        }
    }


}
