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.ao.ImOverviewAO;
import com.wecloud.imserver.client.model.ao.ImRtcOverviewAo;
import com.wecloud.imserver.client.model.dto.Result;
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 Result<OverviewVo> overview(Long appId) {
        log.info("即时通讯服务概览的入参appId为{}",appId);
        OverviewVo overviewVo = new OverviewVo();
        //今日活跃用户
        List<ImMessage> imMessageList = imMessageService.list(new LambdaQueryWrapper<ImMessage>()
                .eq(ImMessage::getFkAppid, appId)
                .ge(ImMessage::getCreateTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIN))
                .groupBy(ImMessage::getSender)
                .select(ImMessage::getSender)
        );
        Integer activeUser = imMessageList.size();
        overviewVo.setActiveUser(activeUser);
        log.info("即时通讯服务概览的今日活跃用户数量为{}",activeUser);
        //总注册用户数
        Integer registerUser = imClientService.count(new LambdaQueryWrapper<ImClient>()
                .eq(ImClient::getFkAppid,appId)
        );
        overviewVo.setRegisterUser(registerUser);
        log.info("即时通讯服务概览的注册用户数量为{}",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);
        log.info("即时通讯服务概览的活跃群组数量为{}",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);
        log.info("即时通讯服务概览的总群组数量为{}",activeGroup);

        log.info("即时通讯服务概览的返回参数为{}",overviewVo);
        return Result.getSuccessResult(overviewVo);
    }

    @Override
    public Result<StatisticsVo> groupStatistics(ImOverviewAO imOverviewAo) {
        log.info("即时通讯数据统计的业务统计的appId为{}",imOverviewAo.getAppId());
        LocalDateTime start = imOverviewAo.getStart();
        LocalDateTime end = imOverviewAo.getEnd();
        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, imOverviewAo.getAppId())
                .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);
        log.info("即时通讯数据统计的业务统计的活跃群组数为{}",activeGroup);
        //新增群组数（前1天）
        Integer newGroup = imConversationService.count(new LambdaQueryWrapper<ImConversation>()
                .eq(ImConversation::getFkAppid, imOverviewAo.getAppId())
                .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);
        log.info("即时通讯数据统计的业务统计的新增群组数为{}",newGroup);
        //解散群组数(前一天)
        Integer dismissGroup = imMessageService.count(new LambdaQueryWrapper<ImMessage>()
                .eq(ImMessage::getFkAppid, imOverviewAo.getAppId())
                .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);
        log.info("即时通讯数据统计的业务统计的解散群组数为{}",dismissGroup);

        //活跃群组平均成员数
        Integer avgMember = statistics == null ? 0 : statistics.getGroupMember()/statistics.getData();
        statisticsVo.setAvgActiveGroup(avgMember);
        log.info("即时通讯数据统计的业务统计的活跃群组平均成员数为{}",avgMember);
        //活跃群组折线图
        List<ImStatistics> imStatistics = imStatisticsService.activeUserOrGroup(imOverviewAo.getAppId(), 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, imOverviewAo.getAppId())
                    .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, imOverviewAo.getAppId())
                    .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);
        log.info("即时通讯数据统计的业务统计的返回参数为{}",statisticsVo);
        return Result.getSuccessResult(statisticsVo);
    }


    @Override
    public Result<List<LineChart>> activeUser(ImOverviewAO imOverviewAo) {
        log.info("即时通讯数据统计的用户统计入参为{}",imOverviewAo.getAppId());
        LocalDateTime start = imOverviewAo.getStart();
        LocalDateTime end = imOverviewAo.getEnd();
        if(start == null && end ==null){
            start = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(8);
            end = start.plusDays(7);
        }
        //活跃用户数
        List<ImStatistics> imStatistics = imStatisticsService.activeUserOrGroup(imOverviewAo.getAppId(), 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);
        }
        log.info("即时通讯数据统计的用户统计返回参数为{}",activeUser);
        return Result.getSuccessResult(activeUser);
    }

    @Override
    public Result<RtcRecordVo> rtcStatistics(ImRtcOverviewAo imrtcOverviewAo) {
        log.info("音视频通讯数据统计的入参的appId为{}",imrtcOverviewAo.getAppId());
        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(imrtcOverviewAo.getStart(),imrtcOverviewAo.getStart().plusMonths(1)); i++) {
            //每天的视频通话数据==============================
            LineChart videoLineChart = new LineChart();
            LocalDateTime start = imrtcOverviewAo.getStart().plusDays(i);
            LocalDateTime end = imrtcOverviewAo.getStart().plusDays(i+1);

            Integer videoLength = 0;

            List<ImRtcRecord> imVideoList = imRtcRecordService.list(new LambdaQueryWrapper<ImRtcRecord>()
                    .eq(ImRtcRecord::getFkAppid,imrtcOverviewAo.getAppId())
                    .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,imrtcOverviewAo.getAppId())
                    .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<Long> ids = imRtcTranscribeService.list(new LambdaQueryWrapper<ImRtcTranscribe>()
                    .between(ImRtcTranscribe::getStartTime, start, end)
                    .groupBy(ImRtcTranscribe::getFkRecordId)
                    .select(ImRtcTranscribe::getFkRecordId)
            ).stream().map(ImRtcTranscribe::getFkRecordId).collect(Collectors.toList());
            for (Long id : ids) {
                ImRtcRecord imRtcRecord = imRtcRecordService.getById(id);
                if(imRtcRecord.getCallType()==1){

                }else if(imRtcRecord.getCallType()==2){

                }
            }
        }

        rtcRecordVo.setVideo(video);
        rtcRecordVo.setVoice(voice);
        log.info("音视频通讯数据统计的返回参数为{}",rtcRecordVo);
        return Result.getSuccessResult(rtcRecordVo);
    }
}
