package com.ads.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.ads.business.dao.ConversationDao;
import com.ads.business.dao.ConversationUserRelDao;
import com.ads.business.entity.Conversation;
import com.ads.business.entity.ConversationUserRel;
import com.ads.business.entity.DocConversationRel;
import com.ads.business.entity.DocTypeConversationRel;
import com.ads.business.service.*;
import com.ads.business.service.model.request.ConversationAddRequest;
import com.ads.business.service.model.request.ConversationListRequest;
import com.ads.business.service.model.response.*;
import com.ads.common.data.JsonResult;
import com.ads.common.dingTalk.domain.ServiceResult;
import com.ads.common.dingTalk.domain.UserDTO;
import com.ads.common.dingTalk.service.DingTalkService;
import com.ads.common.util.OnlineUserUtils;
import com.ads.common.util.PageUtils;
import com.ads.common.util.UtilConst;
import com.ads.common.util.UtilMessage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dingtalk.api.request.OapiChatCreateRequest;
import com.dingtalk.api.response.OapiChatCreateResponse;
import com.dingtalk.api.response.OapiChatGetResponse;
import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

import static com.ads.common.util.UtilConst.CONVERSATION_STTAUS_DISMISS;
import static com.ads.common.util.UtilConst.CONVERSATION_STTAUS_NORMAL;
import static com.ads.common.util.UtilMessage.*;

/**
 * <p>
 * 会话表 服务实现类
 * </p>
 *
 * @author hou
 * @since 2021-11-18
 */
@Service
@Slf4j
public class ConversationServiceImpl extends ServiceImpl<ConversationDao, Conversation> implements ConversationService {


    @Resource
    private DingTalkService dingTalkService;
    @Resource
    private TokenService tokenService;
    @Resource
    private ConversationUserRelService conversationUserRelService;
    @Resource
    private ConversationUserRelDao userRelDao;

    @Resource
    private DocTypeConversationRelService docTypeConversationRelService;

    @Resource
    private DocConversationRelService docConversationRelService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult create(ConversationAddRequest request) {
        //构建body参数
        OapiChatCreateRequest chatCreateRequest = new OapiChatCreateRequest();
        BeanUtil.copyProperties(request, chatCreateRequest);
        //群名称
        chatCreateRequest.setName(request.getConversationName());
        //获取群主userid
        ServiceResult<OapiV2UserGetbymobileResponse> getResult = dingTalkService.getbymobile(request.getOwnerMobile());
        if (!getResult.isSuccess()) {
            if (UtilConst.DING_USER_NOT_EXIST.equals(getResult.getCode())) {
                return JsonResult.fail(String.format(DING_USER_NOT_EXIST, request.getOwnerMobile()));
            }
            return JsonResult.fail("errcode: " + getResult.getCode() + "; errmsg: " + getResult.getMessage());
        }
        //群主userid
        chatCreateRequest.setOwner(getResult.getResult().getResult().getUserid());
        //群成员列表
        List<String> useridlist = new ArrayList<>();
        Map<String, String> userIdMobileMap = new HashMap<>();
        List<String> mobileList = request.getMobileList();
        if (!mobileList.contains(request.getOwnerMobile())) {
            //将群主加入群成员
            mobileList.add(request.getOwnerMobile());
        }
        for (String mobile : mobileList) {
            ServiceResult<OapiV2UserGetbymobileResponse> mobileResult = dingTalkService.getbymobile(mobile);
            if (!mobileResult.isSuccess()) {
                if (UtilConst.DING_USER_NOT_EXIST.equals(mobileResult.getCode())) {
                    return JsonResult.fail(String.format(DING_USER_NOT_EXIST, mobile));
                }
                return JsonResult.fail("errcode: " + mobileResult.getCode() + "; errmsg: " + mobileResult.getMessage() + "; mobile: " + mobile);
            }
            String userid = mobileResult.getResult().getResult().getUserid();
            userIdMobileMap.put(userid, mobile);
            useridlist.add(userid);
        }
        chatCreateRequest.setUseridlist(useridlist);
        ServiceResult<OapiChatCreateResponse> createResult = dingTalkService.create(chatCreateRequest);
        if (!createResult.isSuccess()) {
            return JsonResult.fail("errcode: " + createResult.getCode() + "; errmsg: " + createResult.getMessage());
        }

        //会话信息入库
        Conversation conversation = new Conversation();
        BeanUtil.copyProperties(request, conversation);
        //会话ID
        String chatId = createResult.getResult().getChatid();
        conversation.setChatId(chatId);
        String openConversationId = createResult.getResult().getOpenConversationId();
        conversation.setOpenConversationId(openConversationId);
        conversation.setConversationTag(createResult.getResult().getConversationTag().intValue());
        conversation.setOwnerId(chatCreateRequest.getOwner());
        conversation.setCreateUser(Long.valueOf(OnlineUserUtils.get().getUserId()));
        conversation.setCreateTime(new Date());
        //群成员信息入库
        List<ConversationUserRel> conversationUserRelList = new ArrayList<>();
        for (String userid : useridlist) {
            ConversationUserRel conversationUserRel = new ConversationUserRel();
            conversationUserRel.setChatId(chatId);
            conversationUserRel.setOpenConversationId(openConversationId);
            conversationUserRel.setUserId(userid);
            conversationUserRel.setPhone(userIdMobileMap.get(userid));
            ServiceResult<UserDTO> userServiceResult = dingTalkService.getUser(tokenService.getAccessToken(), userid);
            if (userServiceResult.isSuccess()) {
                //用户头像
                conversationUserRel.setAvatar(userServiceResult.getResult().getAvatar());
                //用户名
                conversationUserRel.setUserName(userServiceResult.getResult().getName());
                if (chatCreateRequest.getOwner().equals(userid)) {
                    conversation.setOwnerName(conversationUserRel.getUserName());
                }
            }
            conversationUserRelList.add(conversationUserRel);
        }
        this.save(conversation);
        if (CollUtil.isNotEmpty(conversationUserRelList)) {
            conversationUserRelService.saveBatch(conversationUserRelList);
        }
        return JsonResult.success(ADD_SUCCESS);
    }

