package com.sonic.cow.event.inner.handler;

import com.alibaba.fastjson.JSON;
import com.sonic.common.event.Event;
import com.sonic.common.event.EventConsumer;
import com.sonic.common.event.EventHandler;
import com.sonic.cow.client.rtc.EventData;
import com.sonic.cow.domain.entity.VoiceChatRecord;
import com.sonic.cow.domain.input.VoiceChatOptInput;
import com.sonic.cow.enums.VoiceChatOptTypeEnum;
import com.sonic.cow.event.inner.EventType;
import com.sonic.cow.event.inner.payload.VoiceCallWebhookPayload;
import com.sonic.cow.service.CommonSendMqService;
import com.sonic.cow.service.VoiceChatRecordService;
import com.sonic.cow.service.VoiceChatService;
import com.sonic.cow.utils.RedisKeyUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.concurrent.TimeUnit;

/**
 * @author chenjun
 */
@Slf4j
@Component
public class VoiceCallWebhookHandler implements EventHandler, InitializingBean {

    @Autowired
    private EventConsumer eventConsumer;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private VoiceChatService voiceChatService;
    @Autowired
    private RedisKeyUtils redisKeyUtils;
    @Autowired
    private CommonSendMqService commonSendMqService;
    @Autowired
    private VoiceChatRecordService voiceChatRecordService;

    @Override
    public void onEvent(Event event) {
        try {
            VoiceCallWebhookPayload payload = event.normalizedData(VoiceCallWebhookPayload.class);
            log.info("VoiceCallWebhookHandler payload:{}", payload);
            com.sonic.cow.client.rtc.Event voiceCallEvent = payload.getVoiceCallEvent();
            String eventType = voiceCallEvent.getEventType();
            //房间销毁
            if ("RoomDestroy".equals(eventType)) {
                //房间销毁，调用stopVoiceChat接口,停止语音通话
                roomDestroy(voiceCallEvent);
            } else if ("UserLeaveRoom".equals(eventType)) {
                userLeaveRoom(voiceCallEvent);
            } else if ("UserJoinRoom".equals(eventType)) {
                //从redis zset中移除元素
                userJoinRoom(voiceCallEvent);
            }
        } catch (Exception e) {
            log.error("VoiceCallWebhookHandler error:", e);
        }
    }

    @Override
    public void afterPropertiesSet() {
        eventConsumer.registerHandler(EventType.VOICE_CALL_WEBHOOK.getEventCode(), this);
    }

    /**
     * 房间销毁处理
     *
     * @param voiceCallEvent
     */
    private void roomDestroy(com.sonic.cow.client.rtc.Event voiceCallEvent) {
        EventData eventData = JSON.parseObject(voiceCallEvent.getEventData(), EventData.class);
        String roomId = eventData.getRoomId();
        //获得通话双方的用户id
        String[] split = roomId.split("-");
        Long userId = Long.valueOf(split[0]);
        Long aiId = Long.valueOf(split[1]);

        //缓存中获取到taskId
        String taskId = stringRedisTemplate.opsForValue().get(redisKeyUtils.voiceChatTaskIdKey(userId.toString()));
        log.info("roomDestroy taskId:{}", taskId);
        //如果删除了，则直接返回
        if (taskId == null) {
            return;
        }
        //查询聊天记录
        VoiceChatRecord voiceChatRecord = voiceChatRecordService.getByRoomIdAndTaskId(roomId, taskId);
        //不存在聊天记录，return
        if (voiceChatRecord == null) {
            return;
        }
        //已经结束return
        if (voiceChatRecord.getStatus() == 3) {
            return;
        }
        //时长
        LocalDateTime createTime = voiceChatRecord.getCreateTime();
        Long startTime = createTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        Long duration = (System.currentTimeMillis() - startTime);
        //调用stopVoiceChat接口,停止语音通话
        VoiceChatOptInput voiceChatOptInput = VoiceChatOptInput.builder()
                .aiId(aiId)
                .roomId(roomId)
                .optType(VoiceChatOptTypeEnum.STOP)
                .taskId(taskId)
                .duration(duration)
                .build();
        log.info("VoiceCallWebhookHandler voiceChatOptInput:{} ", JSON.toJSONString(voiceChatOptInput));
        voiceChatService.voiceChatOpt(userId, voiceChatOptInput);
    }

    /**
     * 用户离开房间处理
     *
     * @param voiceCallEvent
     */
    private void userLeaveRoom(com.sonic.cow.client.rtc.Event voiceCallEvent) {
        EventData eventData = JSON.parseObject(voiceCallEvent.getEventData(), EventData.class);
        String userId = eventData.getUserId();
        //真实用户离开，停止费用计算，定时任务，如果超过3分钟没有加入，调用stopVoiceChat接口,停止语音通话
        if (!userId.contains("@")) {
            stringRedisTemplate.opsForZSet().add(redisKeyUtils.voiceChatUserLeaveRoomKey(), userId, System.currentTimeMillis());
        }
    }


    /**
     * 用户加入房间处理
     *
     * @param voiceCallEvent
     */
    private void userJoinRoom(com.sonic.cow.client.rtc.Event voiceCallEvent) {
        EventData eventData = JSON.parseObject(voiceCallEvent.getEventData(), EventData.class);
        String userId = eventData.getUserId();
        String roomId = eventData.getRoomId();
        //真实用户加入，删除redis
        if (!userId.contains("@")) {
            //用户离开房间中移除
            stringRedisTemplate.opsForZSet().remove(redisKeyUtils.voiceChatUserLeaveRoomKey(), userId);
            //获取最近一个未关闭的语音通话
            String taskId = stringRedisTemplate.opsForValue().get(redisKeyUtils.voiceChatTaskIdKey(userId));
            if (taskId == null) {
                return;
            }
            VoiceChatRecord voiceChatRecord = voiceChatRecordService.getByRoomIdAndTaskId(roomId, taskId);
            //不存在，return
            if (voiceChatRecord == null) {
                return;
            }
            //已经结束return
            if (voiceChatRecord.getStatus() == 3) {
                return;
            }
        }
    }
}
