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

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.sonic.common.event.Event;
import com.sonic.common.event.EventConsumer;
import com.sonic.common.event.EventHandler;
import com.sonic.cow.client.request.InputRequest;
import com.sonic.cow.domain.entity.VoiceChatRecord;
import com.sonic.cow.domain.input.VoiceChatOptInput;
import com.sonic.cow.enums.DeductionTypeEnum;
import com.sonic.cow.enums.VoiceChatOptTypeEnum;
import com.sonic.cow.event.inner.EventType;
import com.sonic.cow.event.inner.payload.VoiceCallDeductionPayload;
import com.sonic.cow.event.outer.payload.UserDeductionStatPayload;
import com.sonic.cow.service.CommonSendMqService;
import com.sonic.cow.service.VoiceChatRecordService;
import com.sonic.cow.service.VoiceChatService;
import com.sonic.cow.service.VoiceService;
import com.sonic.cow.utils.DateUtils;
import com.sonic.cow.utils.RedisKeyUtils;
import com.sonic.pigeon.lib.client.ImMessageClient;
import com.sonic.pigeon.lib.enums.ImMessageTypeEnum;
import com.sonic.pigeon.lib.input.SendAiCustomerMessageInput;
import lombok.extern.slf4j.Slf4j;
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.HashMap;
import java.util.List;
import java.util.Map;

import static com.sonic.cow.utils.Constant.VOICE_CALL_DEDUCTION_AMOUNT;

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

    @Autowired
    private EventConsumer eventConsumer;
    @Autowired
    private VoiceChatRecordService voiceChatRecordService;
    @Autowired
    private CommonSendMqService commonSendMqService;
    @Autowired
    private VoiceService voiceService;
    @Autowired
    private ImMessageClient imMessageClient;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedisKeyUtils redisKeyUtils;
    @Autowired
    private VoiceChatService voiceChatService;
    @Autowired
    private VoiceCallEmotionScoreHandler voiceCallEmotionScoreHandler;

    @Override
    public void onEvent(Event event) {
        VoiceCallDeductionPayload payload = event.normalizedData(VoiceCallDeductionPayload.class);
        log.info("VoiceCallDeductionHandler payload:{}", payload);
        Long voiceCallId = payload.getVoiceCallId();
        //查询本次语音通话信息
        VoiceChatRecord voiceChatRecord = voiceChatRecordService.getById(voiceCallId);
        log.info("VoiceCallDeductionHandler voiceChatRecord:{}", voiceChatRecord);
        //不存在或者通话已经结束，则快速返回
        if (voiceChatRecord == null || voiceChatRecord.getStatus() == 3) {
            return;
        }
//        //用户离开，则不发送扣费，判断元素是否存在
//        Double score = stringRedisTemplate.opsForZSet().score(redisKeyUtils.voiceChatUserLeaveRoomKey(), payload.getUserId().toString());
//        log.info("VoiceCallDeductionHandler score:{}", score);
//        if (score != null) {
//            return;
//        }
        //如果余额不足，发送IM消息并发起结算
        boolean balanceIsInsufficient = voiceService.checkBalanceIsInsufficient(payload.getUserId(), VOICE_CALL_DEDUCTION_AMOUNT);
        if (balanceIsInsufficient) {
            //发送IM消息,通知前端
            Map<String, Object> extra = new HashMap<>();
            extra.put("type", ImMessageTypeEnum.INSUFFICIENT_BALANCE.name());
            extra.put("content", "INSUFFICIENT_BALANCE");
            SendAiCustomerMessageInput sendAiCustomerMessageInput = SendAiCustomerMessageInput.builder()
                    .fromUserId(payload.getUserId())
                    .toUserId(payload.getAiId())
                    .content("INSUFFICIENT_BALANCE")
                    .attachment(JSON.toJSONString(extra))
                    .build();
            imMessageClient.sendUserToAiCustomerMessage(sendAiCustomerMessageInput);
            //余额不足，发送MQ，余额不足处理
//            commonSendMqService.userBalanceInsufficientCheckoutMq(payload.getUserId());
            //调用stopVoiceChat接口,停止语音通话
            Long startTime = voiceChatRecord.getCreateTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
            Long duration = (System.currentTimeMillis() - startTime);
            VoiceChatOptInput voiceChatOptInput = VoiceChatOptInput.builder()
                    .aiId(voiceChatRecord.getAiId())
                    .roomId(voiceChatRecord.getRoomId())
                    .optType(VoiceChatOptTypeEnum.STOP)
                    .taskId(voiceChatRecord.getTaskId())
                    .duration(duration)
                    .build();
            log.info("VoiceCallDeductionHandler voiceChatOptInput:{} ", JSON.toJSONString(voiceChatOptInput));
            voiceChatService.voiceChatOpt(voiceChatRecord.getUserId(), voiceChatOptInput);
            return;
        }
        //发送到用户预扣费统计队列
        HashMap<Object, Object> extraMap = Maps.newHashMap();
        extraMap.put("voiceCallId", voiceCallId);
        //当前时间-开始时间
        Long duration = DateUtils.getTimeDifference(voiceChatRecord.getCreateTime(), LocalDateTime.now());
        extraMap.put("duration", duration);
        extraMap.put("status", voiceChatRecord.getStatus());
        commonSendMqService.userDeductionStatSendMq(UserDeductionStatPayload.builder()
                .userId(payload.getUserId())
                .aiId(payload.getAiId())
                .deductionType(DeductionTypeEnum.VOICE_CALL)
                .bizTime(LocalDateTime.now())
                .extra(JSON.toJSONString(extraMap))
                .build());
        //发送到死信队列，1分钟后再执行
        commonSendMqService.voiceCallDeductionSendDeadMq(payload.getUserId(), payload.getAiId(), payload.getVoiceCallId());
    }

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