package com.gxwebsoft.shop.controller;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.gxwebsoft.cms.entity.Navigation;
import com.gxwebsoft.common.core.utils.JSONUtil;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.shop.entity.*;
import com.gxwebsoft.shop.param.GoodsCategoryParam;
import com.gxwebsoft.shop.param.GoodsSpecParam;
import com.gxwebsoft.shop.service.CartService;
import com.gxwebsoft.shop.service.GoodsCategoryService;
import com.gxwebsoft.shop.service.GoodsService;
import com.gxwebsoft.shop.service.GoodsSpecService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.gxwebsoft.common.core.utils.CommonUtil.toTreeData;

/**
 * 商品分类控制器
 *
 * @author 科技小王子
 * @since 2024-03-30 19:34:16
 */
@Api(tags = "商品分类管理")
@RestController
@RequestMapping("/api/shop/goods-category")
public class GoodsCategoryController extends BaseController {
  @Resource
  private GoodsCategoryService goodsCategoryService;
  @Resource
  private GoodsSpecService goodsSpecService;
  @Resource
  private GoodsService goodsService;
  @Resource
  private CartService cartService;

  @ApiOperation("查询商城菜单分类级商品数据(不联动)")
  @GetMapping("/listCategoryTree")
  public ApiResult<List<GoodsCategory>> listCategoryTree(GoodsCategoryParam param) {
    // 查询非店铺分类
    param.setMerchantId(0);
    final List<GoodsCategory> goodsCategoryList = goodsCategoryService.listRel(param);
    // 收集分类ID
    final Set<Integer> categoryIds = goodsCategoryList.stream().map(GoodsCategory::getCategoryId).collect(Collectors.toSet());
    if (categoryIds.isEmpty()) {
      return success("分类为空",goodsCategoryList);
    }
    // List转为树形结构
    final List<GoodsCategory> list = toTreeData(goodsCategoryList, 0, GoodsCategory::getParentId, GoodsCategory::getCategoryId, GoodsCategory::setChildren);
    // 查询所有商品
    final List<Goods> goods = goodsService.list(new LambdaQueryWrapper<Goods>()
      .in(Goods::getCategoryId, categoryIds)
      .eq(Goods::getIsShow, 1)
      .eq(Goods::getDeleted, 0));

    System.out.println("goods.size() = " + goods.size());

    final Map<Integer, List<Goods>> collectGoods = goods.stream().collect(Collectors.groupingBy(Goods::getCategoryId));

    final Set<Integer> goodsIds = goods.stream().map(Goods::getGoodsId).collect(Collectors.toSet());

    final List<GoodsSpec> specs = goodsSpecService.list(new LambdaQueryWrapper<GoodsSpec>().in(GoodsSpec::getGoodsId, goodsIds));

    final Map<Integer, List<GoodsSpec>> collectGoodsSpec = specs.stream().collect(Collectors.groupingBy(GoodsSpec::getGoodsId));

    list.forEach(d -> {
      d.setName(d.getTitle());
      final List<Goods> goodsList = collectGoods.get(d.getCategoryId());
      if (!CollectionUtils.isEmpty(goodsList)) {
        goodsList.forEach(v -> {
          final List<GoodsSpec> goodsSpecs = collectGoodsSpec.get(v.getGoodsId());
          if (!CollectionUtils.isEmpty(goodsSpecs)) {
            final GoodsSpec spec = goodsSpecs.get(0);
            v.setSpecValue(spec.getSpecValue());
            v.setGoodsSpecValue(JSONUtil.parseObject(spec.getSpecValue(), Object.class));
          }
        });
        d.setGoods(collectGoods.get(d.getCategoryId()));
      }
    });
    return success(list);
  }

