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

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSONObject;
import com.gic.clerk.api.dto.ClerkDTO;
import com.gic.clerk.api.service.ClerkService;
import com.gic.commons.util.EntityUtil;
import com.gic.haoban.manage.api.dto.StaffClerkRelationDTO;
import com.gic.haoban.manage.api.dto.StaffDTO;
import com.gic.haoban.manage.api.dto.StaffDepartmentRelatedDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.enums.AppPageType;
import com.gic.haoban.manage.api.enums.NoticeMessageTypeEnum;
import com.gic.haoban.manage.api.service.StaffApiService;
import com.gic.haoban.manage.api.service.StaffDepartmentRelatedApiService;
import com.gic.haoban.manage.api.util.notify.NoticeMessageUtil;
import com.gic.haoban.manage.service.config.Config;
import com.gic.haoban.manage.service.dao.mapper.StaffDepartmentRelatedMapper;
import com.gic.haoban.manage.service.dao.mapper.TabHaobanStaffClerkRelationMapper;
import com.gic.haoban.manage.service.entity.TabHaobanStaffDepartmentRelated;
import com.gic.haoban.manage.service.entity.TabHaobanWxEnterprise;
import com.gic.haoban.manage.service.service.StaffDepartmentRelatedService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.wechat.api.dto.qywx.ItemDTO;
import com.gic.wechat.api.dto.qywx.QywxXcxSendMessageDTO;
import com.gic.wechat.api.service.qywx.QywxSuiteApiService;

import cn.hutool.core.collection.CollectionUtil;

@Service
public class StaffDepartmentRelatedApiServiceImpl implements StaffDepartmentRelatedApiService {
    private static final Logger logger = LoggerFactory.getLogger(StaffDepartmentRelatedApiServiceImpl.class);

    @Autowired
    private StaffDepartmentRelatedService staffDepartmentRelatedService;
    @Autowired
    private StaffDepartmentRelatedMapper staffDepartmentRelatedMapper;
    @Autowired
    private ClerkService clerkService;
    @Autowired
    private QywxSuiteApiService qywxSuiteApiService;
    @Autowired
    private Config config;
    @Autowired
    private TabHaobanStaffClerkRelationMapper tabHaobanStaffClerkRelationMapper;
    @Autowired
    private StaffApiService staffApiService;
    @Autowired
    private WxEnterpriseService wxEnterpriseService;

    @Override
    public List<StaffDepartmentRelatedDTO> listByDepartmentId(String departmentId) {
        List<TabHaobanStaffDepartmentRelated> list = staffDepartmentRelatedService.listByDepartmentId(departmentId);
        List<StaffDepartmentRelatedDTO> resultList = EntityUtil.changeEntityListByJSON(StaffDepartmentRelatedDTO.class, list);
        return resultList;
    }

    @Override
    public void updateById(StaffDepartmentRelatedDTO dto) {
        TabHaobanStaffDepartmentRelated tab = EntityUtil.changeEntityByJSON(TabHaobanStaffDepartmentRelated.class, dto);
        staffDepartmentRelatedMapper.updateByPrimaryKeySelective(tab);
    }

    @Override
    public StaffDepartmentRelatedDTO getByStaffDepartmentRelatedId(String staffDepartmentRelatedId) {
        TabHaobanStaffDepartmentRelated tab = staffDepartmentRelatedMapper.getById(staffDepartmentRelatedId);
        if (Objects.isNull(tab)) {
            return null;
        }
        StaffDepartmentRelatedDTO dto = EntityUtil.changeEntity(StaffDepartmentRelatedDTO.class, tab);
        return dto;
    }

    @Override
    public List<StaffDepartmentRelatedDTO> listByStaffId(String staffId) {
        List<TabHaobanStaffDepartmentRelated> list = staffDepartmentRelatedMapper.listStaffDepartmentByStaffId(staffId);
        if (CollectionUtil.isEmpty(list)) {
            return new ArrayList<StaffDepartmentRelatedDTO>();
        }
        List<StaffDepartmentRelatedDTO> resultList = EntityUtil.changeEntityListByJSON(StaffDepartmentRelatedDTO.class, list);
        return resultList;
    }

    @Override
    public List<StaffDepartmentRelatedDTO> listByStaffIds(List<String> staffIds) {
        List<TabHaobanStaffDepartmentRelated> list = staffDepartmentRelatedMapper.listStaffDepartmentByStaffIds(staffIds);
        if (CollectionUtil.isEmpty(list)) {
            return new ArrayList<StaffDepartmentRelatedDTO>();
        }
        List<StaffDepartmentRelatedDTO> resultList = EntityUtil.changeEntityListByJSON(StaffDepartmentRelatedDTO.class, list);
        return resultList;
    }

