package com.izouma.jmrh.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.izouma.jmrh.domain.*;
import com.izouma.jmrh.dto.ConversationDTO;
import com.izouma.jmrh.enums.*;
import com.izouma.jmrh.exception.BusinessException;
import com.izouma.jmrh.repo.*;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class ConversationService {
    private ConversationRepo            conversationRepo;
    private DockingRecordRepo           dockingRecordRepo;
    private UserRepo                    userRepo;
    private ResourceSupplyAndDemandRepo resourceSupplyAndDemandRepo;
    private MessageRepo                 messageRepo;
    private MessageService              messageService;
    private OrgInfoRepo                 orgInfoRepo;

    public void create(Long userId, Long sndId, String orgName, String contactName, String contactPhone,
                       String email, String content , String description) {
        User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
        ResourceSupplyAndDemand snd = resourceSupplyAndDemandRepo.findById(sndId)
                .orElseThrow(new BusinessException("供需不存在"));
        if (userId.equals(snd.getPublishersId())) {
            throw new BusinessException("不能和自己对接");
        }
        Contact contact = new Contact(orgName, contactName, contactPhone, email , description);
        String sessionId = snd.getPublishersId() > userId ?
                (userId + "-" + snd.getPublishersId()) : (snd.getPublishersId() + "-" + userId);


     /*   Conversation conversationFrom = conversationRepo
                .findFirstByUserIdAndToUserIdOrderByIdDesc(userId, snd.getPublishersId());
        if (conversationFrom == null) {
            conversationFrom = Conversation.builder()
                    .sessionId(sessionId)
                    .userId(userId)
                    .toUserId(snd.getPublishersId())
                    .orgId(snd.getOrgId())
                    .contact(contact)
                    .type(ConversationType.DOCKING)
                    .build();
        }
        conversationFrom.setOrgId(snd.getOrgId());
        conversationFrom.setContact(contact);
        conversationRepo.save(conversationFrom);*/

        Conversation conversationFrom = conversationRepo.findBySndIdAAndUserId(sndId,userId);

        if (conversationFrom == null) {
            conversationFrom = Conversation.builder()
                                           .sessionId(sessionId)
                                           .userId(userId)
                                           .toUserId(snd.getPublishersId())
                                           .orgId(snd.getOrgId())
                                           .contact(contact)
                                           .type(ConversationType.DOCKING)
                                           .sndId(sndId)
                                           .resSndType(snd.getType())
                                           .build();
            conversationRepo.save(conversationFrom);
        }else{
            conversationFrom.setOrgId(snd.getOrgId());
            conversationFrom.setContact(contact);
            conversationRepo.save(conversationFrom);
        }


        //-------------------------------

      /*  Conversation conversationTo = conversationRepo
                .findFirstByUserIdAndToUserIdOrderByIdDesc(snd.getPublishersId(), userId);
        if (conversationTo == null) {
            conversationTo = Conversation.builder()
                    .sessionId(sessionId)
                    .userId(snd.getPublishersId())
                    .toUserId(userId)
                    .orgId(snd.getOrgId())
                    .contact(contact)
                    .type(ConversationType.PUBLISH)
                    .build();
        }
        conversationTo.setContact(contact);
        conversationTo.setOrgId(snd.getOrgId());
        conversationRepo.save(conversationTo);*/


//
//        Conversation conversationTo = Conversation.builder()
//                                                  .sessionId(sessionId)
//                                                  .userId(snd.getPublishersId())
//                                                  .toUserId(userId)
//                                                  .orgId(snd.getOrgId())
//                                                  .contact(contact)
//                                                  .type(ConversationType.PUBLISH)
//                                                  .build();
//        conversationRepo.save(conversationTo);
        //------------------------------------

        messageService.send(userId, snd.getPublishersId(), sessionId, MessageType.TEXT, content);
        messageService.send(userId, snd.getPublishersId(), sessionId, MessageType.SND, JSON.toJSONString(snd));

        DockingRecord dockingRecordFrom = dockingRecordRepo
                .findFirstByUserIdAndSndIdAndRoleAndStatusInOrderByIdDesc(userId, sndId, DockingRole.DOCKING,
                        Arrays.asList(DockingStatus.PENDING, DockingStatus.IN_PROGRESS));
        if (dockingRecordFrom == null) {
            dockingRecordFrom = DockingRecord.builder()
                    .userId(userId)
                    .orgId(snd.getOrgId())
                    .sndId(sndId)
                    .role(DockingRole.DOCKING)
                    .status(DockingStatus.PENDING)
                    .build();
        }
        dockingRecordFrom.setConversationId(conversationFrom.getId());
        dockingRecordFrom.setContact(contact);
        dockingRecordRepo.save(dockingRecordFrom);

//        DockingRecord dockingRecordTo = dockingRecordRepo
//                .findFirstByUserIdAndSndIdAndRoleAndStatusInOrderByIdDesc(snd
//                                .getPublishersId(), sndId, DockingRole.PUBLISH,
//                        Arrays.asList(DockingStatus.PENDING, DockingStatus.IN_PROGRESS));
//        if (dockingRecordTo == null) {
//            dockingRecordTo = DockingRecord.builder()
//                    .userId(snd.getPublishersId())
//                    .orgId(snd.getOrgId())
//                    .sndId(sndId)
//                    .role(DockingRole.PUBLISH)
//                    .status(DockingStatus.PENDING)
//                    .build();
//        }
//        dockingRecordTo.setConversationId(conversationTo.getId());
//        dockingRecordTo.setContact(contact);
//        dockingRecordRepo.save(dockingRecordTo);
    }

    public ConversationDTO get(Long id) {
        return conversationRepo.get(id).orElseThrow(new BusinessException("无记录"));
    }

    public List<ConversationDTO> my(Long userId) {
        try {
            conversationRepo.saveAll(Arrays.asList(Conversation.builder()
                            .sessionId("like-" + userId)
                            .userId(userId)
                            .type(ConversationType.LIKE)
                            .build(),
                    Conversation.builder()
                            .sessionId("comment-" + userId)
                            .userId(userId)
                            .type(ConversationType.COMMENT)
                            .build(),
                    Conversation.builder()
                            .sessionId("sys-" + userId)
                            .userId(userId)
                            .type(ConversationType.SYS)
                            .build()
            ));
        } catch (Exception ignored) {
        }
        Map<Integer, ConversationDTO> head = new HashMap<>();
        List<ConversationDTO> list = conversationRepo.my(userId);
        Iterator<ConversationDTO> it = list.iterator();
        while (it.hasNext()) {
            ConversationDTO dto = it.next();
            if (dto.getType() == ConversationType.LIKE) {
                it.remove();
                head.put(0, dto);
            } else if (dto.getType() == ConversationType.COMMENT) {
                it.remove();
                head.put(1, dto);
            } else if (dto.getType() == ConversationType.SYS) {
                it.remove();
                head.put(2, dto);
            }
            if (head.size() == 3) {
                break;
            }
        }
        list.addAll(0, head.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .map(Map.Entry::getValue)
                .collect(Collectors.toList()));
        return list;
    }
}
