package com.ruoyi.wx.web.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.framework.recovery.domain.RecContent;
import com.ruoyi.framework.recovery.domain.RecSaleInfo;
import com.ruoyi.framework.recovery.domain.RecStores;
import com.ruoyi.framework.recovery.mapper.RecSaleInfoMapper;
import com.ruoyi.framework.recovery.service.IRecContentService;
import com.ruoyi.framework.recovery.service.IRecSaleInfoService;
import com.ruoyi.wx.web.domain.vo.RecStoresVo;
import com.ruoyi.wx.web.domain.vo.SaleInfoVo;
import com.ruoyi.wx.web.mapper.WxHomeMapper;
import com.ruoyi.wx.web.service.IWxHomeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Service
public class WxHomeServiceImpl implements IWxHomeService {
    @Autowired
    private IRecSaleInfoService recSaleInfoService;

    @Autowired
    private IRecContentService recContentService;

    @Autowired
    private RecSaleInfoMapper saleInfoMapper;

    @Autowired
    private WxHomeMapper wxHomeMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(9);

    private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();

    @SuppressWarnings("unused")
    private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(9, 9, 1000, TimeUnit.MILLISECONDS,
            WORK_QUEUE, HANDLER);

    @Override
    public AjaxResult getIndex() throws ExecutionException, InterruptedException {
        AjaxResult result = new AjaxResult();
        // 查询最近创建的活动并且处于活动期间的内容
        DateTime dateTime = DateUtil.beginOfDay(new Date());
        Date startTime = DateUtil.offsetDay(dateTime, -1);
        Date endTime = DateUtil.offsetDay(dateTime, 1);
        Callable<List<RecSaleInfo>> saleInfoCallable = () -> recSaleInfoService.selectRecSaleInfoByTime(startTime, endTime);
        // 评论
        Callable<List<RecContent>> contentCallable = () -> recContentService.selectRecContentList(new RecContent());
        FutureTask<List<RecSaleInfo>> saleInfoTask = new FutureTask<>(saleInfoCallable);
        FutureTask<List<RecContent>> contentTask = new FutureTask<>(contentCallable);
        executorService.submit(saleInfoTask);
        executorService.submit(contentTask);
        List<RecContent> contents = contentTask.get();
        String display = wxHomeMapper.selectLotteryDisplay("is_lottery");
        for (RecContent content : contents) {
            Object value = redisCache.getCacheMapValue(Constants.THUMBS_UP, "like" + content.getId());
            if (value != null) {
                content.setThumbs(Long.parseLong(value.toString()));
            }
            redisCache.setCacheMapValue(Constants.THUMBS_UP, "like" + content.getId(), content.getThumbs());
        }
        List<RecSaleInfo> saleInfos = saleInfoTask.get();
        boolean flag = false;
        // 若当前没有置顶，则默认第一个为置顶
        for (RecSaleInfo info : saleInfos) {
            if ('Y' == info.getTopUp()) {
                flag = true;
                break;
            }
        }
        if (!flag) {
            saleInfos.get(0).setTopUp('Y');
        }
        result.put("saleInfo", saleInfos);
        result.put("content", contents);
        result.put("is_lottery", display);
        return result;
    }

    @Override
    public List<SaleInfoVo> getSaleInfo(Long id) {
        RecSaleInfo saleInfo = saleInfoMapper.selectRecSaleInfoById(id);
        // 获取到商品id，并将商品id转换为Integer到数据库中查询
        List<String> ids = Arrays.asList(saleInfo.getStoreId().split(","));
        // 根据商品获取所有门店信息
        List<RecStores> stores = wxHomeMapper.selectRecStoresByCommondityIds(ids);
        Map<String, List<RecStores>> cityMap = stores.stream().filter(vo -> StringUtils.isNotEmpty(vo.getCity())).collect(Collectors.groupingBy(RecStores::getCity));
        List<SaleInfoVo> result = new ArrayList<>();
        SaleInfoVo saleInfoVo = new SaleInfoVo();
        List<RecStoresVo> cityList = new ArrayList<>();
        BeanUtils.copyProperties(saleInfo, saleInfoVo);
        // 插入门店详情
        cityMap.forEach((key, value) -> {
            RecStoresVo storesVo = new RecStoresVo();
            storesVo.setCity(key);
            storesVo.setStores(value);
            cityList.add(storesVo);
        });
        saleInfoVo.setStores(cityList);
        result.add(saleInfoVo);
        return result;
    }

    @Override
    public List<SaleInfoVo> getSaleCalendar() {
        List<RecSaleInfo> recSaleInfos = saleInfoMapper.selectRecSaleInfoList(new RecSaleInfo());
        List<SaleInfoVo> result = new ArrayList<>();
        for (RecSaleInfo info : recSaleInfos) {
            SaleInfoVo vo = new SaleInfoVo();
            BeanUtils.copyProperties(info, vo);
            result.add(vo);
        }
        return result;
    }

    @Override
    public Long thumbs(Long id) {
        Object value = redisCache.getCacheMapValue(Constants.THUMBS_UP, "like" + id);
        long increment = 0L;
        if (value == null) {
            increment = stringRedisTemplate.opsForHash().increment(Constants.THUMBS_UP, "like" + id, 1);
        } else if (value instanceof Integer) {
            increment = stringRedisTemplate.opsForHash().increment(Constants.THUMBS_UP, "like" + id, 1);
        } else if (value instanceof Long longValue) {
            // 如果值是 Long 类型，将其转换为 Integer 类型并更新
            int intValue = longValue.intValue();  // 转换为 Integer
            // 更新 Redis 中的值为 Integer 类型
            stringRedisTemplate.opsForHash().put(Constants.THUMBS_UP, "like" + id, Integer.toString(intValue));
            // 执行自增操作
            increment = stringRedisTemplate.opsForHash().increment(Constants.THUMBS_UP, "like" + id, 1);
        }
        if (increment <= 0) {
            return 0L;
        }
        Object mapValue = redisCache.getCacheMapValue(Constants.THUMBS_UP, "like" + id);
        long result = 0L;
        if (mapValue instanceof Integer) {
            result = ((Integer) mapValue).longValue();
        } else if (mapValue instanceof Long) {
            result = (Long) mapValue;
        }
        return result;
    }
}
