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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.ServiceResponse;
import com.gic.enterprise.api.constant.EnterpriseServiceEnum;
import com.gic.enterprise.api.dto.EnterpriseSettingDTO;
import com.gic.enterprise.api.service.EnterpriseService;
import com.gic.enterprise.api.service.EnterpriseUseForbidService;
import com.gic.haoban.manage.api.dto.QwPendingIdDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.service.QwFriendApiService;
import com.gic.haoban.manage.service.config.Config;
import com.gic.haoban.manage.service.errorcode.HaoBanErrCode;
import com.gic.haoban.manage.service.pojo.bo.WxEnterpriseRelationBO;
import com.gic.haoban.manage.service.service.WxEnterpriseRelatedService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.haoban.manage.service.util.QwInterfaceLimitEnum;
import com.gic.haoban.manage.service.util.QwTimesUtils;
import com.gic.member.api.dto.MemberWechatInfoDTO;
import com.gic.member.api.service.MemberApiService;
import com.gic.wechat.api.dto.qywx.PendingIdDTO;
import com.gic.wechat.api.service.qywx.QywxExternalUserService;

@Service("qwFriendApiService")
public class QwFriendApiServiceImpl implements QwFriendApiService {

    private static final Logger log = LogManager.getLogger(QwFriendApiService.class);
    private int subjectType = 0 ;

    @Autowired
    private EnterpriseUseForbidService enterpriseUseForbidService;
    @Autowired
    private QywxExternalUserService qywxExternalUserService;
    @Autowired
    private WxEnterpriseRelatedService wxEnterpriseRelatedService;
    @Autowired
    private WxEnterpriseService wxEnterpriseService;
    @Autowired
    private EnterpriseService enterpriseService ;
    @Autowired
    private Config config;
    @Autowired
    private MemberApiService memberApiService ;
    
    @Override
    public ServiceResponse<Map<String, String>> pendingIdCheck(String enterpriseId) {
        ServiceResponse<MemberWechatInfoDTO> resp = this.memberApiService.getMemberWechatInfo(enterpriseId) ;
        log.info("pendingId校验查询={}",JSON.toJSON(resp));
        if(!resp.isSuccess()) {
            return ServiceResponse.failure("9999", resp.getMessage()) ;
        }
        MemberWechatInfoDTO dto = resp.getResult() ;
        String unionid = dto.getUnionId() ;
        String openid =  dto.getOpenId() ;
        String wxaUnionid =  dto.getUnionId() ;
        String wxaOpenid = dto.getWxaOpenId() ;
        return this.pendingIdCheck(enterpriseId, unionid, openid, wxaUnionid, wxaOpenid,false);
    }

    public ServiceResponse<Map<String, String>> pendingIdCheck(String enterpriseId, String unionid, String openid,
            String wxaUnionid, String wxaOpenid , boolean setCheckFlag) {
        if("ff8080815dacd3a2015dacd3ef5c0000".equals(enterpriseId)) {
            subjectType = 1 ;
        }
        ServiceResponse<WxEnterpriseQwDTO> corpidResp = this.checkAndGetCorpid(enterpriseId,setCheckFlag);
        if (!corpidResp.isSuccess()) {
            return ServiceResponse.failure(corpidResp.getCode(), corpidResp.getMessage());
        }
        String suiteid = config.getWxSuiteid();
        WxEnterpriseQwDTO qwDTO = corpidResp.getResult();
        String corpid = qwDTO.getThirdCorpid();
        ServiceResponse<PendingIdDTO> wxResp = this.qywxExternalUserService.unionidToExternalUserid(corpid, suiteid,
                unionid, openid, subjectType);
        Map<String, String> retMap = new HashMap<>();
        StringBuilder sb = new StringBuilder();
        String url ="https://open.work.weixin.qq.com/devtool/query?e=" ;
        String result = "";
        String wxCode = "0";
        String wxUrl = "" ;
        String wxaCode = "0";
        String wxaUrl ="" ;
        if (wxResp.isSuccess()) {
            result = "ok";
        } else {
            result = wxResp.getCode();
            wxCode = result;
            wxUrl = url+result;
            retMap.put("服务号", wxUrl) ;
        }
        retMap.put("wxCode", wxCode);
        sb.append("服务号-").append(result).append(",");
        ServiceResponse<PendingIdDTO> wxaResp = this.qywxExternalUserService.unionidToExternalUserid(corpid, suiteid,
                wxaUnionid, wxaOpenid, subjectType);
        if (wxaResp.isSuccess()) {
            result = "ok";
        } else {
            result = wxaResp.getCode();
            wxaCode = result;
            wxaUrl = url+result;
            retMap.put("小程序", wxaUrl) ;
        }
        sb.append("小程序-").append(result);
        retMap.put("remark", sb.toString());
        retMap.put("wxaCode", wxaCode);
        return ServiceResponse.success(retMap);
    }
    
