package com.fs.live.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Date;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.spring.SpringUtils;
import com.fs.live.vo.ColumnsConfigVo;
import com.fs.live.vo.DateRange;
import com.fs.live.vo.RecentLiveDataVo;
import com.fs.live.vo.TrendDataVO;
import jodd.util.CollectionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fs.live.mapper.LiveDataMapper;
import com.fs.live.domain.LiveData;
import com.fs.live.service.ILiveDataService;
import org.springframework.util.CollectionUtils;

/**
 * 直播数据Service业务层处理
 *
 * @author fs
 * @date 2025-03-05
 */
@Service
public class LiveDataServiceImpl extends ServiceImpl<LiveDataMapper, LiveData> implements ILiveDataService {

    @Autowired
    private LiveDataMapper liveDataMapper;
    private final RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private final String COLUMNS_CONFIG = "columnsConfigKey";

    /**
     * 查询直播数据
     *
     * @param liveId 直播数据主键
     * @return 直播数据
     */
    @Override
    public LiveData selectLiveDataByLiveId(Long liveId)
    {
        return baseMapper.selectLiveDataByLiveId(liveId);
    }

    /**
     * 查询直播数据列表
     *
     * @param liveData 直播数据
     * @return 直播数据
     */
    @Override
    public List<LiveData> selectLiveDataList(LiveData liveData)
    {
        return baseMapper.selectLiveDataList(liveData);
    }

    /**
     * 新增直播数据
     *
     * @param liveData 直播数据
     * @return 结果
     */
    @Override
    public int insertLiveData(LiveData liveData)
    {
        liveData.setCreateTime(DateUtils.getNowDate());
        return baseMapper.insertLiveData(liveData);
    }

    /**
     * 修改直播数据
     *
     * @param liveData 直播数据
     * @return 结果
     */
    @Override
    public int updateLiveData(LiveData liveData)
    {
        return baseMapper.updateLiveData(liveData);
    }

    /**
     * 批量删除直播数据
     *
     * @param liveIds 需要删除的直播数据主键
     * @return 结果
     */
    @Override
    public int deleteLiveDataByLiveIds(Long[] liveIds)
    {
        return baseMapper.deleteLiveDataByLiveIds(liveIds);
    }

    /**
     * 删除直播数据信息
     *
     * @param liveId 直播数据主键
     * @return 结果
     */
    @Override
    public int deleteLiveDataByLiveId(Long liveId)
    {
        return baseMapper.deleteLiveDataByLiveId(liveId);
    }
    /**
     * 查询所有正在直播的直播间iD
     * @return
     */
    @Override
    public List<Long> getAllLiveIds() {
        return baseMapper.getAllLiveIds();
    }

    @Override
    public List<RecentLiveDataVo> getRecentLive() {
        return liveDataMapper.getRecentLive();
    }

    @Override
    public List<RecentLiveDataVo> getLiveTop(String rankType) {
        return liveDataMapper.getLiveTop(rankType);
    }
    /**
     * 查询直播趋势数据
     * @param type
     * @param selectedDate
     * @return
     */
    @Override
    public TrendDataVO getTrendData(String type, String selectedDate,String category) {
        //DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date = LocalDate.parse(selectedDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        DateRange currentRange = getDateRange(type, date, 0);
        DateRange previousRange = getDateRange(type, date, -1);
        DateRange chartRange = getChartDateRange(type, date); // 天 / 10 周 / 12 月
        // 查询当前周期数据
        TrendDataVO currentData = liveDataMapper.getCurrentData(currentRange.getStart(), currentRange.getEnd());
        if (currentData == null) {
            currentData = new TrendDataVO();
        }
        // 查询上一周期数据
        TrendDataVO prevData = liveDataMapper.getPreviousData(previousRange.getStart(), previousRange.getEnd());
        if (prevData == null) {
            prevData = new TrendDataVO();
        }
        List<Map<String, Object>> chartRawData = liveDataMapper.getChartData(chartRange.getStart(), chartRange.getEnd(), type,category.trim());
        List<String> dates = new ArrayList<>();
        List<Integer> data = new ArrayList<>();

        for (Map<String, Object> row : chartRawData) {
            String dateRange = (String) row.get("date_range");
            Integer views = ((Number) row.get("views")).intValue();

            dates.add(dateRange);
            data.add(views);
        }

        currentData.setDates(dates);
        currentData.setData(data);
        //计算和上一个周期相比的变化百分比
        currentData.setViewsChange(calcChange(
                currentData.getViews() != null ? currentData.getViews() : 0,
                prevData.getPrevViews() != null ? prevData.getPrevViews() : 0));

        currentData.setVisitorsChange(calcChange(
                currentData.getVisitors() != null ? currentData.getVisitors() : 0,
                prevData.getPrevVisitors() != null ? prevData.getPrevVisitors() : 0));

        currentData.setStreamsChange(calcChange(
                currentData.getStreams() != null ? currentData.getStreams() : 0,
                prevData.getPrevStreams() != null ? prevData.getPrevStreams() : 0));

        currentData.setPvChange(calcChange(
                currentData.getPv() != null ? currentData.getPv() : 0,
                prevData.getPrevPv() != null ? prevData.getPrevPv() : 0));

        currentData.setUvChange(calcChange(
                currentData.getUv() != null ? currentData.getUv() : 0,
                prevData.getPrevUv() != null ? prevData.getPrevUv() : 0));

        return currentData;
    }



