package com.hfkj.service.group.impl;

import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.utils.RedisUtil;
import com.hfkj.dao.BsStoreProductCategoryMapper;
import com.hfkj.entity.BsStoreProduct;
import com.hfkj.entity.BsStoreProductCategory;
import com.hfkj.entity.BsStoreProductCategoryExample;
import com.hfkj.service.group.BsStoreGroupService;
import com.hfkj.service.group.BsStoreProductCategoryService;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

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

/**
 * @className: BsStoreProductCategoryServiceImpl
 * @author: HuRui
 * @date: 2023/11/28
 **/
@Service("storeProductCategoryService")
public class BsStoreProductCategoryServiceImpl implements BsStoreProductCategoryService {

    @Resource
    private BsStoreProductCategoryMapper storeProductCategoryMapper;

    @Resource
    private BsStoreGroupService storeGroupService;

    @Resource
    private RedisUtil redisUtil;

    @Override
    public void editData(BsStoreProductCategory data) {
        if (data.getId() == null) {
            data.setCreateTime(new Date());
            data.setUpdateTime(new Date());
            storeProductCategoryMapper.insert(data);
        } else {
            data.setUpdateTime(new Date());
            storeProductCategoryMapper.updateByPrimaryKey(data);
        }
    }

    @Override
    public BsStoreProductCategory getCategory(Long id) {
        BsStoreProductCategory category = storeProductCategoryMapper.selectByPrimaryKey(id);
        if (category == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的分类id");
        }
        return category;
    }

    @Override
    public BsStoreProductCategory getCategoryBySort(Long storeId, Integer sort) {
        BsStoreProductCategoryExample example = new BsStoreProductCategoryExample();
        example.createCriteria().andStoreIdEqualTo(storeId).andSortEqualTo(sort);
        List<BsStoreProductCategory> list = storeProductCategoryMapper.selectByExample(example);
        if (!list.isEmpty()) {
          return list.get(0);
        }
        return null;
    }

    @Override
    public int getMaxSort(Long storeId) {
        Integer sort = storeProductCategoryMapper.queryMaxSort(storeId);
        if (sort == null) {
            return 0;
        }
        return sort;
    }

    @Override
    public void sortUp(Long id) {
        // 查询分类
        BsStoreProductCategory category = getCategory(id);

        // 查询交换顺序的数据
        BsStoreProductCategory categorySort = getCategoryBySort(category.getStoreId(), category.getSort() - 1);
        if (categorySort == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "已经到达最顶部");
        }
        categorySort.setSort(categorySort.getSort() + 1);
        editData(categorySort);

        category.setSort(category.getSort() - 1);
        editData(category);

        // 刷新缓存
        getStoreCategoryCache(category.getStoreId(), true);
    }

    @Override
    public void sortDown(Long id) {
        // 查询分类
        BsStoreProductCategory category = getCategory(id);

        // 查询交换顺序的数据
        BsStoreProductCategory categorySort = getCategoryBySort(category.getStoreId(), category.getSort() + 1);
        if (categorySort == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "已经到达最底部");
        }
        categorySort.setSort(categorySort.getSort() - 1);
        editData(categorySort);

        category.setSort(category.getSort() + 1);
        editData(category);

        // 刷新缓存
        getStoreCategoryCache(category.getStoreId(), true);
    }

    @Override
    public void delCategory(Long id) {
        // 查询分类
        BsStoreProductCategory category = getCategory(id);
        category.setStatus(0);
        editData(category);

        Map<String, Object> param = new HashMap<>();
        param.put("storeId", category.getStoreId());
        List<BsStoreProductCategory> categoryList = getCategoryList(param);
        for (int i = 0; i < categoryList.size(); i++) {
            categoryList.get(i).setSort(i+1);
            editData(categoryList.get(i));
        }

        // 刷新缓存
        getStoreCategoryCache(category.getStoreId(), true);
    }

    @Override
    public List<BsStoreProductCategory> getCategoryList(Map<String, Object> param) {
        BsStoreProductCategoryExample example = new BsStoreProductCategoryExample();
        BsStoreProductCategoryExample.Criteria criteria = example.createCriteria().andStatusNotEqualTo(0);

        if (MapUtils.getLong(param, "storeId") != null) {
            criteria.andStoreIdEqualTo(MapUtils.getLong(param, "storeId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "name"))) {
            criteria.andNameLike("%" + MapUtils.getString(param, "name") + "%");
        }

        example.setOrderByClause("sort");
        return storeProductCategoryMapper.selectByExample(example);
    }

    @Override
    public List<BsStoreProductCategory> getStoreCategoryCache(Long storeId, Boolean refresh) {
        // 不刷新
        if (!refresh) {
            Object obj = redisUtil.get("STORE_PRODUCT:" + storeId);
            if (obj != null) {
                return (List<BsStoreProductCategory>) obj;
            }
        }

        List<BsStoreProductCategory> categoryList = new ArrayList<>();

        Map<String,Object> param = new HashMap<>();
        param.put("storeId", storeId);

        // 分类列表
        List<BsStoreProductCategory> categoryData = getCategoryList(param);

        // 产品列表
        List<BsStoreProduct> storeProductData = storeGroupService.getStoreProductByList(param);

        for (BsStoreProductCategory category : categoryData) {
            category.setProductList(storeProductData.stream().filter(o -> o.getProductCategoryId() != null && o.getProductCategoryId().equals(category.getId())).collect(Collectors.toList()));
            categoryList.add(category);
        }

        redisUtil.set("STORE_PRODUCT:" + storeId, categoryList);
        return categoryList;
    }
}