    @Override
    public ServiceResponse<Map<String, String>> pendingIdCheck(String enterpriseId, String unionid, String openid,
           String wxaUnionid, String wxaOpenid) {
       return this.pendingIdCheck(enterpriseId, unionid, openid, wxaUnionid, wxaOpenid, true) ;
    }

    @Override
    public ServiceResponse<QwPendingIdDTO> getPendingIdByUnionid(String enterpriseId, String unionid, String openid) {
        ServiceResponse<WxEnterpriseQwDTO> corpidResp = this.checkAndGetCorpid(enterpriseId,true);
        if (!corpidResp.isSuccess()) {
            return ServiceResponse.failure(corpidResp.getCode(), corpidResp.getMessage());
        }
        if("ff8080815dacd3a2015dacd3ef5c0000".equals(enterpriseId)) {
            subjectType = 1 ;
        }
        String suiteid = config.getWxSuiteid();
        WxEnterpriseQwDTO qwDTO = corpidResp.getResult();
        String wxEnterpriseId = qwDTO.getWxEnterpriseId();

        HaoBanErrCode limitCode = QwTimesUtils.isLimit(wxEnterpriseId, enterpriseId, QwInterfaceLimitEnum.GET_PENDING_ID);
        if (null != limitCode) {
            return ServiceResponse.failure(limitCode.getCode(), limitCode.getMsg());
        }
        String corpid = qwDTO.getThirdCorpid();
        ServiceResponse<PendingIdDTO> qwResp = this.qywxExternalUserService.unionidToExternalUserid(corpid, suiteid,
                unionid, openid, subjectType);
        QwTimesUtils.addTimes(wxEnterpriseId, QwInterfaceLimitEnum.GET_PENDING_ID);
        log.info("Unionid获取pendingid,参数={},{},返回={}", unionid, openid, JSON.toJSONString(qwResp));
        if (!qwResp.isSuccess()) {
            return ServiceResponse.failure(qwResp.getCode(), qwResp.getMessage());
        }
        QwPendingIdDTO dto = new QwPendingIdDTO();
        dto.setExternalUserId(qwResp.getResult().getExternal_userid());
        dto.setPendingId(qwResp.getResult().getPending_id());
        return ServiceResponse.success(dto);
    }

