package org.springblade.modules.api.controller;

/**
 * Author pangqijun
 * Date 2023/2/13
 * Description
 */

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springblade.common.constant.CommonConstant;
import org.springblade.common.enums.BusinessTypeEnum;
import org.springblade.common.enums.GoodsStateEnum;
import org.springblade.common.enums.OrderTypeEnum;
import org.springblade.common.enums.YesOrNoEnum;
import org.springblade.common.utils.SpringUtils;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.api.request.BeforeCheckRequest;
import org.springblade.modules.api.request.CartSubmitOrderRequest;
import org.springblade.modules.api.request.GoodsListRequest;
import org.springblade.modules.api.request.SubmitOrderRequest;
import org.springblade.modules.api.response.BeforeCheckResponse;
import org.springblade.modules.api.response.SubmitOrderResponse;
import org.springblade.modules.api.service.IMallService;
import org.springblade.modules.api.service.SubmitOrderService;
import org.springblade.modules.mall.entity.CategoryInfo;
import org.springblade.modules.mall.entity.GoodsInfo;
import org.springblade.modules.mall.entity.GoodsParams;
import org.springblade.modules.mall.entity.GoodsSpec;
import org.springblade.modules.mall.service.ICategoryInfoService;
import org.springblade.modules.mall.service.IGoodsInfoService;
import org.springblade.modules.mall.service.IGoodsParamsService;
import org.springblade.modules.mall.service.IGoodsSpecService;
import org.springblade.modules.mall.vo.GoodsInfoVO;
import org.springblade.modules.mall.wrapper.GoodsInfoWrapper;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Author pangqijun
 * Date 2023/2/13
 * Description
 */
@RestController
@RequestMapping(CommonConstant.API_URL + "/mall")
@Api(value = "商城模块接口", tags = "05.商城模块接口")
public class MallController extends BladeController {

    @Resource
    private ICategoryInfoService categoryInfoService;
    @Resource
    private IGoodsInfoService goodsInfoService;
    @Resource
    private IGoodsParamsService goodsParamsService;
    @Resource
    private IGoodsSpecService goodsSpecService;
    @Resource
    private IMallService mallService;