    /**
     *
     * @param current 当前周期
     * @param previous 上一周期
     * @return
     */
    private double calcChange(Integer current, Integer previous) {
        if (current==previous){return 0.0;}
        if (previous == null || previous == 0) {return 100.0;}
        double change = ((double) (current - previous) / previous) * 100;
        BigDecimal bd = new BigDecimal(change).setScale(2, RoundingMode.HALF_UP);
        return bd.doubleValue();
    }
    /**
     * 获取当前/上个周期的时间范围
     */
    private DateRange getDateRange(String type, LocalDate date, int offset) {
        LocalDate start, end;
        switch (type) {
            case "week":
                start = date.minusWeeks(-offset).with(DayOfWeek.MONDAY); // 该周的周一
                end = start.plusDays(6); // 该周的周日
                break;
            case "month":
                start = date.minusMonths(-offset).withDayOfMonth(1); // 该月第一天
                end = start.plusMonths(1).minusDays(1); // 该月最后一天
                break;
            default: // "day"
                start = date.minusDays(Math.abs(offset)); // 计算 start
                end = date;
                break;
        }
        return new DateRange(start.toString(), end.toString());
    }


    /**
     * 获取折线图查询范围
     */
    private DateRange getChartDateRange(String type, LocalDate date) {
        LocalDate start, end;
        switch (type) {
            case "week":
                start = date.minusWeeks(9).with(DayOfWeek.MONDAY);
                end = date.with(DayOfWeek.SUNDAY);
                break;
            case "month":
                start = date.minusMonths(11).withDayOfMonth(1);
                end = date.withDayOfMonth(date.lengthOfMonth());
                break;
            default: // day
                start = date.minusDays(30);
                end = date;
                break;
        }
        return new DateRange(start.format(FORMATTER), end.format(FORMATTER));
    }
    /**
     * @param  userId 当前登录用户id
     * 查询表格字段配置
     * @return
     */
    /*@Override
    public List<ColumnsConfigVo> getColumnsConfig(String userId) {
        List<Object> cacheList = redisCache.getCacheObject(COLUMNS_CONFIG + userId + ":");
        if (cacheList == null){
            List<ColumnsConfigVo> columns = new ArrayList<>();
            *//*columns.add(new ColumnsConfigVo("customer_name", "客户名", "ENABLE"));
            columns.add(new ColumnsConfigVo("live_room", "直播间", "ENABLE"));
            columns.add(new ColumnsConfigVo("follower", "跟进人", "ENABLE"));*//*
            columns.add(new ColumnsConfigVo("department", "归属部门", "ENABLE"));
            columns.add(new ColumnsConfigVo("created_time", "客户创建时间", "ENABLE"));
            columns.add(new ColumnsConfigVo("contact_method", "联系方式", "ENABLE"));
            columns.add(new ColumnsConfigVo("order_goods", "去下单实物商品", "ENABLE"));
            columns.add(new ColumnsConfigVo("share_live_count", "分享直播间次数", "ENABLE"));
            columns.add(new ColumnsConfigVo("reply_count", "答题次数", "ENABLE"));
            columns.add(new ColumnsConfigVo("correct_reply_count", "答题正确次数", "ENABLE"));
            columns.add(new ColumnsConfigVo("reply_accuracy", "答题正确率", "ENABLE"));
            columns.add(new ColumnsConfigVo("first_visit_time", "首次访问时间", "ENABLE"));
            columns.add(new ColumnsConfigVo("first_visit_type", "首次访问类型", "ENABLE"));
            columns.add(new ColumnsConfigVo("max_live_stay_time", "直播最长停留时间", "ENABLE"));
            columns.add(new ColumnsConfigVo("total_live_watch_time", "直播累计观看时长", "ENABLE"));
            columns.add(new ColumnsConfigVo("max_replay_stay_time", "回放最长停留时间", "ENABLE"));
            columns.add(new ColumnsConfigVo("total_replay_watch_time", "回放累计观看时长", "ENABLE"));
            columns.add(new ColumnsConfigVo("total_watch_time", "总累计观看时长", "ENABLE"));
            columns.add(new ColumnsConfigVo("last_exit_time", "最后一次退出时间", "ENABLE"));
            columns.add(new ColumnsConfigVo("speak_count", "发言次数", "ENABLE"));
            columns.add(new ColumnsConfigVo("visit_form_name", "访问表单名称", "ENABLE"));
            columns.add(new ColumnsConfigVo("submit_form_name", "提交表单名称", "ENABLE"));
            columns.add(new ColumnsConfigVo("pending_payment_goods", "待支付商品", "ENABLE"));
            columns.add(new ColumnsConfigVo("purchased_goods", "购买商品名称", "ENABLE"));
            columns.add(new ColumnsConfigVo("last_purchase_time", "最近商品购买时间", "ENABLE"));
            columns.add(new ColumnsConfigVo("spending_amount", "消费金额", "ENABLE"));
            columns.add(new ColumnsConfigVo("coupon_name", "优惠券名称", "ENABLE"));
            columns.add(new ColumnsConfigVo("is_participate_lottery", "是否参与抽奖", "ENABLE"));
            columns.add(new ColumnsConfigVo("is_winner", "是否中奖", "ENABLE"));
            columns.add(new ColumnsConfigVo("claimed_watch_reward", "领取观看奖励", "ENABLE"));
            columns.add(new ColumnsConfigVo("reward_withdrawal_amount", "奖励提现金额", "ENABLE"));
            columns.add(new ColumnsConfigVo("reward_type", "奖励类型", "ENABLE"));
            columns.add(new ColumnsConfigVo("red_envelope_count", "红包领取次数", "ENABLE"));
            columns.add(new ColumnsConfigVo("click_external_goods", "点击外链商品次数", "ENABLE"));
            columns.add(new ColumnsConfigVo("is_request_mic", "是否申请连麦", "ENABLE"));
            columns.add(new ColumnsConfigVo("is_on_mic", "是否连麦", "ENABLE"));
            columns.add(new ColumnsConfigVo("advertiser", "广告商", "ENABLE"));
            columns.add(new ColumnsConfigVo("promotion_account", "推广账户", "ENABLE"));
            columns.add(new ColumnsConfigVo("promotion_level_1", "推广一级", "ENABLE"));
            columns.add(new ColumnsConfigVo("promotion_level_2", "推广二级", "ENABLE"));
            columns.add(new ColumnsConfigVo("site_placement", "站点投放", "ENABLE"));
            columns.add(new ColumnsConfigVo("channel", "渠道", "ENABLE"));
            columns.add(new ColumnsConfigVo("tags", "标签", "ENABLE"));
            columns.add(new ColumnsConfigVo("follow_status", "跟进状态", "ENABLE"));
            columns.add(new ColumnsConfigVo("sharer_name", "分享人名称", "ENABLE"));
            columns.add(new ColumnsConfigVo("customer_id", "客户ID", "ENABLE"));
            columns.add(new ColumnsConfigVo("union_id", "unionId", "ENABLE"));
            columns.add(new ColumnsConfigVo("source", "来源", "ENABLE"));
            columns.add(new ColumnsConfigVo("landing_page", "着陆页", "ENABLE"));
            columns.add(new ColumnsConfigVo("live_room_url", "直播间访问地址", "ENABLE"));
            columns.add(new ColumnsConfigVo("collaborator", "协作人", "ENABLE"));
            columns.add(new ColumnsConfigVo("wechat_note", "微信备注", "ENABLE"));
            redisCache.setCacheList(COLUMNS_CONFIG + userId + ":",columns);
            return columns;
        }
        // 如果缓存中有数据，将其转换为 ColumnsConfigVo 对象并返回
        List<ColumnsConfigVo> columnsConfigList = new ArrayList<>();
        for (Object obj : cacheList) {
            if (obj instanceof ColumnsConfigVo) {
                columnsConfigList.add((ColumnsConfigVo) obj);
            }
        }
        return columnsConfigList;
    }
*/
    @Override
    public void saveColumnsConfig(String userId, List<ColumnsConfigVo> columns) {
        redisCache.deleteObject(COLUMNS_CONFIG + userId + ":");
        redisCache.setCacheObject(COLUMNS_CONFIG + userId + ":", columns);
    }
    private Map<String, String> createColumn(String dataIndex, String status, String title) {
        Map<String, String> column = new HashMap<>();
        column.put("dataIndex", dataIndex);
        column.put("status", status);
        column.put("title", title);
        return column;
    }

}
