package com.qs.mp.web.controller.api.admin;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicParameters;
import com.qs.mp.admin.domain.Goods;
import com.qs.mp.admin.domain.GoodsSku;
import com.qs.mp.admin.domain.GoodsTagRel;
import com.qs.mp.admin.domain.excel.GoodsExcel;
import com.qs.mp.admin.domain.excel.UserTicketOrderItemExcel;
import com.qs.mp.admin.domain.param.GoodsParam;
import com.qs.mp.admin.domain.param.GoodsQueryParam;
import com.qs.mp.admin.domain.param.GoodsUpdateSortWeightParam;
import com.qs.mp.admin.domain.vo.GoodsExportVO;
import com.qs.mp.admin.domain.vo.GoodsVO;
import com.qs.mp.admin.service.IGoodsService;
import com.qs.mp.admin.service.IGoodsSkuService;
import com.qs.mp.admin.service.IGoodsTagRelService;
import com.qs.mp.common.annotation.Log;
import com.qs.mp.common.core.domain.AjaxResult;
import com.qs.mp.common.core.page.TableDataInfo;
import com.qs.mp.common.enums.BusinessType;
import com.qs.mp.common.enums.ErrorCodeEnum;
import com.qs.mp.common.enums.GoodsStatusEnum;
import com.qs.mp.common.utils.LogUtil;
import com.qs.mp.utils.ExcelUtil;
import com.qs.mp.web.controller.common.BaseApiController;
import io.swagger.annotations.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;

import ma.glasnost.orika.MapperFacade;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * @auther liugl
 * @create 2022-03-09 23:45:48
 * @describe 商品管理前端控制器
 */
@Api(tags = "商品管理API")
@RestController
@RequestMapping("/api/v1/mp/admin/goods/*")
@Component
public class GoodsMgrController extends BaseApiController {

    @Autowired
    private IGoodsService goodsService;

    @Autowired
    private IGoodsSkuService goodsSkuService;

    @Autowired
    private IGoodsTagRelService goodsTagRelService;

    @Autowired
    private MapperFacade mapperFacade;


    /**
     * 查询商品列表, 支持翻页
     *
     * @return
     */
    @PostMapping("/list")
    @PreAuthorize("@ss.hasPermi('business:goods:list')")
    @ApiOperation(value = "商品列表接口", notes = "查询商品列表, 支持翻页")
    @ApiResponses(
            @ApiResponse(code = 200, message = "查询成功", response = Goods.class)
    )
    public TableDataInfo list(@RequestBody GoodsQueryParam queryParam) {
        // 商品标签
        List<Long> goodsIds = new ArrayList<>();
        if (null != queryParam.getTagId()) {
            List<GoodsTagRel> goodsTagRelList = goodsTagRelService.list(
                    new LambdaQueryWrapper<GoodsTagRel>().eq(GoodsTagRel::getTagId, queryParam.getTagId()));
            goodsIds = goodsTagRelList.stream().map(GoodsTagRel::getGoodsId)
                    .collect(Collectors.toList());
            if (CollectionUtils.isEmpty(goodsIds)) {
                return getDataTable(new ArrayList<>());
            }
        }
        startPage();
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<Goods>();
        queryWrapper.lambda()
                .like(null != queryParam && StringUtils.isNotBlank(queryParam.getTitle()), Goods::getTitle,
                        queryParam.getTitle());
        queryWrapper.lambda()
                .eq(null != queryParam.getGoodsId() && 0 != queryParam.getGoodsId(),
                        Goods::getGoodsId, queryParam.getGoodsId());
        // 供应商
        queryWrapper.lambda()
                .eq(null != queryParam.getSupplierId() && 0 != queryParam.getSupplierId(),
                        Goods::getSupplierId, queryParam.getSupplierId());
        // 成本
        queryWrapper.lambda()
                .ge(null != queryParam.getMinCost(), Goods::getCost, queryParam.getMinCost());
        queryWrapper.lambda()
                .le(null != queryParam.getMaxCost(), Goods::getCost, queryParam.getMaxCost());
        // 价格
        queryWrapper.lambda()
                .ge(null != queryParam.getMinValue(), Goods::getValue, queryParam.getMinValue());
        queryWrapper.lambda()
                .le(null != queryParam.getMaxValue(), Goods::getValue, queryParam.getMaxValue());

        // 盲豆兑换价格
        queryWrapper.lambda()
                .ge(null != queryParam.getMinExchange(), Goods::getExchangePrice, queryParam.getMinExchange());
        queryWrapper.lambda()
                .le(null != queryParam.getMaxExchange(), Goods::getExchangePrice, queryParam.getMaxExchange());

        // 状态
        queryWrapper.lambda()
                .eq(null != queryParam.getStatus(), Goods::getStatus, queryParam.getStatus());
        // 是否支持兑换
        queryWrapper.lambda().eq(null != queryParam.getExchangeShow(), Goods::getExchangeShow,
                queryParam.getExchangeShow());
        // 商品分类
        if (!CollectionUtils.isEmpty(queryParam.getCategoryIdList())) {
            queryWrapper.lambda().in(Goods::getCategoryId, queryParam.getCategoryIdList());
        }
        // 标签过滤的商品ID
        queryWrapper.lambda().in(null != queryParam.getTagId(), Goods::getGoodsId, goodsIds);
        queryWrapper.lambda().eq(Goods::getIsDeleted, 0);
        queryWrapper.orderByAsc("FIELD(`status`, 'init', 'on', 'off')");
        queryWrapper.lambda().orderByDesc(Goods::getGoodsId);
        List<Goods> goodsList = goodsService.list(queryWrapper);
        TableDataInfo res = getDataTable(goodsList);
        res.setRows(goodsList);
        return res;
    }


