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 com.gic.enterprise.api.dto.StoreDTO;
import com.gic.enterprise.api.service.StoreService;
import com.gic.haoban.manage.api.dto.MemberGroupFriendDTO;
import com.gic.haoban.manage.service.dao.mapper.TabHaobanClerkMainStoreRelatedMapper;
import com.gic.haoban.manage.service.dao.mapper.chat.GroupChatMapper;
import com.gic.haoban.manage.service.dao.mapper.chat.GroupChatUserMapper;
import com.gic.haoban.manage.service.entity.*;
import com.gic.haoban.manage.service.entity.chat.TabGroupChat;
import com.gic.haoban.manage.service.entity.chat.TabGroupChatUser;
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.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 ;
    @Autowired
    private TabHaobanClerkMainStoreRelatedMapper clerkMainStoreRelatedMapper ;
    @Autowired
    private StoreService storeService ;
    @Autowired
    private GroupChatMapper groupChatMapper ;
    @Autowired
    private GroupChatUserMapper groupChatUserMapper ;
    private static final String SELF_APP = "selfSuiteId";

    @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);
            });
            // 处理关联关系
            List<String> staffIdList = dtoList.stream().filter(dto -> StringUtils.isNotBlank(dto.getStaffId()))
                    .map(dto -> dto.getStaffId()).collect(Collectors.toList());
            List<String> relationStaffIdList = null ;
            if (CollectionUtils.isNotEmpty(staffIdList)) {
                relationStaffIdList = this.staffClerkRelationService.listRelationsStaffId(new HashSet<>(staffIdList));
                for (GroupChatDTO one : dtoList) {
                    one.setClerkRelationFlag(relationStaffIdList.contains(one.getStaffId()) ? 1 : 0);
                }
                if(CollectionUtils.isNotEmpty(relationStaffIdList)) {
                    List<TabHaobanClerkMainStoreRelated> storeRelationList = this.clerkMainStoreRelatedMapper.listByStaffIdList(relationStaffIdList);
                    if(CollectionUtils.isNotEmpty(storeRelationList)) {
                        List<String> storeIdList = storeRelationList.stream().map(o->o.getStoreId()).collect(Collectors.toSet()).stream().collect(Collectors.toList());
                        String[] arr = storeIdList.toArray(new String[storeIdList.size()]) ;
                        List<StoreDTO> storeList = this.storeService.getStores(arr) ;
                        if(CollectionUtils.isNotEmpty(storeList)) {
                            Map<String,String> staffMap = storeRelationList.stream().collect(Collectors.toMap(TabHaobanClerkMainStoreRelated::getStaffId,TabHaobanClerkMainStoreRelated::getStoreId,(k1,k2)->k1)) ;
                            Map<String,StoreDTO> storeMap = storeList.stream().collect(Collectors.toMap(StoreDTO::getStoreId,o->o,(k1,k2)->k1)) ;
                            for (GroupChatDTO one : dtoList) {
                                String staffId = one.getStaffId() ;
                                String storeId = staffMap.get(staffId) ;
                                if(StringUtils.isNotBlank(storeId)) {
                                    StoreDTO store = storeMap.get(storeId) ;
                                    if(null != store) {
                                        one.setOwnerStoreCode(store.getStoreCode());
                                        one.setOwnerStoreName(store.getStoreName());
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // 原群主
            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.getWxSecurityType()==5) {
            if (qwDTO.isSelf() && dto.getSelfCallback() == 0) {
                logger.info("非自建应用回调");
                return ServiceResponse.success();
            }
        }
        if(qwDTO.getWxSecurityType() !=6 && StringUtils.isNotBlank(dto.getSuiteId()) && SELF_APP.equals(dto.getSuiteId())) {
            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();
    }

    @Override
    public ServiceResponse<GroupChatDTO> getByWxChatId(String wxEnterpriseId, String wxChatId) {
        TabGroupChat groupChat = this.groupChatMapper.selectByWxChatId(wxEnterpriseId, wxChatId);
        if(null == groupChat) {
            groupChat =  this.groupChatMapper.selectByWxChatIdDk(wxEnterpriseId,wxChatId) ;
        }
        if(null == groupChat) {
            return ServiceResponse.success(null) ;
        }
        GroupChatDTO dto = EntityUtil.changeEntityByJSON(GroupChatDTO.class,groupChat) ;
        return ServiceResponse.success(dto);
    }

    @Override
    public GroupChatUserDTO getGroupUserInfo(Long groupChatId, String externalUserId) {
        TabGroupChatUser tab = this.groupChatUserMapper.getGroupUserInfo(groupChatId,externalUserId) ;
        if(null != tab) {
            GroupChatUserDTO dto = EntityUtil.changeEntityByJSON(GroupChatUserDTO.class,tab) ;
            return dto ;
        }
        return null;
    }

    @Override
    public List<String> listOpenGroupChatDK(String enterpriseId, String staffId) {
        return this.groupChatMapper.listOpenGroupChatDK(enterpriseId,staffId);
    }

    @Override
    public ServiceResponse<MemberGroupFriendDTO> memberIsAddGroup(String enterpriseId, String memberId) {
        List<TabGroupChatUser> list = this.groupChatUserService.getByMember(enterpriseId,memberId) ;
        if(CollectionUtils.isNotEmpty(list)) {
            logger.info("会员入群数={}",memberId,list.size());
            TabGroupChatUser item = list.get(0) ;
            MemberGroupFriendDTO dto = new MemberGroupFriendDTO() ;
            dto.setType(1);
            Long groupChatId = item.getGroupChatId() ;
            TabGroupChat group = this.groupChatMapper.selectById(groupChatId) ;
            if(null != group) {
                dto.setGroupChatId(groupChatId);
                dto.setRemark(group.getName()+"("+groupChatId+")");
                return ServiceResponse.success(dto);
            }
        }
        return ServiceResponse.success(null);
    }

    @Override
    public ServiceResponse<Boolean> isAddGroup(String enterpriseId, String memberId) {
        return ServiceResponse.success(this.groupChatUserService.isAddGroupChat(enterpriseId,memberId)>0);
    }
}
