package com.wecloud.im.appmanager;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wecloud.im.entity.*;
import com.wecloud.im.sdk.enums.ChatTypeEnum;
import com.wecloud.im.service.*;
import com.wecloud.im.ws.enums.MsgTypeEnum;
import com.wecloud.imserver.client.api.ImOverview;
import com.wecloud.imserver.client.model.vo.LineChart;
import com.wecloud.imserver.client.model.vo.OverviewVo;
import com.wecloud.imserver.client.model.vo.RtcRecordVo;
import com.wecloud.imserver.client.model.vo.StatisticsVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.*;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@DubboService
public class ImOverviewImpl implements ImOverview {

    @Autowired
    private ImMessageService imMessageService;
    @Autowired
    private ImClientService imClientService;
    @Autowired
    private ImConversationService imConversationService;
    @Autowired
    private ImStatisticsService imStatisticsService;
    @Autowired
    private ImRtcRecordService imRtcRecordService;
    @Autowired
    private ImRtcTranscribeService imRtcTranscribeService;

    @Override
    public OverviewVo overview(Long appId) {
        OverviewVo overviewVo = new OverviewVo();
        //今日活跃用户
        Integer activeUser = imMessageService.count(new LambdaQueryWrapper<ImMessage>()
                .eq(ImMessage::getFkAppid, appId)
                .ge(ImMessage::getCreateTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIN))
                .groupBy(ImMessage::getSender)
                .select(ImMessage::getSender)
        );
        overviewVo.setActiveUser(activeUser);
        //总注册用户数
        Integer registerUser = imClientService.count(new LambdaQueryWrapper<ImClient>()
                .eq(ImClient::getFkAppid,appId)
        );
        overviewVo.setRegisterUser(registerUser);
        //七天内活跃群组数
        List<Long> ids = imMessageService.list(new LambdaQueryWrapper<ImMessage>()
                .ge(ImMessage::getCreateTime, LocalDateTime.now().minusDays(7))
                .le(ImMessage::getCreateTime, LocalDateTime.now())
                .groupBy(ImMessage::getFkConversationId)
                .select(ImMessage::getFkConversationId)
        ).stream().map(ImMessage::getFkConversationId).collect(Collectors.toList());

        Integer activeGroup = imConversationService.count(new LambdaQueryWrapper<ImConversation>()
                .eq(ImConversation::getFkAppid, appId)
                .eq(ImConversation::getChatType, ChatTypeEnum.NORMAL_GROUP.getCode())
                .eq(ImConversation::getChatType, ChatTypeEnum.THOUSAND_GROUP.getCode())
                .in(ImConversation::getId, ids)
        );
        overviewVo.setActiveGroup(activeGroup);
        //总群组数
        Integer group = imConversationService.count(new LambdaQueryWrapper<ImConversation>()
                .eq(ImConversation::getFkAppid,appId)
                .eq(ImConversation::getChatType, ChatTypeEnum.NORMAL_GROUP.getCode())
                .eq(ImConversation::getChatType, ChatTypeEnum.THOUSAND_GROUP.getCode())
        );
        overviewVo.setGroup(group);

