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

import com.alibaba.fastjson.JSONObject;
import com.fzm.mall.server.front.asset.model.dto.OrderMainDTO;
import com.fzm.mall.server.front.asset.model.dto.OrderMainListDTO;
import com.fzm.mall.server.front.asset.model.dto.OrderMainUnitDTO;
import com.fzm.mall.server.front.asset.model.po.qo.OrderQO;
import com.fzm.mall.server.front.asset.model.vo.good.OrderMainVO;
import com.fzm.mall.server.front.asset.model.vo.order.OrderPageVo;
import com.fzm.mall.server.front.asset.model.vo.order.OrderVO;
import com.fzm.mall.server.front.asset.service.OrderMainService;
import com.fzm.mall.server.front.base.PageVO;
import com.fzm.mall.server.front.base.ResponseVO;
import com.fzm.mall.server.front.base.UserVO;
import com.fzm.mall.server.front.constant.*;
import com.fzm.mall.server.front.goods.model.GoodSale;
import com.fzm.mall.server.front.goods.model.GoodSku;
import com.fzm.mall.server.front.goods.model.GoodSpu;
import com.fzm.mall.server.front.goods.service.IGoodSaleService;
import com.fzm.mall.server.front.goods.service.IGoodSkuService;
import com.fzm.mall.server.front.goods.service.IGoodSpuService;
import com.fzm.mall.server.front.order.service.IGoodsCouponService;
import com.fzm.mall.server.front.order.service.IGoodsPromotionService;
import com.fzm.mall.server.front.order.service.IOrderService;
import com.fzm.mall.server.front.user.model.Header;
import com.fzm.mall.server.front.util.TimeUtil;
import com.fzm.mall.server.front.valid.CoinValid;
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.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.util.List;

/**
 * @author tdz
 * @date 2021/02/22 11:26
 */
