package com.xinelu.manage.service.chatrecord.impl;

import com.alibaba.fastjson2.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xinelu.common.config.XinELuConfig;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.dto.MessageTemplate;
import com.xinelu.common.enums.MessageContentType;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.exception.file.InvalidExtensionException;
import com.xinelu.common.socket.WebSocketUtils;
import com.xinelu.common.utils.DateUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.common.utils.file.FileUploadUtils;
import com.xinelu.common.utils.file.MimeTypeUtils;
import com.xinelu.common.utils.http.HttpService;
import com.xinelu.common.utils.spring.SpringUtils;
import com.xinelu.common.utils.uuid.IdUtils;
import com.xinelu.manage.domain.chatRecord.ChatRecord;
import com.xinelu.manage.domain.chatrecordread.ChatRecordRead;
import com.xinelu.manage.domain.hospitalpersoninfo.HospitalPersonInfo;
import com.xinelu.manage.dto.chatrecord.ChatRecordDTO;
import com.xinelu.manage.dto.chatrecord.MessageSearchDto;
import com.xinelu.manage.mapper.chatrecord.ChatRecordMapper;
import com.xinelu.manage.service.chatrecord.IChatRecordService;
import com.xinelu.manage.service.chatrecordread.IChatRecordReadService;
import com.xinelu.manage.service.hospitalpersoninfo.IHospitalPersonInfoService;
import com.xinelu.manage.vo.chatrecord.MessageCenterVo;
import com.xinelu.manage.vo.chatrecord.MessageVo;
import com.xinelu.manage.vo.patientinfo.PatientInfoVO;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 * 图文咨询-聊天记录Service业务层处理
 *
 * @author xinelu
 * @date 2023-09-25
 */
@Service
public class ChatRecordServiceImpl implements IChatRecordService {
    @Resource
    private ChatRecordMapper chatRecordMapper;
    @Resource
    private XinELuConfig xinYiLuConfig;
    @Resource
    private IHospitalPersonInfoService hospitalPersonInfoService;
	@Resource
	private IChatRecordReadService chatRecordReadService;
    @Resource
    private HttpService httpService;

    /**
     * 查询图文咨询-聊天记录
     *
     * @param id 图文咨询-聊天记录主键
     * @return 图文咨询-聊天记录
     */
    @Override
    public ChatRecord selectChatRecordById(Long id) {
        return chatRecordMapper.selectChatRecordById(id);
    }

    /**
     * 查询图文咨询-聊天记录列表
     *
     * @param chatRecord 图文咨询-聊天记录
     * @return 图文咨询-聊天记录
     */
    @Override
    public List<ChatRecord> selectChatRecordList(ChatRecord chatRecord) {
        return chatRecordMapper.selectChatRecordList(chatRecord);
    }

    /**
     * 新增图文咨询-聊天记录
     *
     * @param chatRecord 图文咨询-聊天记录
     * @return 结果
     */
    @Override
    public int insertChatRecord(ChatRecordDTO chatRecord) {
        chatRecord.setCreateTime(DateUtils.getNowDate());
        ChatRecord record = new ChatRecord();
        BeanUtils.copyBeanProp(record, chatRecord);
        record.setMessageNo(IdUtils.fastSimpleUUID());
	    record.setReadStatus("0");
	    record.setSendTime(new Date());
	    record.setDelFlag(0);
        return chatRecordMapper.insertChatRecord(record);
    }

    @Override
    public Boolean sendMessage(ChatRecordDTO chatRecord) {
        // 构建消息结构
        MessageTemplate msg = new MessageTemplate();
        msg.setMessage(chatRecord.getContent());
        msg.setFromKey(chatRecord.getSenderId().toString());
        msg.setToKey(chatRecord.getRecipientId().toString());
        msg.setMsgType(MessageContentType.CHAT.name());
        msg.setMessageType(chatRecord.getMessageType());
        msg.setSendTime(chatRecord.getSendTime());
        return WebSocketUtils.sendMessage(chatRecord.getRecipientId().toString(), msg);
    }

