package com.centreproject.system.service.guestExperience.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.centreproject.common.constant.GuestConstants;
import com.centreproject.common.constant.KeyConstants;
import com.centreproject.common.utils.DateUtils;
import com.centreproject.system.domain.kpi.socialMedia.KpiSocialMediaSentimental;
import com.centreproject.system.domain.vo.SocialMediaDetailVo;
import com.centreproject.system.domain.vo.SocialMediaVo;
import com.centreproject.system.domain.vo.SocialVo;
import com.centreproject.system.mapper.kpi.KpiSocialMediaSentimentalMapper;
import com.centreproject.system.service.guestExperience.IKpiSocialMediaSentimentalService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhonglei.xu
 * @description 社交媒体情感分析服务实现类
 */
@Service
public class KpiSocialMediaSentimentalServiceImpl extends ServiceImpl<KpiSocialMediaSentimentalMapper, KpiSocialMediaSentimental>
        implements IKpiSocialMediaSentimentalService {


    @Autowired
    private KpiSocialMediaSentimentalMapper mapper;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    /**
     * Social Media Sentimental Analysis
     *
     * @return Social Media Sentimental Analysis
     */
    @Override
    public SocialVo getAnalysis() {
        String redisKey = KeyConstants.SOCIAL_MEDIA_SENTIMENTAL + DateUtils.getRiDate() + GuestConstants.LATEST_60_DAYS;

        // 1. 缓存检查（含空值缓存）
        SocialVo cached = (SocialVo) redisTemplate.opsForValue().get(redisKey);
        if (cached != null) {
            return cached;
        }else if (Boolean.TRUE.equals(redisTemplate.hasKey(redisKey))){
            return new SocialVo();
        }

        // 2. 数据查询
        List<KpiSocialMediaSentimental> currentLists = mapper.getSocialMediaByLast60DaysOfSum();
        if (CollectionUtils.isEmpty(currentLists)) {
            return new SocialVo();
        }

        // 3. 计算核心指标
        SocialVo result = new SocialVo();
        BigDecimal googleTotal = calculateTotal(currentLists, KpiSocialMediaSentimental::getGoogleReview);
        double tripAverage = calculateAverage(currentLists, KpiSocialMediaSentimental::getTripAdvisor);

        // 4. 环比计算
        List<KpiSocialMediaSentimental> preLists = mapper.getSocialMediaByLast60DaysTo120DaysOfSum();
        SocialMediaVo google = new SocialMediaVo();
        google.setValue(googleTotal);
        SocialMediaVo trip = new SocialMediaVo();
        trip.setValue(BigDecimal.valueOf(tripAverage));
        if (CollectionUtils.isNotEmpty(preLists)) {
            BigDecimal googleTotalPre = calculateTotal(preLists, KpiSocialMediaSentimental::getGoogleReview);
            double tripAveragePre = calculateAverage(preLists, KpiSocialMediaSentimental::getTripAdvisor);

            result.setGoogleReviews(buildSocialMediaVo(google,googleTotal, googleTotalPre));
            result.setTripAdvisor(buildSocialMediaVo(trip,BigDecimal.valueOf(tripAverage), BigDecimal.valueOf(tripAveragePre)));
        }

        // 5. 明细数据构建
        result.setGoogleReviews(buildDetailList(google,currentLists, KpiSocialMediaSentimental::getGoogleReview));
        result.setTripAdvisor(buildDetailList(trip, currentLists, KpiSocialMediaSentimental::getTripAdvisor));

        // 6. 缓存结果
        redisTemplate.opsForValue().set(redisKey, result, 1, TimeUnit.HOURS);
        return result;
    }

// --------------------- 工具方法 ---------------------

    /**
     * 计算BigDecimal字段平均值（自动过滤null值）
     */
    private double calculateAverage(List<KpiSocialMediaSentimental> list,
                                    Function<KpiSocialMediaSentimental, BigDecimal> mapper) {
        return list.parallelStream()
                .map(mapper)
                .filter(Objects::nonNull)
                .mapToDouble(BigDecimal::doubleValue)
                .average()
                .orElse(0.0);
    }

    /**
     * 构建带环比数据的SocialMediaVo对象
     */
    private SocialMediaVo buildSocialMediaVo(SocialMediaVo vo,BigDecimal currentVal, BigDecimal preVal) {

        if (currentVal.compareTo(BigDecimal.ZERO) != 0 && preVal.compareTo(BigDecimal.ZERO) != 0) {
            BigDecimal diff = currentVal.subtract(preVal)
                    .divide(currentVal, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
            vo.setPreValue(diff);
        }
        return vo;
    }

    /**
     * 构建明细列表
     */
    private SocialMediaVo buildDetailList(SocialMediaVo google,List<KpiSocialMediaSentimental> list,
                                          Function<KpiSocialMediaSentimental, BigDecimal> mapper) {
        List<SocialMediaDetailVo> details = list.stream()
                .map(kpi -> SocialMediaDetailVo.builder()
                        .parkCode(kpi.getParkCode())
                        .value(mapper.apply(kpi))
                        .build())
                .collect(Collectors.toList());
        google.setLists(details);
        return google;
    }

    /**
     * 计算BigDecimal字段总和（自动过滤null值）
     */
    private BigDecimal calculateTotal(List<KpiSocialMediaSentimental> list,
                                      Function<KpiSocialMediaSentimental, BigDecimal> mapper) {
        return list.parallelStream()
                .map(mapper)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    /**
     * Get World Cloud
     *
     * @param type 词云的类型 Google Evaluation Word Cloud/TripAdvisor Evaluation Word Cloud
     * @return World Cloud
     */
    @Override
    public String getWorldCloud(String type) {
        return null;
    }
}
