/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.gateway.goods_gatway.service.impl;



import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.druid.support.json.JSONUtils;
import liquibase.pro.packaged.G;
import org.springblade.common.enums.GoodsConstant;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.gateway.goods_gatway.service.IAppGoodsService;
import org.springblade.gateway.goods_gatway.vo.AppGoodsVO;
import org.springblade.gateway.goods_gatway.vo.GoodsManagementVO;
import org.springblade.gateway.goods_gatway.vo.GoodsMenuVO;
import org.springblade.gateway.goods_gatway.vo.SameCategoryPropertyVO;
import org.springblade.ldt.goods.entity.Goods;
import org.springblade.ldt.goods.entity.GoodsCategory;
import org.springblade.ldt.goods.entity.GoodsProperty;
import org.springblade.ldt.goods.mapper.GoodsMapper;
import org.springblade.ldt.goods.service.IGoodsCategoryService;
import org.springblade.ldt.goods.service.IGoodsPropertyService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;


/**
 *  服务实现类
 *
 * @author huangmp
 * @since 2021-09-17
 */
@Service
public class AppGoodsServiceImpl extends BaseServiceImpl<GoodsMapper, Goods> implements IAppGoodsService {

	@Resource
	private IGoodsCategoryService goodsCategoryService;
	@Resource
	private IGoodsPropertyService goodsPropertyService;
	@Resource
	private RedisTemplate redisTemplate;

	private final String GOODS_MENU_KEY_PREFIX="goods_menu:";