    @GetMapping("/category/list")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "查询分类列表", notes = "查询根分类，parentId传 0 ")
    public R<List<CategoryInfo>> list(@ApiParam(value = "父分类Id，不传默认为0", defaultValue = "0")
                                      @RequestParam(value = "parentId", required = false) Long parentId) {
        parentId = parentId == null ? 0L : parentId;
        return R.data(categoryInfoService.lambdaQuery().eq(CategoryInfo::getState, YesOrNoEnum.YES.getValue()).eq(CategoryInfo::getParentId, parentId).orderByAsc(CategoryInfo::getSort).list());
    }


    @GetMapping("/goods/page")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "商品分页接口", notes = "传入goodsInfo")
    public R<List<GoodsInfoVO>> list(GoodsListRequest request, Query query) {
        LambdaQueryWrapper<GoodsInfo> wrapper = Wrappers.lambdaQuery(GoodsInfo.class);
        if (request.getZoneType() != null) {
            wrapper.eq(GoodsInfo::getZoneType, request.getZoneType());
        }
        if (request.isSelfSupport()) {
            wrapper.eq(GoodsInfo::getBusinessType, BusinessTypeEnum.SELF_SUPPORT.getValue());
        }
        if (StrUtil.isNotBlank(request.getGoodsCategoryId())) {
            CategoryInfo categoryInfo = categoryInfoService.getById(request.getGoodsCategoryId());
            Assert.notNull(categoryInfo, "分类不存在");
            wrapper.likeRight(GoodsInfo::getGoodsCategoryId, request.getGoodsCategoryId());
//            if (categoryInfo.getParentId() == 0) {
//                wrapper.likeRight(GoodsInfo::getGoodsCategoryId, request.getGoodsCategoryId() + "-");
//            } else {
//                wrapper.likeRight(GoodsInfo::getGoodsCategoryId, categoryInfo.getParentId() + "-" + request.getGoodsCategoryId() + "-");
//            }
        }
        if (StrUtil.isNotBlank(request.getGoodsName())) {
            wrapper.like(GoodsInfo::getGoodsName, request.getGoodsName());
        }
        wrapper.orderByAsc(GoodsInfo::getSort);
        if (request.getIsRecom() != null) {
            wrapper.eq(GoodsInfo::getIsRecom, 1).orderByDesc(GoodsInfo::getTotalViews).orderByDesc(GoodsInfo::getTotalSales);
        } else {
            wrapper.orderByAsc(GoodsInfo::getSalePrice);
        }
        wrapper.eq(GoodsInfo::getIsSale, GoodsStateEnum.ON_SALE.getValue());
//        wrapper.ge(GoodsInfo::getTotalStock, 1);
        IPage<GoodsInfo> pages = goodsInfoService.page(Condition.getPage(query), wrapper);
        List<GoodsInfoVO> goodsInfoVOS = GoodsInfoWrapper.build().listVO(pages.getRecords());
        return R.data(goodsInfoVOS);
    }

    @GetMapping("/goods/detail")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "商品详情接口", notes = "传入goodsInfo")
    public R<GoodsInfoVO> detail(@RequestParam("id") Long id) {
        GoodsInfo detail = goodsInfoService.detail(id);
        GoodsInfoVO goodsInfoVO = GoodsInfoWrapper.build().entityVO(detail);
        List<GoodsParams> goodsParamsList = goodsParamsService.getByGoodsId(id);
        goodsInfoVO.setGoodsParamsList(goodsParamsList);
        List<GoodsSpec> goodsSpecList = goodsSpecService.lambdaQuery().eq(GoodsSpec::getGoodsId, id)
                .eq(GoodsSpec::getIsSale, GoodsStateEnum.ON_SALE.getValue()).orderByAsc(GoodsSpec::getSalePrice).list();
        goodsInfoVO.setGoodsSpecList(goodsSpecList);
        // 增加浏览量
        detail.setTotalViews(detail.getTotalViews() + 1);
        goodsInfoService.updateById(detail);
        return R.data(goodsInfoVO);
    }


    @ApiLog("提交下单（通用）")
    @PostMapping("/submit")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "提交下单")
    public R<SubmitOrderResponse> submitOrder(@Valid @RequestBody SubmitOrderRequest request) {
        if (StringUtil.isEmpty(request.getDistributeMode())) {
            request.setDistributeMode(1);
        }
        if (OrderTypeEnum.CUSTOM_WINE.getValue().equals(request.getOrderType())) {
            return R.fail("暂不支持该类型下单");
        }
        request.setUserId(AuthUtil.getUserId());
        SubmitOrderService submitOrderService = SpringUtils.getBean(OrderTypeEnum.getInstanceByValue(request.getOrderType()));
        Assert.notNull(submitOrderService, "获取实现类失败");
        String orderNo = submitOrderService.submitOrder(request);
        return data(new SubmitOrderResponse(orderNo));
    }

    @ApiLog("购物车提交下单")
    @PostMapping("/cart/submit")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "提交下单")
    public R<SubmitOrderResponse> cartSubmitOrder(@Valid @RequestBody CartSubmitOrderRequest request) {
        request.setUserId(AuthUtil.getUserId());
        String orderNo = mallService.cartSubmitOrder(request);
        return data(new SubmitOrderResponse(orderNo));
    }


    @GetMapping("/availableCheck")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "可售检测", notes = "此接口一般常应用于进入商品详情页后调取，以防个别商品部分规格不可售或无货导致用户无法下单")
    public R list(@ApiParam(value = "商品id") @RequestParam Long goodsInfoId,
                  @ApiParam(value = "用户地址id") @RequestParam(required = false) Long userAddressId) {
        if (userAddressId == null) {
            return R.fail("请先到设置后货地址");
        }
        // 更新商品浏览量
        goodsInfoService.addTotalView(goodsInfoId);
        // 自营商品暂时返回空的数据
        HashMap<String, List<Long>> map = new HashMap<>();
        ArrayList<Long> arrayList = new ArrayList<>();
        map.put("ban", arrayList);
//        List<GoodsSpec> list = goodsSpecService.lambdaQuery().eq(GoodsSpec::getGoodsId, goodsInfoId).eq(GoodsSpec::getIsSale, GoodsStateEnum.ON_SALE.getValue()).list();
//        List<Long> collect = list.stream().map(GoodsSpec::getId).collect(Collectors.toList());
        map.put("available", arrayList);
        return R.data(map);
    }


    @PostMapping("/beforeCheck")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "前置校验", notes = "此接口一般常应用于客户付款之前确认订单页面，该接口会返回当下订单传入的商品是否有不可售的商品，以保证商品下单后都能流转到供应链中台。")
    public R<BeforeCheckResponse> beforeCheck(@Valid @RequestBody BeforeCheckRequest request) {
        if (request.getUserAddressId() == null) {
            return R.fail("请选择收货地址");
        }
        BeforeCheckResponse beforeCheckResponse = new BeforeCheckResponse();
        GoodsInfo goodsInfo = goodsInfoService.getById(request.getGoodsInfoId());
        // 商品不包邮则获取设置的邮费
        if (goodsInfo.getIsFreeShipping() == 0) {
            beforeCheckResponse.setFreight(goodsInfo.getFreePrice().setScale(2, BigDecimal.ROUND_HALF_UP));
        }
        return R.data(beforeCheckResponse);
    }

}