  @ApiOperation("查询商城菜单分类级商品数据(不联动)")
  @GetMapping("/listCategoryParentIdTree/{parentId}")
  public ApiResult<List<GoodsCategory>> listCategoryParentIdTree(@PathVariable("parentId") Integer parentId) {
    // 查询非店铺分类
    final List<GoodsCategory> list = goodsCategoryService.list(new LambdaQueryWrapper<GoodsCategory>()
      .eq(GoodsCategory::getParentId,parentId)
        .eq(GoodsCategory::getType,0)
      .eq(GoodsCategory::getMerchantId,0));

    final Set<Integer> categoryIds = list.stream().map(GoodsCategory::getCategoryId).collect(Collectors.toSet());
    final List<Goods> goods = goodsService.list(new LambdaQueryWrapper<Goods>().in(Goods::getCategoryId, categoryIds));
    final Map<Integer, List<Goods>> collect = goods.stream().collect(Collectors.groupingBy(Goods::getCategoryId));

    final Map<Integer, List<Goods>> collectGoods = goods.stream().collect(Collectors.groupingBy(Goods::getCategoryId));

    final Set<Integer> goodsIds = goods.stream().map(Goods::getGoodsId).collect(Collectors.toSet());

    final List<GoodsSpec> specs = goodsSpecService.list(new LambdaQueryWrapper<GoodsSpec>().in(GoodsSpec::getGoodsId, goodsIds));

    final Map<Integer, List<GoodsSpec>> collectGoodsSpec = specs.stream().collect(Collectors.groupingBy(GoodsSpec::getGoodsId));

    LambdaQueryWrapper<Cart> wrapper = new LambdaQueryWrapper<>();
    wrapper.in(Cart::getGoodsId, goodsIds).eq(Cart::getSelected,1);
    if(ObjectUtil.isNotEmpty(getLoginUser())){
      wrapper.eq(Cart::getUserId,getLoginUser().getUserId());
    }
    final List<Cart> carts = cartService.list();
    final Map<Integer, List<Cart>> collectCart = carts.stream().collect(Collectors.groupingBy(Cart::getGoodsId));

    list.forEach(d -> {
      d.setName(d.getTitle());
      final List<Goods> goodsList = collectGoods.get(d.getCategoryId());
      if (!CollectionUtils.isEmpty(goodsList)) {
        goodsList.forEach(v -> {
          final List<GoodsSpec> goodsSpecs = collectGoodsSpec.get(v.getGoodsId());
          if (!CollectionUtils.isEmpty(goodsSpecs)) {
            final GoodsSpec spec = goodsSpecs.get(0);
            v.setSpecValue(spec.getSpecValue());
            v.setGoodsSpecValue(JSONUtil.parseObject(spec.getSpecValue(), Object.class));
          }
          final List<Cart> carts1 = collectCart.get(v.getGoodsId());

          if (ArrayUtil.isNotEmpty(carts1)) {
            final Cart cart = carts1.get(0);

              if (getLoginUser() != null && cart.getUserId().equals(getLoginUserId())) {
                v.setTotalNums(cart.getCartNum());
              }

          }

        });
        d.setGoods(goodsList);
      }
    });
    return success("请求成功",list);
  }