    @PostMapping("/update/sortWeight")
    @PreAuthorize("@ss.hasPermi('business:goods:edit')")
    @ApiOperation("更新商品排序权重")

    public AjaxResult updateSortWeight(@RequestBody GoodsUpdateSortWeightParam param) {

        Goods goods = new Goods();
        goods.setGoodsId(param.getGoodsId());
        goods.setSortWeight(param.getSortWeight());
        return AjaxResult.success(goodsService.updateById(goods));
    }


    /**
     * 获取商品详情信息
     *
     * @param
     * @return
     */
    @PostMapping(value = "/detail")
    @PreAuthorize("@ss.hasPermi('business:goods:query')")
    @ApiOperation("商品详情接口")
    @DynamicParameters(properties = {
            @DynamicParameter(name = "goodsId", value = "商品id", required = true, dataTypeClass = Long.class)
    })
    @ApiResponses(
            @ApiResponse(code = 200, message = "查询成功", response = GoodsVO.class)
    )
    public AjaxResult getGoodsDetail(@RequestBody JSONObject jsonObject) {
        Long goodsId = jsonObject.getLong("goodsId");
        if (null == goodsId || 0 == goodsId) {
            return error(ErrorCodeEnum.ERROR_CODE_1001);
        }
        Goods goods = goodsService.getById(goodsId);
        if (null == goods) {
            return error(ErrorCodeEnum.ERROR_CODE_1001);
        }
        GoodsVO goodsVo = new GoodsVO();
        BeanUtils.copyProperties(goods, goodsVo);
        // 查询SKU列表
        List<GoodsSku> skuList = new ArrayList<>();
        LambdaQueryWrapper<GoodsSku> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GoodsSku::getGoodsId, goods.getGoodsId());
        queryWrapper.orderByDesc(GoodsSku::getCreatedTime);
        skuList = goodsSkuService.list(queryWrapper);
        if (null != skuList && skuList.size() > 0) {
            goodsVo.setSkuList(skuList);
        }
        // 查询标签ID列表
        List<GoodsTagRel> goodsTagRelList = goodsTagRelService.list(
                new LambdaQueryWrapper<GoodsTagRel>().eq(GoodsTagRel::getGoodsId, goods.getGoodsId()));
        List<Long> tagIds = goodsTagRelList.stream().map(GoodsTagRel::getTagId)
                .collect(Collectors.toList());
        goodsVo.setTagIds(tagIds);