    @Override
    public ServiceResponse<QwPendingIdDTO> getPendingIdByExternalid(String enterpriseId, String externalUserId) {
        String suiteid = config.getWxSuiteid();
        ServiceResponse<WxEnterpriseQwDTO> corpidResp = this.checkAndGetCorpid(enterpriseId,true);
        if (!corpidResp.isSuccess()) {
            return ServiceResponse.failure(corpidResp.getCode(), corpidResp.getMessage());
        }
        WxEnterpriseQwDTO qwDTO = corpidResp.getResult();
        String corpid = qwDTO.getThirdCorpid();
        ServiceResponse<List<PendingIdDTO>> qwResp = this.qywxExternalUserService.externalUseridToPendingId(corpid,
                suiteid, Arrays.asList(externalUserId));
        log.info("Externalid获取pendingid,参数={},返回={}", externalUserId, JSON.toJSONString(qwResp));
        if (!qwResp.isSuccess()) {
            return ServiceResponse.failure(qwResp.getCode(), qwResp.getMessage());
        }
        List<PendingIdDTO> list = qwResp.getResult();
        if (CollectionUtils.isNotEmpty(list)) {
            QwPendingIdDTO dto = new QwPendingIdDTO();
            dto.setExternalUserId(list.get(0).getExternal_userid());
            dto.setPendingId(list.get(0).getPending_id());
            return ServiceResponse.success(dto);
        }
        return ServiceResponse.failure("9999", "企微未查询到数据");
    }

//    @Override
//    public ServiceResponse<List<QwPendingIdDTO>> listPendingIdByExternalid(String enterpriseId,
//            List<String> externalUserIdList) {
//        if (CollectionUtils.isEmpty(externalUserIdList) || externalUserIdList.size() > 1000) {
//            return ServiceResponse.failure("9999", "外部联系人不能为空且每次最多1000条");
//        }
//        String suiteid = config.getWxSuiteid();
//        ServiceResponse<WxEnterpriseQwDTO> corpidResp = this.checkAndGetCorpid(enterpriseId,true);
//        if (!corpidResp.isSuccess()) {
//            return ServiceResponse.failure(corpidResp.getCode(), corpidResp.getMessage());
//        }
//        WxEnterpriseQwDTO qwDTO = corpidResp.getResult();
//        String corpid = qwDTO.getThirdCorpid();
//        ServiceResponse<List<PendingIdDTO>> qwResp = this.qywxExternalUserService.externalUseridToPendingId(corpid,
//                suiteid, externalUserIdList);
//        log.info("获取pendingid,参数={},返回={}", externalUserIdList, JSON.toJSONString(qwResp));
//        if (!qwResp.isSuccess()) {
//            return ServiceResponse.failure(qwResp.getCode(), qwResp.getMessage());
//        }
//        List<PendingIdDTO> list = qwResp.getResult();
//        if (CollectionUtils.isNotEmpty(list)) {
//            List<QwPendingIdDTO> retList = new ArrayList<>();
//            for (PendingIdDTO item : list) {
//                QwPendingIdDTO dto = new QwPendingIdDTO();
//                dto.setExternalUserId(item.getExternal_userid());
//                dto.setPendingId(item.getPending_id());
//                retList.add(dto);
//            }
//            return ServiceResponse.success(retList);
//        }
//        return ServiceResponse.failure("9999", "企微未查询到数据");
//    }
    
    // 2010 不需要处理的
    // 判断企业是否能用企微
    private ServiceResponse<WxEnterpriseQwDTO> checkAndGetCorpid(String enterpriseId,boolean setCheckFlag) {
        WxEnterpriseRelationBO enterpriseRelation = this.wxEnterpriseRelatedService.getHeadEnterprise(enterpriseId);
        if (null == enterpriseRelation) {
            // 非总部或不存在
            return ServiceResponse.failure(HaoBanErrCode.ERR_2010.getCode(), "请确认商户是否有效且是总部");
        }
        if(setCheckFlag) {
            EnterpriseSettingDTO setting = this.enterpriseService.getEnterpriseSettingByEnterpriseId(enterpriseId) ;
            String customSetting = setting.getCustomSetting() ;
            if(StringUtils.isNotBlank(customSetting)) {
                JSONObject json = JSON.parseObject(customSetting) ;
                String pendingidFlag = json.getString("qwPendingidFlag") ;
                if(StringUtils.isBlank(pendingidFlag) || "0".equals(pendingidFlag)) {
                    log.info("未配置unionid查询企微外部联系人接口调用");
                    return ServiceResponse.failure(HaoBanErrCode.ERR_2010.getCode(), "未配置unionid查询企微外部联系人接口调用");
                }
            }
        }
        Integer code = this.enterpriseUseForbidService.selectPermissionStatus(enterpriseId,
                EnterpriseServiceEnum.HAO_BAN.getRightMenuCode());
        log.info("好办是否到期停用={},{}", enterpriseId, code);
        if (code != 0 && code != 1) {
            return ServiceResponse.failure(HaoBanErrCode.ERR_2010.getCode(), "好办未启用或已停用");
        }
        int memberOpenCardlag = enterpriseRelation.getMemberOpenCardFlag();
        if (memberOpenCardlag != 0) {
            // 不在同一开放平台
            return ServiceResponse.failure(HaoBanErrCode.ERR_2010.getCode(), "不在同一开放平台");
        }
        String wxEnterpriseId = enterpriseRelation.getWxEnterpriseId();
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
        return ServiceResponse.success(qwDTO);
    }
    
    @Override
    public ServiceResponse<Object> getCallTimes(String wxEnterpriseId) {
        return ServiceResponse.success(QwTimesUtils.getPendingTimes(wxEnterpriseId));
    }

}
