package com.gic.haoban.manage.service.service.out.impl.chat;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.BasePageInfo;
import com.gic.api.base.commons.Page;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.commons.util.DateUtil;
import com.gic.commons.util.EntityUtil;
import com.gic.commons.util.PageHelperUtils;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.dto.chat.ChatEventDTO;
import com.gic.haoban.manage.api.dto.chat.GroupChatDTO;
import com.gic.haoban.manage.api.dto.chat.GroupChatOwnerDTO;
import com.gic.haoban.manage.api.dto.chat.GroupChatOwnerHistoryDTO;
import com.gic.haoban.manage.api.dto.chat.GroupChatUserDTO;
import com.gic.haoban.manage.api.dto.qdto.chat.GroupChatSearchQDTO;
import com.gic.haoban.manage.api.dto.qdto.chat.GroupChatUserSearchQDTO;
import com.gic.haoban.manage.api.dto.qdto.chat.OwnerSearchQDTO;
import com.gic.haoban.manage.api.service.chat.GroupChatApiService;
import com.gic.haoban.manage.service.entity.TabHaobanStaff;
import com.gic.haoban.manage.service.entity.TabHaobanWxEnterprise;
import com.gic.haoban.manage.service.entity.TabHaobanWxEnterpriseRelated;
import com.gic.haoban.manage.service.pojo.bo.chat.GroupChatBO;
import com.gic.haoban.manage.service.service.StaffClerkRelationService;
import com.gic.haoban.manage.service.service.StaffService;
import com.gic.haoban.manage.service.service.WxEnterpriseRelatedService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.haoban.manage.service.service.chat.GroupChatService;
import com.gic.haoban.manage.service.service.chat.GroupChatUserService;

@Service("groupChatApiService")
public class GroupChatApiServiceImpl implements GroupChatApiService {

    private static final Logger logger = LogManager.getLogger(GroupChatApiService.class);

    @Autowired
    private GroupChatService groupChatService;
    @Autowired
    private GroupChatUserService groupChatUserService;
    @Autowired
    private StaffService staffService;
    @Autowired
    private WxEnterpriseRelatedService wxEnterpriseRelatedService;
    @Autowired
    private StaffClerkRelationService staffClerkRelationService;
    @Autowired
    private WxEnterpriseService wxEnterpriseService ;

