package com.xxfc.platform.vehicle.biz;

import com.ace.cache.annotation.Cache;
import com.ace.cache.annotation.CacheClear;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.xxfc.platform.vehicle.common.RestResponse;
import com.xxfc.platform.vehicle.constant.RedisKey;
import com.xxfc.platform.vehicle.entity.AccompanyingItem;
import com.xxfc.platform.vehicle.mapper.AccompanyingItemMapper;
import com.xxfc.platform.vehicle.pojo.AddOrUpdateAccompanyingItem;
import com.xxfc.platform.vehicle.pojo.QueryAccompanyItemVo;
import com.xxfc.platform.vehicle.pojo.vo.AccompanyingItemVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

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

@Service
@Slf4j
public class AccompanyingItemBiz extends BaseBiz<AccompanyingItemMapper, AccompanyingItem> {

     @Autowired
     private RedisTemplate redisTemplate;

    @Resource(name = "redisTemplate")
    HashOperations  itemHashOperations;

    private static  final  String ACCOMPANY_ITEM="accompany:item";

    @Cache(key = RedisKey.ACCOMPANYING_ITEM_CACHE_ALL)
    public List<AccompanyingItem> getAll(){
        return mapper.selectAll();
    }

    /**
     * 按id获取列表，没有缓存
     * @param id
     * @return
     */
    public AccompanyingItem get(Integer id){
        return mapper.selectByPrimaryKey(id);
    }

    /**
     * 按id获取列表，没有缓存
     * @param ids
     * @return
     */
    public List<AccompanyingItem> getByIds(List<Integer> ids){
        return mapper.getByIdList(ids);
    }

    /**
     * 按页查询，
     * 注意，此处一共名称的模糊查询是预测其数据量较少，有变化后考虑加入全文索引
     * @param queryAccompanyItemVo
     * @return
     * @throws Exception
     */
    public PageDataVO<AccompanyingItem> getByPage(QueryAccompanyItemVo queryAccompanyItemVo) throws Exception{
        Map<String,String> params = BeanUtils.describe(queryAccompanyItemVo);
        PageHelper.startPage(queryAccompanyItemVo.getPage(),queryAccompanyItemVo.getLimit());
        List<AccompanyingItem> accompanyingItems = mapper.getAllByPage(params);
        PageInfo<AccompanyingItem> accompanyingItemsPageInfo = new PageInfo<>(accompanyingItems);
        return PageDataVO.pageInfo(accompanyingItemsPageInfo);
    }

    @CacheClear(key= RedisKey.ACCOMPANYING_ITEM_CACHE_ALL)
    public RestResponse<Integer> add( AddOrUpdateAccompanyingItem addOrUpdateAccompanyingItem) throws Exception{
        AccompanyingItem accompanyingItem = new AccompanyingItem();
        accompanyingItem.setId(null);
        BeanUtils.copyProperties(accompanyingItem,addOrUpdateAccompanyingItem);
        Integer effected = mapper.insertSelective(accompanyingItem);
        redisTemplate.delete(ACCOMPANY_ITEM);
        return RestResponse.suc();
    }

    @CacheClear(key= RedisKey.ACCOMPANYING_ITEM_CACHE_ALL)
    public RestResponse<Integer> update( AddOrUpdateAccompanyingItem addOrUpdateAccompanyingItem) throws Exception{
        AccompanyingItem accompanyingItem = new AccompanyingItem();
        BeanUtils.copyProperties(accompanyingItem,addOrUpdateAccompanyingItem);
        Integer effected = mapper.updateByPrimaryKeySelective(accompanyingItem);
        redisTemplate.delete(ACCOMPANY_ITEM);
        return RestResponse.suc();
    }

    @CacheClear(key= RedisKey.ACCOMPANYING_ITEM_CACHE_ALL)
    public RestResponse<Integer> del(Integer id){
        Integer effected = mapper.deleteByPrimaryKey(id);
        redisTemplate.delete(ACCOMPANY_ITEM);
        return RestResponse.suc();
    }

    public List<AccompanyingItemVo> listAllItem(List<Integer> types){
         String typeKey = null;
        if (CollectionUtils.isNotEmpty(types)){
            typeKey = types.stream().sorted(Integer::compareTo).map(String::valueOf).reduce("",(x, y)-> x+":"+y);
              String itemJson = (String) itemHashOperations.get(ACCOMPANY_ITEM,typeKey);
             if (!StringUtils.isEmpty(itemJson)){
                  return JSON.parseObject(itemJson,new TypeReference<List<AccompanyingItemVo>>(){});
             }
         }
         if (CollectionUtils.isEmpty(types)){
             typeKey= "all";
             String itemJson = (String) itemHashOperations.get(ACCOMPANY_ITEM, typeKey);
             if (!StringUtils.isEmpty(itemJson)){
                 return JSON.parseObject(itemJson,new TypeReference<List<AccompanyingItemVo>>(){});
             }
         }

        List<AccompanyingItemVo> accompanyingItemVos = new ArrayList<>();
        Example example = new Example(AccompanyingItem.class);
        Example.Criteria criteria = example.createCriteria();
        if (CollectionUtils.isNotEmpty(types)){
            criteria.andIn("type",types);
        }
        criteria.andEqualTo("isDel",0);
        List<AccompanyingItem> accompanyingItems = mapper.selectByExample(example);
        if (CollectionUtils.isEmpty(accompanyingItems)){
            return accompanyingItemVos;
        }

        List<AccompanyingItemVo> accompanyingItemVoList = accompanyingItems.stream().map(item -> {
            AccompanyingItemVo accompanyingItemVo = new AccompanyingItemVo();
            org.springframework.beans.BeanUtils.copyProperties(item, accompanyingItemVo);
            return accompanyingItemVo;
        }).sorted(Comparator.comparing(AccompanyingItemVo::getType).thenComparing(AccompanyingItemVo::getRank)).collect(Collectors.toList());
        itemHashOperations.put(ACCOMPANY_ITEM,typeKey,JSON.toJSONString(accompanyingItemVoList));
        return accompanyingItemVoList;
    }

}