    @Override
    public Map<String, String> getWxUserIdByClerkId(String clerkId) {
        Map<String, String> map = new HashMap<>();

        StaffClerkRelationDTO relation = tabHaobanStaffClerkRelationMapper.getOneByClerkId(clerkId,null);
        if (relation == null) {
            return map;
        }
        ClerkDTO clerkDTO = clerkService.getclerkById(clerkId);
        if (clerkDTO == null) {
            return map;
        }
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(relation.getWxEnterpriseId());
        StaffDTO staffDTO = staffApiService.selectById(relation.getStaffId());
        if (staffDTO == null) {
            return map;
        }
        String wxUserId = "";
        if (qwDTO.needOpenUserId3th()) {
            wxUserId = staffDTO.getWxOpenUseId();
        } else {
            wxUserId = staffDTO.getWxUserId();
        }
        map.put("wxUserId", wxUserId);
        map.put("wxEnterpriseId", qwDTO.getWxEnterpriseId());
        map.put("corpId", qwDTO.getThirdCorpid());
        map.put("clerkName", clerkDTO.getClerkName());
        return map;
    }

    public Map<String, String> getWxUserIdByStaffId(String staffId) {
        Map<String, String> map = new HashMap<>();
        StaffDTO staffDTO = staffApiService.selectById(staffId);
        if (staffDTO == null) {
            return map;
        }
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(staffDTO.getWxEnterpriseId());
        String wxUserId = staffDTO.getWxUserId();
        if (qwDTO.needOpenUserId3th()) {
            wxUserId = staffDTO.getWxOpenUseId();
        }
        map.put("wxUserId", wxUserId);
        map.put("wxEnterpriseId", qwDTO.getWxEnterpriseId());
        map.put("corpId", qwDTO.getThirdCorpid());
        map.put("staffName", staffDTO.getStaffName());
        return map;
    }

