package com.example.hospital.api.config;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import com.example.hospital.api.db.dao.MisUserDao;
import com.example.hospital.api.db.dao.VideoDiagnoseDao;
import com.example.hospital.api.socket.WebSocketService;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.trtc.v20190722.TrtcClient;
import com.tencentcloudapi.trtc.v20190722.models.DismissRoomByStrRoomIdRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class KeyExpiredListener extends KeyExpirationEventMessageListener {

    @Value("${tencent.cloud.secretId}")
    private String cloudSecretId;

    @Value("${tencent.cloud.secretKey}")
    private String cloudSecretKey;

    @Value("${tencent.trtc.appId}")
    private Long trtcAppId;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private VideoDiagnoseDao videoDiagnoseDao;

    @Resource
    private MisUserDao misUserDao;

    public KeyExpiredListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    @Transactional
    public void onMessage(Message message, byte[] pattern) {
        String key = message.toString();
        if(key.startsWith("video_diagnose_")){
            String temp = key.substring(key.lastIndexOf("_") + 1);
            int currentOrder = Integer.parseInt(temp.split("#")[0]);
            int doctorId = Integer.parseInt(temp.split("#")[1]);
            int userId = misUserDao.searchUserId(new HashMap() {{
                put("refId", doctorId);
                put("job", "医生");
            }});

            String onlineKey = "online_doctor_" + doctorId;

            if(key.startsWith("video_diagnose_start_")){
                redisTemplate.opsForHash().put(onlineKey,"currentStatus",2);
                String roomId = IdUtil.simpleUUID().toUpperCase();
                redisTemplate.opsForHash().put(onlineKey, "roomId", roomId);
                HashMap param=new HashMap(){{
                    put("id", currentOrder);
                    put("status", 2);
                    put("realStart", new DateTime().toString("yyyy-MM-dd HH:mm:ss"));
                }};
                videoDiagnoseDao.updateStatus(param);
                WebSocketService.sendInfo("StartDiagnose" + "#" + roomId + "&" + currentOrder, userId + "");
            }
            else if(key.startsWith("video_diagnose_end_")){
                redisTemplate.opsForHash().put(onlineKey,"currentStatus",3);
                String roomId = redisTemplate.opsForHash().get(onlineKey, "roomId").toString();
                HashMap param=new HashMap(){{
                    put("id", currentOrder);
                    put("status", 3);
                    put("realEnd", new DateTime().toString("yyyy-MM-dd HH:mm:ss"));
                }};
                videoDiagnoseDao.updateStatus(param);
                Map entries = redisTemplate.opsForHash().entries(onlineKey);
                String nextPatient = MapUtil.getStr(entries, "nextPatient");
                String nextOrder = MapUtil.getStr(entries, "nextOrder");
                String nextStart = MapUtil.getStr(entries, "nextStart");
                String nextEnd = MapUtil.getStr(entries, "nextEnd");
                boolean nextPayment = MapUtil.getBool(entries, "nextPayment");
                if(!"none".equals(nextOrder)){
                    //把等候的问诊换成当前问诊
                    entries.replace("currentPatient", nextPatient);
                    entries.replace("currentOrder", nextOrder);
                    entries.replace("currentHandle", false);
                    entries.replace("currentStart", nextStart);
                    entries.replace("currentEnd", nextEnd);
                    entries.replace("currentPayment", nextPayment);
                    entries.replace("currentNotify", false);
                    entries.replace("currentStatus", 1);

                    //清理等候问诊的缓存
                    entries.replace("nextPatient", "none");
                    entries.replace("nextOrder", "none");
                    entries.replace("nextStart", null);
                    entries.replace("nextEnd", null);
                    entries.replace("nextPayment", false);
                    entries.replace("nextNotify", false);
                }
                else{
                    entries.replace("currentPatient", "none");
                    entries.replace("currentOrder", "none");
                    entries.replace("currentHandle", false);
                    entries.replace("currentStart", null);
                    entries.replace("currentEnd", null);
                    entries.replace("currentPayment", false);
                    entries.replace("currentNotify", false);
                    entries.replace("currentStatus", null);
                }
                redisTemplate.opsForHash().putAll(onlineKey,entries);
                WebSocketService.sendInfo("EndDiagnose" + "#" + roomId, userId + "");
                try{
                    Thread.sleep(2000);
                }catch (InterruptedException e){
                    log.error("线程休眠异常", e);
                }
                Credential cred=new Credential(cloudSecretId,cloudSecretKey);
                TrtcClient client=new TrtcClient(cred,"ap-beijing");
                DismissRoomByStrRoomIdRequest request=new DismissRoomByStrRoomIdRequest();
                request.setSdkAppId(trtcAppId);
                request.setRoomId(roomId);
                try{
                    client.DismissRoomByStrRoomId(request);
                }catch (TencentCloudSDKException e){
                    log.error("销毁TRTC房间失败", e);
                }
                redisTemplate.opsForHash().put(onlineKey,"roomId",null);
            }
        }
        else if(key.startsWith("patient_video_diagnose_payment")){
            int id = Integer.parseInt(key.split("#")[1]);
            HashMap map = videoDiagnoseDao.searchPaymentStatus(id);
            int paymentStatus = MapUtil.getInt(map, "paymentStatus");
            int doctorId = MapUtil.getInt(map, "doctorId");
            key = "online_doctor_" + doctorId;
            if(paymentStatus!=2){
                Map entries = redisTemplate.opsForHash().entries(key);
                if(id == MapUtil.getInt(entries, "nextOrder")){
                    redisTemplate.opsForHash().putAll(key, new HashMap() {{
                        put("nextPatient", "none");   //候诊患者Id
                        put("nextOrder", "none");  //等候问诊的订单号
                        put("nextStart", "none");  //等候问诊的开始时间
                        put("nextEnd", "none");    //等候问诊的结束时间
                        put("nextPayment", false); //等候问诊是否付款
                        put("nextNotify", false); //是否通知了医生端
                    }});
                }

                videoDiagnoseDao.closePayment(new HashMap(){{
                    put("id",id);
                }});
            }
            else{
                //使用WebSocket通知视频问诊页面刷新
                int userId = misUserDao.searchUserId(new HashMap() {{
                    put("refId", doctorId);
                    put("job", "医生");
                }});
                //推送的消息格式为“消息本体#参数”，这里我只设置了消息本体为RefreshDiagnose
                WebSocketService.sendInfo("RefreshDiagnose", userId + "");
            }

        }
    }
}