    @Override
    public JsonResult selectList(ConversationListRequest request) {
        Long currPage = request.getPage() == null ? 1 : request.getPage().longValue();
        Long pageSize = request.getPageSize() == null ? 10 : request.getPageSize().longValue();
        Page<DocTypeListResponse> page = new Page<>(currPage, pageSize);
        QueryWrapper<ConversationListResponse> wrapper = new QueryWrapper();
        if (StringUtils.isNotBlank(request.getConversationName())) {
            wrapper.like("conversation_name", request.getConversationName());
        }
        wrapper.like(StringUtils.isNotBlank(request.getOwnerName()), "owner_name", request.getOwnerName());
        wrapper.eq("status", CONVERSATION_STTAUS_NORMAL);
        wrapper.orderByDesc("create_time");
        return JsonResult.success(new PageUtils(this.baseMapper.findPage(page, wrapper)), UtilMessage.GET_MESSAGE_SUCCESS);
    }

    @Override
    public JsonResult<ConversationDetail> detail(String chatId) {
        Conversation conversation = this.getById(chatId);
        if (conversation == null) {
            return JsonResult.fail(CONVERSATION_NOT_EXIST);
        }
        ConversationDetail conversationDetail = new ConversationDetail();
        BeanUtil.copyProperties(conversation, conversationDetail);
        QueryWrapper<ConversationUserRelResponse> wrapper = new QueryWrapper();
        wrapper.eq("chat_id", chatId);
        List<ConversationUserRelResponse> userRelResponseList = userRelDao.getByChatId(wrapper);
        userRelResponseList.stream().filter(u -> conversation.getOwnerId().equals(u.getUserId())).findFirst().get().setOwner(1);
        conversationDetail.setUserRelList(userRelResponseList);
        return JsonResult.success(conversationDetail);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult sync(String chatId) {
        Conversation conversation = this.getById(chatId);
        if (conversation == null) {
            return JsonResult.fail(CONVERSATION_NOT_EXIST);
        }
        ServiceResult<OapiChatGetResponse> result = dingTalkService.getChatInfo(chatId);
        if (!result.isSuccess()) {
            return JsonResult.fail("errcode: " + result.getCode() + "; errmsg: " + result.getMessage());
        }
        //会话信息
        OapiChatGetResponse.ChatInfo chatInfo = result.getResult().getChatInfo();
        //群名称
        conversation.setConversationName(chatInfo.getName());
        //群主的userid
        conversation.setOwnerId(chatInfo.getOwner());
        ServiceResult<UserDTO> userServiceResult = dingTalkService.getUser(tokenService.getAccessToken(), chatInfo.getOwner());
        if (userServiceResult.isSuccess()) {
            //群主名
            conversation.setOwnerName(userServiceResult.getResult().getName());
        }
        // 会话类型 2：企业群
        conversation.setConversationTag(chatInfo.getConversationTag().intValue());
        //是否开启群禁言：0（默认）：不禁言  1：全员禁言
        conversation.setChatBannedType(chatInfo.getChatBannedType().intValue());
        conversation.setSearchable(chatInfo.getSearchable().intValue());
        conversation.setValidationType(chatInfo.getValidationType().intValue());
        conversation.setMentionAllAuthority(chatInfo.getMentionAllAuthority().intValue());
        conversation.setManagementType(chatInfo.getManagementType().intValue());
        conversation.setShowHistoryType(chatInfo.getShowHistoryType() == null ? 0 : chatInfo.getShowHistoryType().intValue());
        conversation.setConversationIcon(chatInfo.getIcon());
        conversation.setStatus(chatInfo.getStatus().intValue());
        //群成员的userid列表
        List<String> useridlist = chatInfo.getUseridlist();
        if (CollUtil.isEmpty(useridlist)) {
            //所有成员退出，群已解散
            conversation.setStatus(CONVERSATION_STTAUS_DISMISS);
        }
        //更新群会话信息
        this.updateById(conversation);
        if (CONVERSATION_STTAUS_DISMISS.equals(conversation.getStatus())) {
            //删除会话文件关系
            docConversationRelService.remove(new LambdaQueryWrapper<DocConversationRel>()
                    .eq(DocConversationRel::getChatId, conversation.getChatId()));
            //删除会话文件分类关系
            docTypeConversationRelService.remove(new LambdaQueryWrapper<DocTypeConversationRel>()
                    .eq(DocTypeConversationRel::getChatId, conversation.getChatId()));
            //群已解散
            return JsonResult.success(SYNC_SUCCESS);
        }

        //群成员列表
        List<ConversationUserRel> conversationUserRelList = new ArrayList<>();
        //原有群成员
        List<ConversationUserRel> userRelList = conversationUserRelService
                .list(new LambdaQueryWrapper<ConversationUserRel>().eq(ConversationUserRel::getChatId, chatId));
        for (String userid : useridlist) {
            ConversationUserRel conversationUserRel = userRelList.stream().filter(u -> userid.equals(u.getUserId())).findFirst().orElse(null);
            if (conversationUserRel != null) {
                conversationUserRelList.add(conversationUserRel);
                continue;
            }
            conversationUserRel = new ConversationUserRel();
            conversationUserRel.setChatId(chatId);
            conversationUserRel.setOpenConversationId(conversation.getOpenConversationId());
            conversationUserRel.setUserId(userid);
            ServiceResult<UserDTO> userResult = dingTalkService.getUser(tokenService.getAccessToken(), userid);
            if (userResult.isSuccess()) {
                //用户手机号
                conversationUserRel.setPhone(userResult.getResult().getMobile());
                //用户头像
                conversationUserRel.setAvatar(userResult.getResult().getAvatar());
                //用户名
                conversationUserRel.setUserName(userResult.getResult().getName());
            }
            conversationUserRelList.add(conversationUserRel);
        }
        //先把原有群成员全部删除
        conversationUserRelService.remove(new LambdaQueryWrapper<ConversationUserRel>().eq(ConversationUserRel::getChatId, chatId));
        if (CollUtil.isNotEmpty(conversationUserRelList)) {
            conversationUserRelService.saveBatch(conversationUserRelList);
        }
        return JsonResult.success(SYNC_SUCCESS);
    }

    @Override
    public JsonResult batchSync(String conversationName, String ownerName) {
        LambdaQueryWrapper<Conversation> queryWrapper = Wrappers.lambdaQuery(new Conversation()).eq(Conversation::getStatus, CONVERSATION_STTAUS_NORMAL)
                .like(StringUtils.isNotBlank(conversationName), Conversation::getConversationName, conversationName)
                .like(StringUtils.isNotBlank(ownerName), Conversation::getOwnerName, ownerName);
        List<Conversation> conversations = baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(conversations)) {
            conversations.parallelStream().forEach(conversation -> {
                sync(conversation.getChatId());
            });
        }
        return JsonResult.success(SYNC_SUCCESS);
    }

    @Override
    public List<ConversationDropListResponse> getDropList() {
        List<Conversation> conversationList = this.baseMapper.selectList(new LambdaQueryWrapper<Conversation>()
                .eq(Conversation::getStatus, 1)
                .orderByDesc(Conversation::getCreateTime));
        List<ConversationDropListResponse> responseList = new ArrayList<>();
        conversationList.stream().forEach(c -> {
            ConversationDropListResponse response = new ConversationDropListResponse();
            BeanUtil.copyProperties(c, response);
            responseList.add(response);
        });
        return responseList;
    }


}