    @Override
    public ServiceResponse<Page<GroupChatDTO>> listPage(GroupChatSearchQDTO qdto, BasePageInfo basePageInfo) {
        if (null != qdto.getEndDate()) {
            qdto.setEndDate(DateUtil.getEndTimeOfDay(qdto.getEndDate()));
        }
        String wxEnterpriseId = qdto.getWxEnterpriseId();
        Page<GroupChatDTO> page = this.groupChatService.listPage(qdto, basePageInfo);
        Page<GroupChatDTO> resultPage = PageHelperUtils.changePageToCurrentPage(page, GroupChatDTO.class);
        List<GroupChatDTO> dtoList = resultPage.getResult();
        // 处理关联状态
        if (CollectionUtils.isNotEmpty(dtoList)) {
            // 处理群主状态
            Map<String, TabHaobanStaff> map = this.getStaffMap(wxEnterpriseId, dtoList, 0);
            dtoList.forEach(one -> {
                TabHaobanStaff staff = map.get(one.getStaffId());
                String reamrk = null;
                Integer ownerAddFlag = 1;
                if (null == staff || staff.getStatusFlag() == 0) {
                    reamrk = "群主不存在";
                    ownerAddFlag = 0;
                } else {
                    Integer activiveFlag = staff.getActiveFlag();
                    Integer openConcatFlag = staff.getOpenConcatFlag();
                    if (activiveFlag == 0) {
                        ownerAddFlag = 0;
                        reamrk = "群主未激活";
                    } else if (openConcatFlag == 0) {
                        ownerAddFlag = 0;
                        reamrk = "群主未配置客户联系功能";
                    }
                }
                one.setOwnerRemark(reamrk);
                one.setOwnerAddFlag(ownerAddFlag);
            });
            // 处理关联关系
            boolean needClerkReltaion = (qdto.getStatus() == 0);
            if (needClerkReltaion) {
                List<String> staffIdList = dtoList.stream().filter(dto -> StringUtils.isNotBlank(dto.getStaffId()))
                        .map(dto -> dto.getStaffId()).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(staffIdList)) {
                    List<String> relationIdList = this.staffClerkRelationService
                            .listRelationsStaffId(new HashSet<>(staffIdList));
                    dtoList.forEach(one -> {
                        one.setClerkRelationFlag(relationIdList.contains(one.getStaffId()) ? 1 : 0);
                    });
                }
            }
            // 原群主
            if (qdto.getStatus() == 2) {
                Map<String, TabHaobanStaff> staffMap = this.getStaffMap(wxEnterpriseId, dtoList, 1);
                dtoList.forEach(one -> {
                    String staffId = one.getOriginalStaffId();
                    TabHaobanStaff staff = staffMap.get(staffId);
                    if (null != staff) {
                        one.setOriginalStaffName(staff.getStaffName());
                    }
                });
            }
        }
        return ServiceResponse.success(resultPage);
    }

    private Map<String, TabHaobanStaff> getStaffMap(String wxEnterpriseId, List<GroupChatDTO> dtoList, int staffType) {
        Set<String> staffIdSet = null;
        // 原群主
        if (staffType == 1) {
            staffIdSet = dtoList.stream().filter(dto -> StringUtils.isNotBlank(dto.getOriginalStaffId()))
                    .map(dto -> dto.getOriginalStaffId()).collect(Collectors.toSet());
        } else {
            staffIdSet = dtoList.stream().filter(dto -> StringUtils.isNotBlank(dto.getStaffId()))
                    .map(dto -> dto.getStaffId()).collect(Collectors.toSet());
        }
        List<String> staffIdList = new ArrayList<>(staffIdSet);
        Map<String, TabHaobanStaff> map = new HashMap<>();
        if (CollectionUtils.isNotEmpty(staffIdList)) {
            List<TabHaobanStaff> staffList = this.staffService.listNoStatusByStaffIds(wxEnterpriseId, staffIdList);
            if (CollectionUtils.isNotEmpty(staffList)) {
                map = staffList.stream().collect(Collectors.toMap(TabHaobanStaff::getStaffId, o -> o, (k1, k2) -> k2));
            }
        }
        return map;
    }

    @Override
    public ServiceResponse<Page<GroupChatUserDTO>> listUserPage(GroupChatUserSearchQDTO qdto,
            BasePageInfo basePageInfo) {
        if (null != qdto.getEndDate()) {
            qdto.setEndDate(DateUtil.getEndTimeOfDay(qdto.getEndDate()));
        }
        Page<GroupChatUserDTO> page = this.groupChatUserService.listPage(qdto, basePageInfo);
        return ServiceResponse.success(page);
    }

    @Override
    public ServiceResponse<GroupChatDTO> detail(String wxEnterpriseId, Long groupChatId) {
        GroupChatBO bo = this.groupChatService.detail(wxEnterpriseId, groupChatId);
        GroupChatDTO dto = EntityUtil.changeEntityByJSON(GroupChatDTO.class, bo);
        if (StringUtils.isNotBlank(dto.getStaffId())) {
            TabHaobanStaff staff = this.staffService.selectById(dto.getStaffId());
            if (null != staff) {
                dto.setStaffName(staff.getStaffName());
                dto.setStaffImage(staff.getHeadImg());
            }
        }
        return ServiceResponse.success(dto);
    }

    @Override
    public ServiceResponse<Void> updateChatEnterpriseId(String wxEnterpriseId, String enterpriseId,
            List<Long> groupChatIdList) {
        this.groupChatService.updateChatEnterpriseId(wxEnterpriseId, enterpriseId, groupChatIdList);
        return ServiceResponse.success();
    }

    @Override
    public ServiceResponse<Page<GroupChatOwnerDTO>> listOwnerPage(OwnerSearchQDTO qdto, BasePageInfo basePageInfo) {
        Page<GroupChatOwnerDTO> page = this.groupChatService.listOwnerPage(qdto, basePageInfo);
        return ServiceResponse.success(page);
    }

    @Override
    public ServiceResponse<Void> qwEventNotice(ChatEventDTO dto) {
        logger.info("收到群事件,params={}", JSON.toJSONString(dto));
        String changeType = dto.getChangeType();
        String wxChatId = dto.getChatId();
        String corpid = dto.getCorpid();
        TabHaobanWxEnterprise wxEnterprise = this.wxEnterpriseService.getEnterpriseBycorpId(corpid);
        if (wxEnterprise == null) {
            logger.info("企业不存在,corpid={}", corpid);
            return ServiceResponse.success();
        }
        String wxEnterpriseId =  wxEnterprise.getWxEnterpriseId();
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
        if(qwDTO.isSelf() && dto.getSelfCallback()==0) {
            logger.info("非自建应用回调");
            return ServiceResponse.success();
        }
        // 群解散事件
        if ("dismiss".equals(changeType)) {
            this.groupChatService.dismissChat(corpid, wxChatId);
        } else if ("create".equals(changeType)) {
            // 创建群
            this.groupChatService.createChat(corpid, wxChatId);
        } else {
            String updateDetail = dto.getUpdateDetail();
            this.groupChatService.updateChat(corpid, wxChatId, updateDetail, JSON.toJSONString(dto));
        }
        return ServiceResponse.success();
    }

    @Override
    public ServiceResponse<List<GroupChatOwnerHistoryDTO>> listOwnerHistory(Long groupChatId, String WxEnterpriseId) {
        return ServiceResponse.success(this.groupChatService.listOwnerHistory(groupChatId, WxEnterpriseId));
    }

    @Override
    public ServiceResponse<Void> transfer(String wxEnterpriseId, String staffId, List<Long> groupChatIdList) {
        return this.groupChatService.transfer(wxEnterpriseId, staffId, groupChatIdList);
    }

    @Override
    public ServiceResponse<List<GroupChatDTO>> listChatByIdList(String wxEnterpriseId, List<Long> groupChatIdList) {
        List<GroupChatBO> list = this.groupChatService.listChatByIdList(groupChatIdList);
        return ServiceResponse.success(EntityUtil.changeEntityListByJSON(GroupChatDTO.class, list));
    }

    @Override
    public ServiceResponse<Boolean> getSetGicFlag(String wxEnterpriseId) {
        List<TabHaobanWxEnterpriseRelated> list = this.wxEnterpriseRelatedService.getByWxEnterpriseId(wxEnterpriseId);
        if (CollectionUtils.isNotEmpty(list) && list.size() == 1) {
            return ServiceResponse.success(Boolean.FALSE);
        }
        return ServiceResponse.success(Boolean.TRUE);
    }

    @Override
    public ServiceResponse<Void> refreshChatInfoFromMQ(String params) {
        JSONObject json = JSONObject.parseObject(params);
        List<Long> arr = JSONObject.parseArray(json.getString("groupChatIdList"), Long.class);
        for (Long id : arr) {
            this.groupChatService.refreshChatInfo(id);
        }
        return ServiceResponse.success();
    }

    @Override
    public ServiceResponse<Void> refreshChatStatusFromMQ(String params) {
        JSONObject json = JSONObject.parseObject(params);
        List<Long> arr = JSONObject.parseArray(json.getString("groupChatIdList"), Long.class);
        for (Long id : arr) {
            this.groupChatService.refreshChatStatus(id);
        }
        return ServiceResponse.success();
    }
}