        return overviewVo;
    }

    @Override
    public StatisticsVo groupStatistics(Long appId, LocalDateTime start, LocalDateTime end) {
        if(start == null && end ==null){
            start = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(8);
            end = start.plusDays(7);
        }

        StatisticsVo statisticsVo = new StatisticsVo();
        //活跃群组数（前1天）
        ImStatistics statistics = imStatisticsService.getOne(new LambdaQueryWrapper<ImStatistics>()
                .eq(ImStatistics::getFkAppid, appId)
                .eq(ImStatistics::getType, 2)
                .between(ImStatistics::getTime,
                        LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(1),
                        LocalDateTime.of(LocalDate.now(), LocalTime.MAX).minusDays(1))
        );
        Integer activeGroup = statistics == null ? 0 : statistics.getData();
        statisticsVo.setActiveGroup(activeGroup);

        //新增群组数（前1天）
        Integer newGroup = imConversationService.count(new LambdaQueryWrapper<ImConversation>()
                .eq(ImConversation::getFkAppid, appId)
                .eq(ImConversation::getChatType, ChatTypeEnum.NORMAL_GROUP.getCode())
                .eq(ImConversation::getChatType, ChatTypeEnum.THOUSAND_GROUP.getCode())
                .between(ImConversation::getCreateTime,
                        LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(1),
                        LocalDateTime.of(LocalDate.now(), LocalTime.MAX).minusDays(1))
        );
        statisticsVo.setNewGroup(newGroup);

        //解散群组数(前一天)
        Integer dismissGroup = imMessageService.count(new LambdaQueryWrapper<ImMessage>()
                .eq(ImMessage::getFkAppid, appId)
                .eq(ImMessage::getMsgType, MsgTypeEnum.CONVERSATION_DISBAND.getUriCode())
                .between(ImMessage::getCreateTime,
                        LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(1),
                        LocalDateTime.of(LocalDate.now(), LocalTime.MAX).minusDays(1))
        );
        statisticsVo.setDismissGroup(dismissGroup);

        //活跃群组平均成员数
        Integer avgMember = statistics == null ? 0 : statistics.getGroupMember()/statistics.getData();
        statisticsVo.setAvgActiveGroup(avgMember);

        //活跃群组折线图
        List<ImStatistics> imStatistics = imStatisticsService.activeUserOrGroup(appId, 2, start, end);
        List<LineChart> activeGroupLine = new ArrayList<>();
        for (ImStatistics imStatistic : imStatistics) {
            LineChart lineChart = new LineChart();
            lineChart.setCount(imStatistic.getData());
            lineChart.setDate(imStatistic.getTime());
            activeGroupLine.add(lineChart);
        }
        statisticsVo.setActiveGroupLine(activeGroupLine);

        //新增群组折线图
        Long days = ChronoUnit.DAYS.between(start, end);
        List<LineChart> newGroupLine = new ArrayList<>();
        for (int i = days.intValue();i>0;i--){
            LineChart lineChart = new LineChart();
            Integer count = imConversationService.count(new LambdaQueryWrapper<ImConversation>()
                    .eq(ImConversation::getFkAppid, appId)
                    .eq(ImConversation::getChatType, ChatTypeEnum.NORMAL_GROUP.getCode())
                    .eq(ImConversation::getChatType, ChatTypeEnum.THOUSAND_GROUP.getCode())
                    .between(ImConversation::getCreateTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(i), LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(i - 1))
            );
            lineChart.setDate(LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(i));
            lineChart.setCount(count);
            newGroupLine.add(lineChart);
        }
        statisticsVo.setNewGroupLine(newGroupLine);

        //解散群组折线图
        List<LineChart> dismissGroupLine = new ArrayList<>();
        for (int i = days.intValue();i>0;i--){
            LineChart lineChart = new LineChart();
            Integer count = imMessageService.count(new LambdaQueryWrapper<ImMessage>()
                    .eq(ImMessage::getFkAppid, appId)
                    .eq(ImMessage::getMsgType, MsgTypeEnum.CONVERSATION_DISBAND.getUriCode())
                    .between(ImMessage::getCreateTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(i), LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(i - 1))
            );
            lineChart.setDate(LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(i));
            lineChart.setCount(count);
            dismissGroupLine.add(lineChart);
        }
        statisticsVo.setDismissGroupLine(dismissGroupLine);

        //活跃群组平均成员数
        List<LineChart> avgActiveGroupLine = new ArrayList<>();
        for (ImStatistics imStatistic : imStatistics) {
            LineChart lineChart = new LineChart();
            lineChart.setCount(imStatistic.getGroupMember()/imStatistic.getData());
            lineChart.setDate(imStatistic.getTime());
            avgActiveGroupLine.add(lineChart);
        }
        statisticsVo.setAvgActiveGroupLine(avgActiveGroupLine);

        return statisticsVo;
    }


    @Override
    public List<LineChart> activeUser(Long appId, LocalDateTime start, LocalDateTime end) {
        if(start == null && end ==null){
            start = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(8);
            end = start.plusDays(7);
        }
        //活跃用户数
        List<ImStatistics> imStatistics = imStatisticsService.activeUserOrGroup(appId, 1, start, end);
        List<LineChart> activeUser = new ArrayList<>();
        for (ImStatistics imStatistic : imStatistics) {
            LineChart lineChart = new LineChart();
            lineChart.setCount(imStatistic.getData());
            lineChart.setDate(imStatistic.getTime());
            activeUser.add(lineChart);
        }
        return activeUser;
    }

    @Override
    public RtcRecordVo RtcStatistics(Long appId, LocalDateTime date) {
        RtcRecordVo rtcRecordVo = new RtcRecordVo();
        List<LineChart> video = new ArrayList<>();
        List<LineChart> voice = new ArrayList<>();
        List<LineChart> videoTranscribe = new ArrayList<>();
        List<LineChart> voiceTranscribe = new ArrayList<>();

        for (int i = 0; i < ChronoUnit.DAYS.between(date,date.plusMonths(1)); i++) {
            //每天的视频通话数据==============================
            LineChart videoLineChart = new LineChart();
            LocalDateTime start = date.plusDays(i);
            LocalDateTime end = date.plusDays(i+1);

            Integer videoLength = 0;

            List<ImRtcRecord> imVideoList = imRtcRecordService.list(new LambdaQueryWrapper<ImRtcRecord>()
                    .eq(ImRtcRecord::getFkAppid,appId)
                    .eq(ImRtcRecord::getCallType,1)
                    .between(ImRtcRecord::getStartTime,start,end)
            );
            for (ImRtcRecord imRtcRecord : imVideoList) {

                Instant startInstant = imRtcRecord.getStartTime().toInstant();
                Instant endInstant = imRtcRecord.getEndTime().toInstant();
                ZoneId zone = ZoneId.systemDefault();
                LocalDateTime startTime = LocalDateTime.ofInstant(startInstant,zone);
                LocalDateTime endTime = LocalDateTime.ofInstant(endInstant,zone);

                Long between = ChronoUnit.MINUTES.between(startTime,endTime);
                if (startTime.getSecond() != endTime.getSecond()){
                    between += 1;
                }
                videoLength += between.intValue();
            }
            videoLineChart.setCount(videoLength);
            videoLineChart.setDate(start);
            video.add(videoLineChart);

            //每天的音频通话数据==============================
            LineChart voiceLineChart = new LineChart();
            Integer voiceLength = 0;

            List<ImRtcRecord> imVoiceList = imRtcRecordService.list(new LambdaQueryWrapper<ImRtcRecord>()
                    .eq(ImRtcRecord::getFkAppid,appId)
                    .eq(ImRtcRecord::getCallType,2)
                    .between(ImRtcRecord::getStartTime,start,end)
            );
            for (ImRtcRecord imRtcRecord : imVoiceList) {

                Instant startInstant = imRtcRecord.getStartTime().toInstant();
                Instant endInstant = imRtcRecord.getEndTime().toInstant();
                ZoneId zone = ZoneId.systemDefault();
                LocalDateTime startTime = LocalDateTime.ofInstant(startInstant,zone);
                LocalDateTime endTime = LocalDateTime.ofInstant(endInstant,zone);

                Long between = ChronoUnit.MINUTES.between(startTime,endTime);
                if (startTime.getSecond() != endTime.getSecond()){
                    between += 1;
                }
                voiceLength += between.intValue();
            }
            voiceLineChart.setDate(start);
            voiceLineChart.setCount(voiceLength);
            voice.add(voiceLineChart);

            //每天的视频通话录制=============================
            List<ImRtcTranscribe> imRtcTranscribeList = imRtcTranscribeService.list(new LambdaQueryWrapper<ImRtcTranscribe>()
                    .between(ImRtcTranscribe::getStartTime, start, end)
                    .groupBy(ImRtcTranscribe::getFkRecordId)
                    .select(ImRtcTranscribe::getFkRecordId)
            );
        }

        rtcRecordVo.setVideo(video);
        rtcRecordVo.setVoice(voice);
        return rtcRecordVo;
    }
}