    /**
     * 修改图文咨询-聊天记录
     *
     * @param chatRecord 图文咨询-聊天记录
     * @return 结果
     */
    @Override
    public int updateChatRecord(ChatRecord chatRecord) {
		// 通知公告或健康推送单独记录消息已读未读
		if (StringUtils.equals("1", chatRecord.getMessageCategory()) || StringUtils.equals("2", chatRecord.getMessageCategory())) {
			// 查询当前时间之前的通知公告/健康推送
			chatRecord.setReadStatus(null);
			List<ChatRecord> recordList = getList(chatRecord);

			ChatRecordRead chatRecordRead = new ChatRecordRead();
			chatRecordRead.setPatientId(chatRecord.getRecipientId());
			chatRecordRead.setMessageCategory(chatRecord.getMessageCategory());
			List<ChatRecordRead> readList = chatRecordReadService.getList(chatRecordRead);

			List<ChatRecord> newList = recordList;
			if (!CollectionUtils.isEmpty(readList)) {
				List<Long> readIdList = readList.stream().map(ChatRecordRead::getChatRecordId).collect(Collectors.toList());
				newList = recordList.stream().filter(m -> !readIdList.contains(m.getId())).collect(Collectors.toList());
			}
			List<ChatRecordRead> list = new ArrayList<>();
			if (!CollectionUtils.isEmpty(newList)) {
				newList.forEach(
					record -> {
						ChatRecordRead addRecord = new ChatRecordRead();
						addRecord.setPatientId(chatRecord.getRecipientId());
						addRecord.setMessageCategory(chatRecord.getMessageCategory());
						addRecord.setReadTime(DateUtils.getNowDate());
						addRecord.setChatRecordId(record.getId());
						list.add(addRecord);
					}
				);
			}
			if (!CollectionUtils.isEmpty(list)) {
				chatRecordReadService.insertList(list);
			}
		} else {
			// 更新已读时间
			chatRecord.setReadTime(DateUtils.getNowDate());
			chatRecord.setReadStatus("1");
			chatRecord.setConsultationId(chatRecord.getConsultationId());
		}
        return chatRecordMapper.updateChatRecord(chatRecord);
    }

    /**
     * 批量删除图文咨询-聊天记录
     *
     * @param ids 需要删除的图文咨询-聊天记录主键
     * @return 结果
     */
    @Override
    public int deleteChatRecordByIds(Long[] ids) {
        return chatRecordMapper.deleteChatRecordByIds(ids);
    }

    /**
     * 删除图文咨询-聊天记录信息
     *
     * @param id 图文咨询-聊天记录主键
     * @return 结果
     */
    @Override
    public int deleteChatRecordById(Long id) {
        return chatRecordMapper.deleteChatRecordById(id);
    }