        return AjaxResult.success(goodsVo);
    }


    /**
     * 新增商品信息
     *
     * @param
     * @return
     */
    @Log(title = "新增商品", businessType = BusinessType.INSERT)
    @ApiOperation(value = "新增商品信息", notes = "后台商品管理新增商品")
    @PostMapping("/create")
    @PreAuthorize("@ss.hasPermi('business:goods:add')")
    public AjaxResult goodsCreate(@Validated @RequestBody GoodsParam goodsParam) {
        Goods goods = mapperFacade.map(goodsParam, Goods.class);
        // 1、校验名称是否重复（商品表）
        LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Goods::getTitle, goods.getTitle());
        queryWrapper.eq(Goods::getIsDeleted, 0);
        int titleCount = goodsService.count(queryWrapper);
        if (titleCount > 0) {
            return AjaxResult.error("商品名称" + goods.getTitle() + "已存在！");
        }
        String description = URLDecoder.decode(goodsParam.getDescription());
        goods.setDescription(description);
        goods.setStatus(GoodsStatusEnum.PUT_INIT);
        // 多SKU
        List<GoodsSku> skuList = goodsParam.getSkuList();
        if (goods.getMultiSku() == 1) {
            if ((null == skuList || skuList.size() == 0)) {
                return AjaxResult.error("商品" + goods.getTitle() + "不满足多SKU条件！");
            } else {
                GoodsSku firstGoodsSku = skuList.get(0);
                goods.setExchangePrice(firstGoodsSku.getExchangePrice());
                goods.setValue(firstGoodsSku.getValue());
                goods.setCost(firstGoodsSku.getCost());
                goods.setDiscountRate(firstGoodsSku.getDiscountRate());
                // 累计库存
                int totalQuantity = skuList.stream().mapToInt(GoodsSku::getQuantity).sum();
                goods.setQuantity(totalQuantity);
            }
        }
        if (null == goods.getOriginPrice()) {
            goods.setOriginPrice(0);
        }
        if (null == goods.getDiscountRate()) {
            goods.setDiscountRate(goodsParam.getDiscountRate());
        }
        // 3.插入数据
        try {
            goods.setSkuProp(getSkuProp(skuList));
            goodsService.saveGoods(goods, skuList, goodsParam.getTagIds());
        } catch (Exception e) {
            LogUtil.error(logger, e, "商品新增失败。");
            return AjaxResult.error("商品'" + goods.getTitle() + "'新增失败");
        }
        return AjaxResult.success("商品'" + goods.getTitle() + "'新增成功");
    }

    /**
     * 编辑商品信息
     *
     * @param
     * @return
     */
    @Log(title = "修改商品", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "编辑商品信息", notes = "后台商品管理修改商品信息")
    @PostMapping("/update")
    @PreAuthorize("@ss.hasPermi('business:goods:edit')")
    public AjaxResult goodsUpdate(@Validated @RequestBody GoodsParam goodsParam) {
        if (null == goodsParam || null == goodsParam.getGoodsId() || 0 == goodsParam.getGoodsId()) {
            return error(ErrorCodeEnum.ERROR_CODE_1001);
        }
        Goods oldGoods = goodsService.getById(goodsParam.getGoodsId());
        if (null == oldGoods || null == oldGoods.getGoodsId()) {
            return AjaxResult.error("商品'" + oldGoods.getTitle() + "'编辑失败，商品ID异常");
        }
        Goods goods = mapperFacade.map(goodsParam, Goods.class);
        // 1、校验名称是否重复（商品表）
        if (!goods.getTitle().equals(oldGoods.getTitle())) {
            LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Goods::getTitle, goods.getTitle());
            queryWrapper.eq(Goods::getIsDeleted, 0);
            int titleCount = goodsService.count(queryWrapper);
            if (titleCount > 0) {
                return AjaxResult.error("商品名称" + goods.getTitle() + "已存在！");
            }
        }
        String description = URLDecoder.decode(goodsParam.getDescription());
        goods.setDescription(description);
        // 多SKU
        List<GoodsSku> skuList = goodsParam.getSkuList();
        if (goods.getMultiSku() == 1) {
            if ((null == skuList || skuList.size() == 0)) {
                return AjaxResult.error("商品" + goods.getTitle() + "不满足多SKU条件！");
            } else {
                GoodsSku firstGoodsSku = skuList.get(0);
                goods.setExchangePrice(firstGoodsSku.getExchangePrice());
                goods.setValue(firstGoodsSku.getValue());
                goods.setCost(firstGoodsSku.getCost());
                goods.setOriginPrice(firstGoodsSku.getOriginPrice());
                if (null == firstGoodsSku.getOriginPrice()) {
                    goods.setOriginPrice(0);
                }
                if (null == firstGoodsSku.getDiscountRate()) {
                    goods.setDiscountRate(goodsParam.getDiscountRate());
                } else {
                    goods.setDiscountRate(firstGoodsSku.getDiscountRate());
                }
                // 累计库存
                int totalQuantity = skuList.stream().mapToInt(GoodsSku::getQuantity).sum();
                goods.setQuantity(totalQuantity);
            }
        }
        // 3.插入数据
        try {
            goods.setSkuProp(getSkuProp(skuList));
            goodsService.updateGoods(goods, skuList, goodsParam.getTagIds());
        } catch (Exception e) {
            LogUtil.error(logger, e, "商品更新失败。");
            return AjaxResult.error("商品'" + goods.getTitle() + "'更新失败");
        }
        return AjaxResult.success("商品'" + goods.getTitle() + "'更新成功");
    }

    // 获取商品的sku
    public String getSkuProp(List<GoodsSku> skuList) {
        if (CollectionUtils.isEmpty(skuList)) {
            return null;
        }
        LinkedHashMap<String, HashSet<String>> skuProp = new LinkedHashMap<>();
        for (GoodsSku sku : skuList) {
            if (StringUtils.isNotBlank(sku.getProperties())) {
                String[] skuAry = sku.getProperties().split(";");
                for (int i = 0; i < skuAry.length; i++) {
                    String item = skuAry[i];
                    String[] itemAry = item.split(":");
                    String key = itemAry[0];
                    String value = itemAry[1];
                    HashSet<String> valueSet = skuProp.get(key);
                    if (null == valueSet) {
                        valueSet = new HashSet<>();
                        skuProp.put(key, valueSet);
                    }
                    valueSet.add(value);
                }
            }
        }
        List<JSONObject> skuPropList = new ArrayList<>();
        for (String key : skuProp.keySet()) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("name", key);
            jsonObject.put("value", skuProp.get(key));
            skuPropList.add(jsonObject);
        }
        return JSONObject.toJSONString(skuPropList);
    }


    /**
     * 上下架商品
     *
     * @param
     * @return
     */
    @Log(title = "上下架商品", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "上下架商品", notes = "上下架商品")
    @PostMapping("/status")
    @PreAuthorize("@ss.hasPermi('business:goods:on')")
    public AjaxResult goodsStatus(@RequestBody JSONObject jsonObject) {
        String goodsId = jsonObject.getString("goodsId");

        GoodsStatusEnum status = GoodsStatusEnum.getStatusEnum(jsonObject.getString("status"));
        if (StringUtils.isBlank(goodsId) || null == status) {
            return error(ErrorCodeEnum.ERROR_CODE_1001);
        }
        try {
            goodsService.lambdaUpdate().set(Goods::getStatus, status).eq(Goods::getGoodsId, goodsId)
                    .update();
            // 查询代金券信息
        } catch (Exception e) {
            return AjaxResult.error("操作失败");
        }
        return AjaxResult.success("操作成功");
    }


    /**
     * 删除商品(假删)
     *
     * @param
     * @return
     */
    @Log(title = "删除商品", businessType = BusinessType.DELETE)
    @PostMapping(value = "/remove")
    @PreAuthorize("@ss.hasPermi('business:goods:remove')")
    public AjaxResult removeGoods(@RequestBody JSONObject jsonObject) {
        Long goodsId = jsonObject.getLong("goodsId");
        if (null == goodsId || 0 == goodsId) {
            return error(ErrorCodeEnum.ERROR_CODE_1001);
        }
        Goods goods = goodsService.getById(goodsId);
        if (null == goods || null == goods.getGoodsId() || 0 == goods.getGoodsId()) {
            return error(ErrorCodeEnum.ERROR_CODE_1001);
        }
        // 商品未下架， 不允许删除
        if (goods.getStatus().equals("on")) {
            return AjaxResult.error("商品未下架，不允许删除");
        }
        LambdaUpdateWrapper<Goods> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(Goods::getIsDeleted, 1);
        updateWrapper.eq(Goods::getGoodsId, goods.getGoodsId());
        boolean res = goodsService.update(updateWrapper);
        if (!res) {
            return AjaxResult.error("商品删除失败");
        }
        return AjaxResult.success("商品删除成功");
    }

    @ApiOperation("商品导出")
    @PostMapping("/export")
    @PreAuthorize("@ss.hasPermi('business:goods:export')")
    public AjaxResult export(@RequestBody GoodsQueryParam queryParam) {

        // 商品标签
        List<Long> goodsIds = new ArrayList<>();
        if (null != queryParam.getTagId()) {
            List<GoodsTagRel> goodsTagRelList = goodsTagRelService.list(
                    new LambdaQueryWrapper<GoodsTagRel>().eq(GoodsTagRel::getTagId, queryParam.getTagId()));
            goodsIds = goodsTagRelList.stream().map(GoodsTagRel::getGoodsId)
                    .collect(Collectors.toList());
            if (CollectionUtils.isEmpty(goodsIds)) {
                return AjaxResult.error("没有符合条件的商品信息");
            }
        }
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<Goods>();
        if (StringUtils.isNotBlank(queryParam.getTitle())) {
            queryWrapper.eq("t1.title", queryParam.getTitle());
        }

        if (queryParam.getGoodsId() != null && queryParam.getGoodsId() != 0) {
            queryWrapper.eq("t1.goods_id", queryParam.getGoodsId());
        }

        if (queryParam.getSupplierId() != null && queryParam.getSupplierId() != 0) {
            queryWrapper.eq("t1.supplier_id", queryParam.getSupplierId());
        }

        // 成本
        if (queryParam.getMinCost() != null) {
            queryWrapper.ge("t1.cost", queryParam.getMinCost());
        }
        if (queryParam.getMaxCost() != null) {
            queryWrapper.le("t1.cost", queryParam.getMaxCost());
        }

        // 价格
        if (queryParam.getMinValue() != null) {
            queryWrapper.ge("t1.value", queryParam.getMinValue());
        }
        if (queryParam.getMaxValue() != null) {
            queryWrapper.le("t1.value", queryParam.getMaxValue());
        }

        // 盲豆兑换价格
        if (queryParam.getMinExchange() != null) {
            queryWrapper.ge("t1.exchange_price", queryParam.getMinExchange());
        }

        if (queryParam.getMaxExchange() != null) {
            queryWrapper.le("t1.exchange_price", queryParam.getMaxExchange());
        }

        // 状态
        if (queryParam.getStatus() != null) {
            queryWrapper.eq("t1.status", queryParam.getStatus());
        }

        // 是否支持兑换
        if (queryParam.getExchangeShow() != null) {
            queryWrapper.eq("t1.exchange_show", queryParam.getExchangeShow());
        }

        // 商品分类
        if (!CollectionUtils.isEmpty(queryParam.getCategoryIdList())) {
            queryWrapper.in("t1.category_id", queryParam.getCategoryIdList());
        }


        // 标签过滤的商品ID
        if (queryParam.getTagId() != null) {
            queryWrapper.in("t1.goods_id", goodsIds);
        }
        queryWrapper.eq("t1.is_deleted", 0);

        queryWrapper.orderByDesc("t1.goods_id");

        List<GoodsExportVO> goodsExportVOList = goodsService.listGoodsExportVOByQueryWrapper(queryWrapper);
        if (CollectionUtils.isEmpty(goodsExportVOList)) {
            return AjaxResult.error("没有符合条件的商品信息");
        }

        List<GoodsExcel> goodsExcelList = new ArrayList<>();
        for (GoodsExportVO goodsExportVO : goodsExportVOList) {
            GoodsExcel goodsExcel = new GoodsExcel();
            BeanUtils.copyProperties(goodsExportVO, goodsExcel);

            if (goodsExportVO.getValue() != null) {
                goodsExcel.setValue(BigDecimal.valueOf(goodsExportVO.getValue()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
            }

            if (goodsExportVO.getCost() != null) {
                goodsExcel.setCost(BigDecimal.valueOf(goodsExportVO.getCost()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
            }

            goodsExcel.setExchangeShow(goodsExportVO.getExchangeShow() == 1 ? "是" : "否");

            if (goodsExportVO.getStatus() != null) {
                goodsExcel.setStatus(goodsExportVO.getStatus().getDesc());
            }

            goodsExcelList.add(goodsExcel);
        }

        ExcelUtil<GoodsExcel> util = new ExcelUtil<>(GoodsExcel.class);
        return util.exportExcel(goodsExcelList, "商品导出", false);

    }


}