    //导购新增，，审核记录，，消息发送
    @Override
    public void sendClerkAdd(String clerkName, String clerkCode, String storeId, int auditStatus, String auditReason) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("storeId", storeId);
        ClerkDTO gicClerk = clerkService.getClerkLeaderByStoreId(storeId);
        if (gicClerk == null) {
            logger.info("店长不存在，发送消息失败{}", storeId);
            return;
        }
        StaffClerkRelationDTO tab = tabHaobanStaffClerkRelationMapper.getOneByClerkId(gicClerk.getClerkId(),null);
        if (tab == null) {
            logger.info("店长未绑定clerkId={}", gicClerk.getClerkId());
            return;
        }
        Map<String, String> params = new HashMap<String, String>();
        params.put("clerkName", clerkName);
        params.put("clerkCode", clerkCode);
        params.put("reason", auditReason);
        if (auditStatus == 1) {
            NoticeMessageUtil.sendNoticeMessage(tab.getEnterpriseId(), tab.getClerkId()
                    , NoticeMessageTypeEnum.CLERK_ADD_AGREE.getType(), null, params, jsonObject);
        } else {
            NoticeMessageUtil.sendNoticeMessage(tab.getEnterpriseId(), tab.getClerkId()
                    , NoticeMessageTypeEnum.CLERK_ADD_REFUSE.getType(), null, params, jsonObject);
        }

    }

    //导购删除，，审核记录，，消息发送
    @Override
    public void sendClerkDel(String clerkName, String clerkCode, String storeId, int auditStatus, String auditReason) {
//		String messageTitle = "门店导购变更";
//		String messageContent = "删除导购：" + clerkName + "（" + clerkCode + "）";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("storeId", storeId);
        ClerkDTO gicClerk = clerkService.getClerkLeaderByStoreId(storeId);
        if (gicClerk == null) {
            logger.info("店长不存在，发送消息失败{}", storeId);
            return;
        }
        StaffClerkRelationDTO tab = tabHaobanStaffClerkRelationMapper.getOneByClerkId(gicClerk.getClerkId(),null);
        if (tab == null) {
            logger.info("店长未绑定clerkId={}", gicClerk.getClerkId());
            return;
        }
//		String pageUrl = this.getPageUrl(AppPageType.STORE_RELATED_RECORD.getCode(), data);
//		this.sendAuditMessage(tab.getStaffId(), messageTitle, messageContent, pageUrl,auditStatus,auditReason);

        Map<String, String> params = new HashMap<String, String>();
        params.put("clerkName", clerkName);
        params.put("clerkCode", clerkCode);
        params.put("reason", auditReason);
        if (auditStatus == 1) {
            NoticeMessageUtil.sendNoticeMessage(tab.getEnterpriseId(), tab.getClerkId()
                    , NoticeMessageTypeEnum.CLERK_DEL_AGREE.getType(), null, params, jsonObject);
        } else {
            NoticeMessageUtil.sendNoticeMessage(tab.getEnterpriseId(), tab.getClerkId()
                    , NoticeMessageTypeEnum.CLERK_DEL_REFUSE.getType(), null, params, jsonObject);
        }
    }

    @Override
    public boolean sendSingleMessage(String clerkId, String title,
                                     String content, String pageUrl) {
        if (StringUtils.isEmpty(clerkId)) {
            logger.info("clerkId不存在============>");
            return false;
        }
        Map<String, String> map = getWxUserIdByClerkId(clerkId);
        String wxUserId = map.get("wxUserId");
        String corpId = map.get("corpId");
        String name = map.get("clerkName");

        if (StringUtils.isBlank(wxUserId)) {
            logger.info("wxUserId不存在============clerkId={}", clerkId);
            return false;
        }
        if (content.length() > 30) {
            content = content.substring(0, 26);
            content = content + "...";
        }
        QywxXcxSendMessageDTO messageDTO = new QywxXcxSendMessageDTO();
        List<ItemDTO> items = new ArrayList();
        ItemDTO dto1 = new ItemDTO();
        ItemDTO dto2 = new ItemDTO();
        dto1.setKey("接收人");
        dto1.setValue(name);
        dto2.setKey("接收事件");
        dto2.setValue(content);
        items.add(dto1);
        items.add(dto2);
        ArrayList<String> list = new ArrayList<>();
        list.add(wxUserId);
        TabHaobanWxEnterprise wxEnterprise = this.wxEnterpriseService.getEnterpriseBycorpId(corpId);
        WxEnterpriseQwDTO qwDTO =this.wxEnterpriseService.getQwInfo(wxEnterprise.getWxEnterpriseId()) ;
        messageDTO.setAppid(qwDTO.getHbWxaAppid());
        messageDTO.setUserIds(list);
        messageDTO.setPage(pageUrl);
        messageDTO.setTitle(title);
        messageDTO.setItems(items);

        logger.info("发送参数为corpId============:{},suitId============:{},messageDTO============:{},", corpId, config.getWxSuiteid(), JSONObject.toJSONString(messageDTO));
        boolean b = qywxSuiteApiService.sendMessage(corpId, qwDTO.getSelf3thSecret(), messageDTO,qwDTO.isSelf(),qwDTO.getUrlHost());
        logger.info("发送===============》{}", b);
        return b;
    }


    /**
     * 单人消息发送通用方法
     *
     * @param clerkId    : 接收人id
     * @param title      : 通知标题
     * @param contentMap : 时间集合, key 为类型, value : 内容(例如 接收事件 : 事件内容)
     * @param pageUrl    : 跳转地址
     * @return : 返回是否发送成功
     */
    @Override
    public Boolean sendSingleMessage(String clerkId, String title, Map<String, String> contentMap, String pageUrl) {
        if (StringUtils.isEmpty(clerkId)) {
            logger.info("消息接收人不存在");
            return Boolean.FALSE;
        }
        if (CollectionUtils.isEmpty(contentMap)) {
            logger.info("发送事件内容不存在");
            return Boolean.FALSE;
        }
        Map<String, String> map = this.getWxUserIdByClerkId(clerkId);
        String wxUserId = map.get("wxUserId");
        String corpId = map.get("corpId");
        String name = map.get("clerkName");
        if (jodd.util.StringUtil.isEmpty(wxUserId)) {
            logger.info("接收人wxUserId不存在, clerkId : {}", clerkId);
            return Boolean.FALSE;
        }
        //组装发送内容
        List<ItemDTO> contentList = new ArrayList<>();
        ItemDTO dto = new ItemDTO();
        dto.setKey("接收人");
        dto.setValue(name);
        contentList.add(dto);
        contentMap.forEach((key, value) -> {
            ItemDTO itemDTO = new ItemDTO();
            itemDTO.setKey(key);
            String content = value.length() > 30 ? value.substring(0, 26) + "..." : value;
            itemDTO.setValue(content);
            contentList.add(itemDTO);
        });
        QywxXcxSendMessageDTO messageDTO = new QywxXcxSendMessageDTO();
        TabHaobanWxEnterprise wxEnterprise = this.wxEnterpriseService.getEnterpriseBycorpId(corpId);
        WxEnterpriseQwDTO qwDTO =this.wxEnterpriseService.getQwInfo(wxEnterprise.getWxEnterpriseId()) ;
        messageDTO.setAppid(qwDTO.getHbWxaAppid());
        messageDTO.setUserIds(Collections.singletonList(wxUserId));
        messageDTO.setTitle(title);
        messageDTO.setItems(contentList);
        messageDTO.setPage(pageUrl);
        logger.info("消息发送, corpId : {}, suitId : {}, messageDTO : {}", corpId, config.getWxSuiteid(), JSONObject.toJSONString(messageDTO));
        boolean sendResult = qywxSuiteApiService.sendMessage(corpId, qwDTO.getSelf3thSecret(), messageDTO,qwDTO.isSelf(),qwDTO.getUrlHost());
        logger.info("消息发送结果, sendResult : {}", sendResult);
        return sendResult;
    }

    @Override
    public boolean sendAuditMessage(String staffId, String title,
                                    String content, String pageUrl, int auditStatus, String auditReason) {
        Map<String, String> map = getWxUserIdByStaffId(staffId);
        String wxUserId = map.get("wxUserId");
        String corpId = map.get("corpId");
        String name = map.get("staffName");

        if (StringUtils.isEmpty(wxUserId)) {
            logger.info("wxUserId不存在============clerkId={}", staffId);
            return false;
        }
        if (content.length() > 30) {
            content = content.substring(0, 26);
            content = content + "...";
        }
        //先发送下，试试
        QywxXcxSendMessageDTO messageDTO = new QywxXcxSendMessageDTO();
        List<ItemDTO> items = new ArrayList();
        ItemDTO dto1 = new ItemDTO();
        ItemDTO dto2 = new ItemDTO();
        ItemDTO dto3 = new ItemDTO();
        ItemDTO dto4 = new ItemDTO();

        dto1.setKey("接收人");
        dto1.setValue(name);
        dto2.setKey("接收事件");
        dto2.setValue(content);
        dto3.setKey("结果");
        dto3.setValue(auditStatus == 1 ? "已同意" : "已拒绝");
        items.add(dto1);
        items.add(dto2);
        items.add(dto3);
        if (StringUtils.isNotEmpty(auditReason)) {
            dto4.setKey("理由");
            dto4.setValue(auditReason);
            items.add(dto4);
        }
        ArrayList<String> list = new ArrayList<>();
        list.add(wxUserId);
        TabHaobanWxEnterprise wxEnterprise = this.wxEnterpriseService.getEnterpriseBycorpId(corpId);
        WxEnterpriseQwDTO qwDTO =this.wxEnterpriseService.getQwInfo(wxEnterprise.getWxEnterpriseId()) ;
        messageDTO.setAppid(qwDTO.getHbWxaAppid());
        messageDTO.setUserIds(list);
        messageDTO.setPage(pageUrl);
        messageDTO.setTitle(title);
        messageDTO.setItems(items);

        logger.info("发送消息参数为corpId={},messageDTO={},", corpId, JSONObject.toJSONString(messageDTO));
        boolean b = qywxSuiteApiService.sendMessage(corpId, qwDTO.getSelf3thSecret(), messageDTO,qwDTO.isSelf(),qwDTO.getUrlHost());
        logger.info("发送消息返回={}", b);
        return b;
    }

    @Override
    public String getPageUrl(int type, String data) {
        String baseUrl = "/pages/route/index";
        String addurl = AppPageType.getDescByCode(type);
        String url = "";
        if (type == AppPageType.INDEX.getCode()) {
            //工作台
            url = baseUrl + "?pageType=" + addurl;
        } else {
            url = baseUrl + "?pageType=" + addurl;
        }
        url = url + "&data=";
        String encodeData = null;
        try {
            encodeData = URLEncoder.encode(data, StandardCharsets.UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            logger.error(e.getMessage());
        }
        url = url + encodeData;
        return url;
    }


    @Override
    public void sendBindAuditMessage(String auditId, String staffId, String clerkId, String reason, boolean isRefuse) {
        logger.info("发送审核消息：auditId:{},clerkId:{},reason:{},isRefuse:{}", auditId, clerkId, reason, isRefuse);
        ClerkDTO clerkDTO = clerkService.getClerkByClerkId(clerkId);
        if (clerkDTO == null) {
            return;
        }
        String enterpriseId = clerkDTO.getEnterpriseId();
        //字段
        Map<String, String> params = new HashMap<String, String>();
        params.put("staffName", clerkDTO.getClerkName());
        params.put("clerkCode", clerkDTO.getClerkCode());
        params.put("reason", reason);
        //参数
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("storeId", clerkDTO.getStoreId());
        //发送消息
        if (isRefuse) {
            NoticeMessageUtil.sendNoticeMessageByStaff(enterpriseId, staffId, clerkId, NoticeMessageTypeEnum.STORE_ACCOUNT_REFUSE.getType(), auditId, params, jsonObject);
        } else {
            NoticeMessageUtil.sendNoticeMessageByStaff(enterpriseId, staffId, clerkId, NoticeMessageTypeEnum.STORE_ACCOUNT_AGREE.getType(), auditId, params, jsonObject);
        }

    }
}