	@Override
	public List<GoodsMenuVO> getGoodsMenuList(Long shopId) {
		final String GOODS_MENU_KEY = GOODS_MENU_KEY_PREFIX + shopId;
		List<GoodsMenuVO> goodsMenuVOListInRedis = (List)JSONUtil.parseArray(redisTemplate.opsForValue().get(GOODS_MENU_KEY));
		if (CollUtil.isNotEmpty(goodsMenuVOListInRedis)) {
			return goodsMenuVOListInRedis;
		}
		List<GoodsCategory> goodsCategoryList = goodsCategoryService.list(Condition.getQueryWrapper(new GoodsCategory()).lambda()
			.eq(GoodsCategory::getShowStatus,true)
			.eq(GoodsCategory::getShopId,shopId));
		// 使用2个map去关联关系
		HashMap<String, List<Goods>> sameCategoryGoodsMap = new HashMap<>(goodsCategoryList.size());
		HashMap<String, GoodsMenuVO> goodsMenuVOMap = new HashMap<>(goodsCategoryList.size());
		for (GoodsCategory goodsCategory : goodsCategoryList) {
			sameCategoryGoodsMap.put(goodsCategory.getName(), new ArrayList<>());
			GoodsMenuVO goodsMenuVO = new GoodsMenuVO();
			goodsMenuVO.setGoodsCategoryName(goodsCategory.getName());
			goodsMenuVO.setGoodsCategoryName(goodsCategory.getName());
			goodsMenuVO.setDisplayOrder(goodsCategory.getDisplayOrder());
			goodsMenuVO.setGoodsCategoryShow(goodsCategory.getShowStatus());
			goodsMenuVOMap.put(goodsCategory.getName(), goodsMenuVO);
		}
		List<Goods> allGoods = this.list(Condition.getQueryWrapper(new Goods()).lambda().eq(Goods::getShopId,shopId));
		// 将所有商品分类
		for (Goods good : allGoods){
			if (sameCategoryGoodsMap.containsKey(good.getGoodsCategoryName())){
				sameCategoryGoodsMap.get(good.getGoodsCategoryName()).add(good);
			}
		}
		// 关联同类商品排好序后放到到对应的类别里
		for (Map.Entry<String, GoodsMenuVO> goodsMenuVOEntry : goodsMenuVOMap.entrySet()) {
			List<Goods> sameCategoryGoodsList = sameCategoryGoodsMap.get(goodsMenuVOEntry.getKey());
			sameCategoryGoodsList.sort(Comparator.comparingInt(Goods::getDisplayOrder));
			List<AppGoodsVO> goodsVos = new ArrayList<>();
			// 填充商品的属性
			for (Goods goods : sameCategoryGoodsList) {
				List<GoodsProperty> goodsPropertyList = goodsPropertyService.list(Condition.getQueryWrapper(new GoodsProperty()).lambda()
					.eq(GoodsProperty::getGoodsId,goods.getId())
					.eq(GoodsProperty::getShopId,shopId));
				HashMap<String, List<GoodsProperty>> propertyMap = new HashMap<>();
				for (GoodsProperty goodsProperty : goodsPropertyList) {
					if (propertyMap.containsKey(goodsProperty.getCategory())) {
						propertyMap.get(goodsProperty.getCategory()).add(goodsProperty);
					} else {
						propertyMap.put(goodsProperty.getCategory(), new ArrayList<GoodsProperty>() {{
							add(goodsProperty);
						}});
					}
					if (goodsProperty.getIsDefault() && GoodsConstant.GoodsPropertyCategory.ENUM_size.value.equals(goodsProperty.getCategory())){
						//重新设置商品的默认价格
						goods.setDefaultPrice(goodsProperty.getRebasePrice());
					}
				}
				List<SameCategoryPropertyVO> goodsPropertyVos = new ArrayList<>();
				for (Map.Entry<String, List<GoodsProperty>> entry : propertyMap.entrySet()) {
					// 属性类别->属性列表  转换成对象
					SameCategoryPropertyVO goodsPropertyVo = new SameCategoryPropertyVO();
					goodsPropertyVo.setCategory(entry.getKey());
					//除了加料其他全部必选
					goodsPropertyVo.setRequired(!GoodsConstant.GoodsPropertyCategory.ENUM_charging.value.equalsIgnoreCase(entry.getKey()));
					goodsPropertyVo.setPropertyList(entry.getValue());
					goodsPropertyVos.add(goodsPropertyVo);
				}
				AppGoodsVO appGoodsVO = new AppGoodsVO();
				BeanUtils.copyProperties(goods, appGoodsVO);
				appGoodsVO.setGoodsPropertyVos(goodsPropertyVos);
				appGoodsVO.setRealPrice(goods.getDefaultPrice());
				appGoodsVO.setNumber(0);
				goodsVos.add(appGoodsVO);
			}
			goodsMenuVOEntry.getValue().setGoodsList(goodsVos);
		}

		List<GoodsMenuVO> goodsMenuVOList = new ArrayList<>(goodsMenuVOMap.values());
		// 最后对菜单进行排序
		goodsMenuVOList.sort(Comparator.comparingInt(GoodsMenuVO::getDisplayOrder));
		if (CollUtil.isNotEmpty(goodsMenuVOList)) {
			redisTemplate.opsForValue().set(GOODS_MENU_KEY, JSONUtil.toJsonStr(goodsMenuVOList));
		}
		return goodsMenuVOList;
	}

    @Override
    public List<GoodsManagementVO> getGoodsList(Long shopId) {
        //获取分类列表
		List<GoodsCategory> goodsCategoryList = goodsCategoryService.list(Condition.getQueryWrapper(new GoodsCategory()).lambda()
			.eq(GoodsCategory::getShopId,shopId)
			.orderByAsc(GoodsCategory::getDisplayOrder));

		List<GoodsManagementVO> managementVOList = new ArrayList<>();
		for (GoodsCategory goodsCategory : goodsCategoryList) {
			GoodsManagementVO goodsManagementVO = new GoodsManagementVO();
			goodsManagementVO.setGoodsCategory(goodsCategory);
			//获取商品列表
			List<Goods> goodsList = this.list(Condition.getQueryWrapper(new Goods()).lambda()
				.eq(Goods::getGoodsCategoryName, goodsCategory.getName())
				.eq(Goods::getShopId, shopId)
				.orderByAsc(Goods::getDisplayOrder));
			goodsManagementVO.setGoods(goodsList);
			managementVOList.add(goodsManagementVO);
		}
		return managementVOList;
    }

	@Override
	public Boolean reload(Long shopId) {
		final String GOODS_MENU_KEY = GOODS_MENU_KEY_PREFIX + shopId;
		return redisTemplate.delete(GOODS_MENU_KEY);
	}

}