@Api(tags = "商品订单接口", description = "用户下单，撤销订单等")
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping(value = "/mall/orderMain", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class OrderMainController {
    private final OrderMainService orderMainService;
    private final IGoodSkuService skuService;
    private final IGoodSpuService spuService;
    private final IGoodSaleService saleService;
    private final IOrderService orderService;


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

    @ApiOperation(value = "分页查询订单")
    @PostMapping("/select")
    public ResponseVO<PageVO<OrderVO>> pageOrder(@RequestBody OrderPageVo orderPageVo, @ApiIgnore @RequestAttribute Header header) {
        String page = orderPageVo.getPage();
        String size = orderPageVo.getSize();
        String orderState = orderPageVo.getOrderState();
        String searchKey = orderPageVo.getSearchKey();
        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()).orderState(orderState).searchKey(searchKey).page(Integer.valueOf(page)).size(Integer.valueOf(size)).build().init();
        PageVO<OrderVO> pageOrder = orderService.pageOrderVO(orderQO);
        return new ResponseVO<>(MallResponseEnum.SUCCESS, pageOrder);
    }

    @ApiOperation(value = "分页查询售后订单")
    @PostMapping("/selectAfterSale")
    public ResponseVO<PageVO<OrderVO>> pageAfterSaleOrder(@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<OrderVO> pageOrder = orderService.pageAfterSaleOrderVO(orderQO);
        return new ResponseVO<>(MallResponseEnum.SUCCESS, pageOrder);
    }

    @ApiOperation(value = "商品下单")
    @PostMapping
    public ResponseVO<OrderMainVO> order(@RequestBody OrderMainDTO orderMainDTO, @ApiIgnore @RequestAttribute(CommonConst.USER) UserVO userVO) {
        List<OrderMainListDTO> orders = orderMainDTO.getOrders();
        if (CollectionUtils.isEmpty(orders)) {
            return new ResponseVO<>(MallResponseEnum.GOOD_DELIVERY_ADDRESS_FORMAT);
        }
        String uid = userVO.getUid();
        log.info("商品下单：{} -> {}", uid, orderMainDTO);
        if (!TypeValid.one(orderMainDTO.getType())) {
            orderMainDTO.setType("0");
        }
        // 校验是否直接提货
        String delivery = orderMainDTO.getDelivery();
        if (!TypeValid.one(delivery)) {
            orderMainDTO.setDelivery("0");
        }
        if ("1".equals(delivery)) {
            if (StringUtils.isBlank(orderMainDTO.getUname()) || StringUtils.isBlank(orderMainDTO.getPhone()) || StringUtils.isBlank(orderMainDTO.getAddress())) {
                log.info("需完善收货地址信息");
                return new ResponseVO<>(MallResponseEnum.GOOD_DELIVERY_ADDRESS_FORMAT);
            }
        } else {
            orderMainDTO.setUname(null);
            orderMainDTO.setPhone(null);
            orderMainDTO.setAddress(null);
        }
        // 校验订单数组信息
        for (OrderMainListDTO order : orders) {
            // 检查商家编号
            String sid = order.getSid();
            if (!CommonValid.uid(sid)) {
                log.info("卖家编号错误：{}", sid);
                return new ResponseVO<>(MallResponseEnum.USER_ID_FORMAT);
            }
            if (uid.equals(sid)) {
                log.info("不可购买自己的商品");
                return new ResponseVO<>(MallResponseEnum.GOOD_CANT_ORDER_SELF);
            }
            // 检查抵扣积分数量
            String bpNum = order.getBpNum();
            if (StringUtils.isNotBlank(bpNum) && !LongValid.positiveLong(bpNum)) {
                log.info("积分数量格式错误：{}", bpNum);
                return new ResponseVO<>(MallResponseEnum.GOOD_BP_NUM_FORMAT);
            }
            // TODO 检查优惠券
            String coupon = order.getCoupon();
            if (StringUtils.isNotBlank(coupon)) {
                log.info("优惠券不存在：{}", bpNum);
                return new ResponseVO<>(MallResponseEnum.GOOD_COUPON_NOT_EXIST);
            }
            // 检查订单
            List<OrderMainUnitDTO> list = order.getList();
            if (CollectionUtils.isEmpty(list)) {
                log.info("订单为空");
                return new ResponseVO<>(MallResponseEnum.HTTP_MESSAGE_NOT_MATCH_EXCEPTION);
            }
            for (OrderMainUnitDTO unit : list) {
                // 检查数量
                String number = unit.getNumber();
                if (!LongValid.positiveLong(number)) {
                    log.info("购买数量必须大于零");
                    return new ResponseVO<>(MallResponseEnum.GOOD_NUMBER_FORMAT);
                }
                // 检查下单商品
                String coin = unit.getCoin();
                if (!CoinValid.good(coin)) {
                    log.info("下单商品不存在");
                    return new ResponseVO<>(MallResponseEnum.GOOD_NOT_EXIST);
                }

                if ("1".equals(delivery)) {
                    String note = unit.getNote();
                    if (StringUtils.isNotBlank(note) && note.length() > 256) {
                        log.info("提货备注格式错误");
                        return new ResponseVO<>(MallResponseEnum.GOOD_DELIVERY_NOTE_FORMAT);
                    }
                } else {
                    unit.setNote(null);
                }

                String gid = unit.getGid();
                GoodSku goodSku = skuService.skuUnitByGidCoin(gid, coin);
                if (goodSku == null) {
                    log.info("商品不存在");
                    return new ResponseVO<>(MallResponseEnum.GOOD_NOT_EXIST);
                }
                // 商品库存
                Integer stock = goodSku.getStock();
                if (stock < Integer.parseInt(number)) {
                    log.info("商品库存不足");
                    return new ResponseVO<>(MallResponseEnum.GOOD_STOCK_NOT_ENOUGH);
                }
                GoodSpu goodSpu = spuService.goodSpu(gid);
                String sid2 = goodSpu.getMerchantId();
                if (!sid.equals(sid2)) {
                    log.info("商户商品不存在：{} -> {}:{}", sid, sid2, gid);
                    return new ResponseVO<>(MallResponseEnum.GOOD_CANT_ORDER_SELF);
                }
                // 检查状态
                if (StateConst.ACTIVE_SUCCESS != goodSpu.getStatus()) {
                    log.info("商品不可购买");
                    return new ResponseVO<>(MallResponseEnum.GOOD_CANT_ORDER);
                }
                // 检查是否是预售
                GoodSale goodSale = saleService.goodSale(gid);
                if (PayTypeConst.PAY_TYPE_PRE_SELL_INT == goodSale.getPayType()) {
                    long timestamp = TimeUtil.timestamp();
                    // 检查是否在预售期限内
                    if (goodSale.getStartTime() > timestamp) {
                        log.info("预售商品还没开始");
                        return new ResponseVO<>(MallResponseEnum.goods_sale_NOT_START);
                    }
                    if (goodSale.getEndTime() < timestamp) {
                        log.info("预售商品已经结束");
                        return new ResponseVO<>(MallResponseEnum.goods_sale_ALREADY_END);
                    }
                }
                unit.setName(goodSpu.getName());
                unit.setAmount(goodSku.getPrice().toPlainString());
            }
        }
        // 校验完成，下单
        OrderMainVO orderMainVO = orderMainService.order(uid, orderMainDTO);
        if (orderMainVO == null) {
            log.info("下单失败：{}", uid);
            return new ResponseVO<>(MallResponseEnum.GOOD_ORDER_FAILURE);
        }
        log.info("下单成功：{}", uid);
        return new ResponseVO<>(MallResponseEnum.SUCCESS, orderMainVO);
    }


}