    /**
     * 聊天记录-文件上传
     *
     * @param multipartFile 文件
     * @return 结果
     */
    @Override
    public AjaxResult uploadChatRecordFile(MultipartFile multipartFile, Long consultationId) throws IOException, InvalidExtensionException {
        //获取不同的文件路径
        String uploadPathUrl = XinELuConfig.getProfile() + xinYiLuConfig.getChatRecordFileUrl() + "/" + consultationId;
        if (StringUtils.isBlank(uploadPathUrl)) {
            return AjaxResult.success();
        }
        //上传
        String pictureName = FileUploadUtils.uploadNurseStationPath(uploadPathUrl, multipartFile, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
        if (StringUtils.isBlank(pictureName)) {
            throw new ServiceException("文件上传失败，请联系管理员！");
        }
        AjaxResult ajax = AjaxResult.success("上传成功！");
        ajax.put("fileUrl", pictureName);
        return ajax;
    }

	@Override
	public List<MessageCenterVo> getMegVoList(MessageSearchDto messageDto) {
		List<MessageCenterVo> messageCenterVos = new ArrayList<>();
		List<MessageVo> messageList = chatRecordMapper.selectMegVoList(messageDto);
		if (!CollectionUtils.isEmpty(messageList)) {
			Map<String, List<MessageVo>> groupByCategory = messageList.stream().collect(Collectors.groupingBy(MessageVo::getMessageCategory));

			groupByCategory.keySet().forEach(key -> {
				MessageCenterVo megCenter = new MessageCenterVo();
				switch(key) {
					case "1":
					case "2":
						if (groupByCategory.get(key) != null && groupByCategory.get(key).size() > 0) {
							BeanUtils.copyProperties(groupByCategory.get(key).get(0), megCenter);
							// 总条数
							int sum = groupByCategory.get(key).size();
							int readCount = 0;
							// 查询已读条数
							ChatRecordRead chatRecordRead = new ChatRecordRead();
							chatRecordRead.setMessageCategory(key);
							chatRecordRead.setPatientId(messageDto.getRecipientId());
							List<ChatRecordRead> readList = chatRecordReadService.getList(chatRecordRead);
							if (!CollectionUtils.isEmpty(readList)) {
								readCount = readList.size();
							}
							int unreadCount = sum - readCount;
							megCenter.setUnreadCount(Math.max(unreadCount, 0));
							messageCenterVos.add(megCenter);
						}
						break;
					case "3":
						// 在线咨询
						List<MessageCenterVo> list = new ArrayList<>();
						List<MessageVo> chatList = groupByCategory.get(key);
						if (chatList != null && chatList.size() > 0) {
							// 先根据consultationId分组
							Map<Long, List<MessageVo>> groupByConsultation = chatList.stream().collect(Collectors.groupingBy(MessageVo::getConsultationId));

							groupByConsultation.keySet().forEach(consultationId -> {
								// 统计未读条数
								List<MessageVo> unreadList = groupByConsultation.get(consultationId).stream().filter(m ->
									m.getRecipientId() == messageDto.getRecipientId() && StringUtils.equals("0", m.getReadStatus())
								).collect(Collectors.toList());

								long receive = groupByConsultation.get(consultationId).get(0).getRecipientId();
								MessageCenterVo chat = chatRecordMapper.selectOneChatRecord(consultationId);

								if (receive != messageDto.getRecipientId()) {
									// 查询咨询的最新一条聊天记录
									if (chat.getSenderId().equals(messageDto.getRecipientId())) {
										// 如果发送人是当前登录用户，则把发送人与接收人颠倒
										Long recipientNo = chat.getSenderId();
										String recipientName = chat.getSenderName();
										chat.setSenderId(chat.getRecipientId());
										chat.setSenderName(chat.getRecipientName());
										chat.setRecipientId(recipientNo);
										chat.setRecipientName(recipientName);
										chat.setConsultationId(chat.getConsultationId());
									}
								}
								chat.setUnreadCount(CollectionUtils.isEmpty(unreadList) ? 0 : unreadList.size());
								list.add(chat);
							});
							// list按照图文问诊id倒序排序
							list.sort(Comparator.comparing(MessageCenterVo::getConsultationId).reversed());
							messageCenterVos.addAll(list);
						}
						break;
					case "4":
						if (groupByCategory.get(key) != null && groupByCategory.get(key).size() > 0) {
							BeanUtils.copyProperties(groupByCategory.get(key).get(0), megCenter);
							Long unreadCount = groupByCategory.get(key).stream().collect(Collectors.groupingBy(MessageVo::getReadStatus, Collectors.counting())).get("0");
							megCenter.setUnreadCount(unreadCount == null ? 0 : unreadCount.intValue());
							messageCenterVos.add(megCenter);
						}
						break;
				}
			});
		}

		return messageCenterVos;
	}

	/**
	 * @Author mengkuiliang
	 * @Description 获取指定类型的消息记录
	 * @Date 2023-10-25 025 15:21
	 * @Param [messageDto]
	 * @return java.util.List<com.xinelu.applet.vo.chatrecord.MessageVo>
	 **/
    @Override
    public List<MessageVo> getMegList(MessageSearchDto messageDto, PatientInfoVO patientInfo) {

        String bindTimeStr = String.valueOf(patientInfo.getBindingTime().getYear()) + String.valueOf(patientInfo.getBindingTime().getMonthValue()) + String.valueOf(patientInfo.getBindingTime().getDayOfMonth()) + String.valueOf(patientInfo.getBindingTime().getHour()) + String.valueOf(patientInfo.getBindingTime().getMinute()) + String.valueOf(patientInfo.getBindingTime().getSecond());
        messageDto.setBindingTime(DateUtils.parseDate(bindTimeStr));

        // 通知公告
        if(messageDto.getMessageCategory().equals("1")) {
            return chatRecordMapper.selectMegList(messageDto);
            // 健康推送
        } else if(messageDto.getMessageCategory().equals("2")) {
            String result = (String) httpService.get(SpringUtils.getFdUrl(messageDto.getCityCode()) + "/resident/signinfo/detail/" + patientInfo.getCardNo(), null, String.class);
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (!"1".equals(jsonObject.get("code"))) {
                throw new ServiceException(jsonObject.get("msg").toString());
            }
            if (!jsonObject.containsKey("data") || jsonObject.get("data") == null) {
                throw new ServiceException("未查询到签约信息");
            }
            JSONObject signInfoObject = jsonObject.getJSONObject("data");
            HospitalPersonInfo hospitalPersonInfo = hospitalPersonInfoService.getByPersonCode(signInfoObject.getString("userNo"), null);
            if (hospitalPersonInfo == null) {
                throw new ServiceException("未查询到医生信息");
            }
            messageDto.setSenderId(hospitalPersonInfo.getId());
            messageDto.setCrowdNoList(Arrays.asList(signInfoObject.getString("crowdsNo").split(",")));
            return chatRecordMapper.selectMegList(messageDto);
            // 消息通知
        } else if(messageDto.getMessageCategory().equals("4")) {
            messageDto.setRecipientId(patientInfo.getId());
            return chatRecordMapper.selectMegList(messageDto);
        } else {
            return new ArrayList<>();
        }
    }

    @Override public Integer deleteMegs(List<Long> ids) {
        return chatRecordMapper.deleteMegs(ids);
    }

	/**
	 * @Author mengkuiliang
	 * @Description 查询健康知识推送列表
	 * @Date 2023-10-25 025 11:24
	 * @Param [messageDto]
	 * @return com.github.pagehelper.PageInfo<com.xinelu.applet.vo.chatrecord.MessageVo>
	 **/
    @Override
    public PageInfo<MessageVo> getNoticList(MessageSearchDto messageDto) {
        // 根据发送人编号查询家医用户信息
        HospitalPersonInfo hospitalPersonInfo = hospitalPersonInfoService.getByPersonCode(messageDto.getSenderNo(), null);
        if(hospitalPersonInfo == null) {
            throw new ServiceException("未查询到医生信息");
        }
        messageDto.setSenderId(hospitalPersonInfo.getId());
        PageHelper.startPage(messageDto.getPageNum(), messageDto.getPageSize());
        return PageInfo.of(chatRecordMapper.getNoticList(messageDto));
    }

    /**
     * @return com.xinelu.mp.message.pojo.vo.MessageVo
     * @Author mengkuiliang
     * @Description 查询消息详情
     * @Date 2023-02-18 14:58
     * @Param [messageNo]
     **/
    @Override
    public MessageVo getNoticDetail(String messageNo) {
        return chatRecordMapper.getByNo(messageNo);
    }

    /**
     * @Author mengkuiliang
     * @Description 删除通知
     * @Date 2023-10-25 025 13:15
     * @Param [messageNo]
     * @return void
     **/
    @Override
    public void del(String messageNo) {
        chatRecordMapper.del(messageNo);
    }

    /**
     * @Author mengkuiliang
     * @Description 更新通知
     * @Date 2023-10-25 025 14:05
     * @Param [entity]
     * @return void
     **/
    @Override
    public void updateChatRecordOfNo(ChatRecord entity) {
        chatRecordMapper.updateChatRecordOfNo(entity);
    }

	@Override public List<ChatRecord> getList(ChatRecord chatRecord) {
		return chatRecordMapper.getList(chatRecord);
	}
}