  @ApiOperation("查询门店菜单分类及菜品数据(联动)")
  @GetMapping("/listShopCategoryTree")
  public ApiResult<List<GoodsCategory>> listShopCategoryTree(GoodsCategoryParam param) {
    final List<GoodsCategory> list = goodsCategoryService.listRel(param);
    final Set<Integer> categoryIds = list.stream().map(GoodsCategory::getCategoryId).collect(Collectors.toSet());
    if (categoryIds.isEmpty()) {
      return success(list);
    }

    final List<Goods> goods = goodsService.list(new LambdaQueryWrapper<Goods>().in(Goods::getCategoryId, categoryIds).eq(Goods::getIsShow, 1).eq(Goods::getDeleted, 0));
    final Map<Integer, List<Goods>> collectGoods = goods.stream().collect(Collectors.groupingBy(Goods::getCategoryId));

    final Set<Integer> goodsIds = goods.stream().map(Goods::getGoodsId).collect(Collectors.toSet());

    final List<GoodsSpec> specs = goodsSpecService.list(new LambdaQueryWrapper<GoodsSpec>().in(GoodsSpec::getGoodsId, goodsIds));

    final Map<Integer, List<GoodsSpec>> collectGoodsSpec = specs.stream().collect(Collectors.groupingBy(GoodsSpec::getGoodsId));

    list.forEach(d -> {
      d.setName(d.getTitle());
      final List<Goods> goodsList = collectGoods.get(d.getCategoryId());
      if (!CollectionUtils.isEmpty(goodsList)) {
        goodsList.forEach(v -> {
          final List<GoodsSpec> goodsSpecs = collectGoodsSpec.get(v.getGoodsId());
          if (!CollectionUtils.isEmpty(goodsSpecs)) {
            final GoodsSpec spec = goodsSpecs.get(0);
            v.setSpecValue(spec.getSpecValue());
            v.setGoodsSpecValue(JSONUtil.parseObject(spec.getSpecValue(), Object.class));
          }
        });
        d.setGoods(collectGoods.get(d.getCategoryId()));
      }
    });
    return success(list);
  }


  @ApiOperation("分页查询商品分类")
  @GetMapping("/page")
  public ApiResult<PageResult<GoodsCategory>> page(GoodsCategoryParam param) {
    // 使用关联查询
    return success(goodsCategoryService.pageRel(param));
  }

  @ApiOperation("查询全部商品分类")
  @GetMapping()
  public ApiResult<List<GoodsCategory>> list(GoodsCategoryParam param) {
    // 使用关联查询
    return success(goodsCategoryService.listRel(param));
  }

  @ApiOperation("根据id查询商品分类")
  @GetMapping("/{id}")
  public ApiResult<GoodsCategory> get(@PathVariable("id") Integer id) {
    // 使用关联查询
    return success(goodsCategoryService.getByIdRel(id));
  }

  @ApiOperation("添加商品分类")
  @PostMapping()
  public ApiResult<?> save(@RequestBody GoodsCategory goodsCategory) {
    // 记录当前登录用户id
    User loginUser = getLoginUser();
    if (loginUser != null) {
      goodsCategory.setUserId(loginUser.getUserId());
    }
    if (goodsCategoryService.save(goodsCategory)) {
      return success("添加成功");
    }
    return fail("添加失败");
  }

  @ApiOperation("修改商品分类")
  @PutMapping()
  public ApiResult<?> update(@RequestBody GoodsCategory goodsCategory) {
    if (goodsCategoryService.updateById(goodsCategory)) {
      return success("修改成功");
    }
    return fail("修改失败");
  }

  @ApiOperation("删除商品分类")
  @DeleteMapping("/{id}")
  public ApiResult<?> remove(@PathVariable("id") Integer id) {
    if (goodsCategoryService.removeById(id)) {
      return success("删除成功");
    }
    return fail("删除失败");
  }

  @ApiOperation("批量添加商品分类")
  @PostMapping("/batch")
  public ApiResult<?> saveBatch(@RequestBody List<GoodsCategory> list) {
    if (goodsCategoryService.saveBatch(list)) {
      return success("添加成功");
    }
    return fail("添加失败");
  }

  @ApiOperation("批量修改商品分类")
  @PutMapping("/batch")
  public ApiResult<?> removeBatch(@RequestBody BatchParam<GoodsCategory> batchParam) {
    if (batchParam.update(goodsCategoryService, "category_id")) {
      return success("修改成功");
    }
    return fail("修改失败");
  }

  @ApiOperation("批量删除商品分类")
  @DeleteMapping("/batch")
  public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
    if (goodsCategoryService.removeByIds(ids)) {
      return success("删除成功");
    }
    return fail("删除失败");
  }

}
