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

import com.alibaba.fastjson.JSON;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.commons.util.DateUtil;
import com.gic.commons.util.EntityUtil;
import com.gic.enterprise.api.constant.EnterpriseServiceEnum;
import com.gic.enterprise.api.dto.EnterpriseUsingPermissionDto;
import com.gic.enterprise.api.service.EnterpriseUseForbidService;
import com.gic.haoban.base.api.common.BasePageInfo;
import com.gic.haoban.common.utils.PageUtil;
import com.gic.haoban.manage.api.dto.*;
import com.gic.haoban.manage.api.enums.SecretTypeEnum;
import com.gic.haoban.manage.api.service.HaobanCommonMQApiService;
import com.gic.haoban.manage.api.service.WxEnterpriseApiService;
import com.gic.haoban.manage.api.service.role.HaobanRoleApiService;
import com.gic.haoban.manage.service.config.Config;
import com.gic.haoban.manage.service.dao.mapper.TabHaobanWelcomeMapper;
import com.gic.haoban.manage.service.dao.mapper.WxEnterpriseMapper;
import com.gic.haoban.manage.service.dao.mapper.WxEnterpriseRelatedMapper;
import com.gic.haoban.manage.service.entity.*;
import com.gic.haoban.manage.service.pojo.bo.StaffPrivacyUseLogBO;
import com.gic.haoban.manage.service.service.*;
import com.gic.wechat.api.service.qywx.QywxUserApiService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
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.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class WxEnterpriseApiServiceImpl implements WxEnterpriseApiService {
    private static final Logger log = LogManager.getLogger(WxEnterpriseApiServiceImpl.class);
    @Autowired
    private WxEnterpriseService wxEnterpriseService;
    @Autowired
    private WxEnterpriseMapper wxEnterpriseMapper;
    @Autowired
    private WxApplicationService wxApplicationService;
    @Autowired
    private SecretSettingService secretSettingService;
    @Autowired
    private MiniprogramSettingService miniprogramSettingService;
    @Autowired
    private TabHaobanWelcomeMapper welcomeMapper;
    @Autowired
    private StaffPrivacyUseLogService staffPrivacyUseLogService;
    @Autowired
    private Config config;
    @Autowired
    private WxEnterpriseRelatedMapper wxEnterpriseRelatedMapper;
    @Autowired
    private QywxUserApiService qywxUserApiService;
    @Autowired
    private EnterpriseUseForbidService enterpriseUseForbidService;
    @Autowired
    private HaobanCommonMQApiService haobanCommonMQApiService ;
    @Autowired
    private HaobanRoleApiService haobanRoleApiService;


    @Override
    public void callbackReviceEnterprise(QywxCorpInfoSimpleDTO dto) {
        log.info("企业微信授权信息：{}", JSON.toJSONString(dto));
        String corpid = dto.getCorpid();
        String corpidIn = dto.getCorpid();
        String corpName = dto.getCorpName();
        String siteId = dto.getSuiteId();
        String agentId = dto.getAgentid();
        String agentName = dto.getAgentName();
        String permanentCode = dto.getPermanentCode();
        String applicationName = dto.getName();
        Integer isCustomizedApp = dto.getIsCustomizedApp();
        String qywxHbzsSuite = config.getQywxHbzsSuite();
        WxEnterpriseDTO wxDTO = EntityUtil.changeEntityByJSON(WxEnterpriseDTO.class, dto);
        String wxEnterpriseId = "";
        TabHaobanWxEnterprise wxEnterprise = this.wxEnterpriseService.getEnterpriseBycorpId(corpid);
        // 调用企微接口
        String serviceCorpid = config.getCorpid();
        String openCorpid = qywxUserApiService.toOpenCorpid(corpid, serviceCorpid);
        log.info("查询企微id,入参={},返回={}", corpid, openCorpid);
        if (StringUtils.isNotBlank(openCorpid) && !openCorpid.equals(corpid)) {
            wxEnterprise = this.wxEnterpriseService.getEnterpriseBycorpId(openCorpid);
            log.info("通过密文corpid查询={},{}", openCorpid, wxEnterprise != null ? wxEnterprise.getWxEnterpriseId() : null);
        }
        // 获取授权好办小程序
        if (wxEnterprise == null) {
            log.info("通过corpid={}未查到记录", corpid);
            // 删除通过名称查询
           // wxEnterprise = this.wxEnterpriseService.getEnterpriseByCorpName(corpName);
        }
        if (wxEnterprise != null) {
            log.info("查询wxEnterpriseId={}", wxEnterprise.getWxEnterpriseId());
            wxEnterpriseId = wxEnterprise.getWxEnterpriseId();
            WxEnterpriseDTO wxEnterpriseDTO = new WxEnterpriseDTO();
            wxEnterpriseDTO.setWxEnterpriseId(wxEnterpriseId);
            wxEnterpriseDTO.setStatusFlag(1);
            wxEnterpriseDTO.setBindFlag(1);
            if (StringUtils.isNotBlank(openCorpid)) {
                this.setCorpid(corpid, openCorpid, wxEnterpriseDTO);
            }
            wxEnterpriseService.update(wxEnterpriseDTO);
        } else {
            if (StringUtils.isNotBlank(openCorpid)) {
                this.setCorpid(corpid, openCorpid, wxDTO);
            }
            wxDTO.setWxSecurityType(2);
            wxEnterpriseId = wxEnterpriseService.add(wxDTO);
            //好办小程序插入权限
            log.info("插入好办小程序权限：{}",wxEnterpriseId);
            haobanRoleApiService.addHaobanRole(wxEnterpriseId);
        }
        TabHaobanWxApplication haobanWxApplication = wxApplicationService.selectBySiteIdAndWxEnterpriseId(siteId, wxEnterpriseId);
        if (haobanWxApplication == null) {
            log.info("新增应用,suiteid={}", siteId);
            haobanWxApplication = new TabHaobanWxApplication();
            haobanWxApplication.setAgentId(agentId);
            haobanWxApplication.setCorpid(corpid);
            haobanWxApplication.setSiteId(siteId);
            haobanWxApplication.setAgentName(agentName);
            haobanWxApplication.setName(applicationName);
            haobanWxApplication.setPermanentCode(permanentCode);
            haobanWxApplication.setIsCustomizedApp(isCustomizedApp);
            if (isCustomizedApp != null && isCustomizedApp == 1) {
                if (qywxHbzsSuite.contains(siteId)) {
                    //好办助手-企业代开发
                    haobanWxApplication.setApplicationType(3);
                } else {
                    //会员小程序代开发
                    haobanWxApplication.setApplicationType(4);
                }
            }
            haobanWxApplication.setWxEnterpriseId(wxEnterpriseId);
            wxApplicationService.insert(haobanWxApplication);
        } else {
            haobanWxApplication.setPermanentCode(permanentCode);
            haobanWxApplication.setCorpid(corpidIn);
            wxApplicationService.update(haobanWxApplication);
        }
        // 企业代开发Secret = permanentCode
        if (isCustomizedApp != null && isCustomizedApp == 1) {
            SecretTypeEnum secretTypeEnum;
            if (qywxHbzsSuite.contains(siteId)) {
                // 好办助手-企业代开发
                secretTypeEnum = SecretTypeEnum.CUSTOMIZED_APP;
            } else {
                // 会员小程序代开发
                secretTypeEnum = SecretTypeEnum.MEMBER_WAPP;
            }
            SecretSettingDTO secretSetting = secretSettingService.getSecretSetting(wxEnterpriseId,
                    secretTypeEnum.getVal());
            if (secretSetting == null) {
                secretSetting = new SecretSettingDTO();
                secretSetting.setWxEnterpriseId(wxEnterpriseId);
                // 兼容代开发会员小程序
                secretSetting.setSecretType(secretTypeEnum.getVal());
                secretSetting.setSecretName(secretTypeEnum.getName());
                secretSetting.setEnterpriseId("-1");
                if (qywxHbzsSuite.contains(siteId)) {
                    // 好办助手-企业代开发
                    secretSetting.setCheckFlag(1);
                } else {
                    // 会员小程序代开发
                    secretSetting.setCheckFlag(0);
                }
            }
            secretSetting.setSecretVal(permanentCode);
            secretSettingService.saveSecretSetting(secretSetting);
        }
        agreeExternalUseridFlag(wxEnterpriseId, 1);
        this.wxEnterpriseService.updateWxSecurityType(wxEnterpriseId);

        log.info("企业微信授权处理完成");
    }

    private void setCorpid(String corpid, String openCorpid, WxEnterpriseDTO wxEnterpriseDTO) {
        if (openCorpid.equals(corpid)) {
            // 密文
            wxEnterpriseDTO.setOpenCorpid(openCorpid);
        } else {
            wxEnterpriseDTO.setOpenCorpid(openCorpid);
            wxEnterpriseDTO.setWxCorpid(corpid);
        }
    }

    @Override
    public com.gic.api.base.commons.Page<YwWxEnterpriseDTO> list(BasePageInfo pageInfo, String keyword,
                                                                 List<String> enterpriseIds, Integer gicContactFlag, String version, List<String> enterpriseIdsNotIn,
                                                                 String loginUserId) {
        PageHelper.startPage(pageInfo.getPageNum(), pageInfo.getPageSize());
        Page<TabHaobanWxEnterprise> page = wxEnterpriseMapper.list(keyword, enterpriseIds, gicContactFlag, version,
                enterpriseIdsNotIn);
        // 数据转换+白名单过滤
        if (Objects.isNull(page) || CollectionUtils.isEmpty(page.getResult())) {
            com.gic.api.base.commons.Page<Object> objectPage = new com.gic.api.base.commons.Page<>();
            objectPage.setPageSize(pageInfo.getPageSize());
            objectPage.setCurrentPage(pageInfo.getPageNum());
            objectPage.setResult(Collections.emptyList());
            return new com.gic.api.base.commons.Page<>();
        }
        com.gic.api.base.commons.Page<YwWxEnterpriseDTO> resPage = PageUtil.changePageHelperToCurrentPage(page,
                YwWxEnterpriseDTO.class);
        boolean matchOperId = matchOperId(loginUserId);
        resPage.getResult().forEach(one -> {
            if (matchOperId) {
                one.setOpenMassFlag(Boolean.TRUE);
            } else {
                one.setOpenMassFlag(Boolean.FALSE);
            }
        });
        return resPage;
    }

    private boolean matchOperId(String loginUserId) {
        if (StringUtils.isEmpty(loginUserId)) {
            return false;
        }
        // 匹配运营id白名单
        String whiteList = config.getHistoryMbrMassOperWhiteList();
        if (StringUtils.isEmpty(whiteList)) {
            return false;
        }
        String[] idArr = whiteList.split(",");
        Set<String> idSet = new HashSet<>(Arrays.asList(idArr));
        return idSet.contains(loginUserId);
    }

    @Override
    public List<YwWxEnterpriseDTO> listAll() {
        List<TabHaobanWxEnterprise> list = wxEnterpriseMapper.listAll();
        return EntityUtil.changeEntityListByJSON(YwWxEnterpriseDTO.class, list);
    }

    @Override
    public List<YwWxEnterpriseDTO> listByIds(Set<String> enterpriseIds) {
        List<TabHaobanWxEnterprise> list = wxEnterpriseMapper.listByIds(enterpriseIds);
        return EntityUtil.changeEntityListByJSON(YwWxEnterpriseDTO.class, list);
    }

    @Override
    public WxEnterpriseDTO getOne(String wxEnterpriseId) {
        TabHaobanWxEnterprise tab = wxEnterpriseMapper.selectByPrimaryKey(wxEnterpriseId);
        WxEnterpriseDTO wxDTO = EntityUtil.changeEntityByJSON(WxEnterpriseDTO.class, tab);
        return wxDTO;
    }
    
    @Override
    public WxEnterpriseDTO selectByWxaAppid(String appid) {
        TabHaobanWxEnterprise tab = wxEnterpriseMapper.selectByWxaAppid(appid);
        WxEnterpriseDTO wxDTO = EntityUtil.changeEntityByJSON(WxEnterpriseDTO.class, tab);
        return wxDTO;
    }

    @Override
    public WxEnterpriseQwDTO getQwInfo(String wxEnterpriseId) {
        return this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
    }

    @Override
    public WxEnterpriseDTO getEnterpriseBycorpId(String corpId) {
        TabHaobanWxEnterprise enterprise = this.wxEnterpriseService.getEnterpriseBycorpId(corpId);
        return EntityUtil.changeEntityByJSON(WxEnterpriseDTO.class, enterprise);
    }

    @Override
    public ServiceResponse<Boolean> isStopHaoban(String corpId) {
        TabHaobanWxEnterprise entity = this.wxEnterpriseService.getEnterpriseBycorpId(corpId);
        if (null == entity) {
            log.info("企微查询不到corpid={}",corpId);
            return ServiceResponse.failure("9999", "企微企业信息不存在");
        }
        String wxEnterpriseId = entity.getWxEnterpriseId();
        List<TabHaobanWxEnterpriseRelated> list = this.wxEnterpriseRelatedMapper.listByWxenterpriseId(wxEnterpriseId);
        if (CollectionUtils.isEmpty(list)) {
            log.info("企微无关联gic商户,wxEnterpriseId={}",wxEnterpriseId);
            //return ServiceResponse.failure("1000", "无关联商户");
            return ServiceResponse.success() ;
        }
        int count = list.size();
        log.info("企微关联数={}，{}", count, JSON.toJSONString(list));
        String msg = "好办服务已到期";
        if (count == 1) {
            msg = this.getEndDate(list.get(0).getEnterpriseId()) ;
            if(null != msg) {
                return ServiceResponse.failure("2000", msg);
            }
        } else {
            boolean flag = false ;
            for(TabHaobanWxEnterpriseRelated item : list) {
                boolean isStop = this.haobanIsStop(item.getEnterpriseId()) ;
                if(!isStop) {
                    flag = true ;
                }
            }
            if(!flag) {
                return ServiceResponse.failure("3000", msg);
            }
        }
        return ServiceResponse.success() ;
    }

    @Override
    public void update(WxEnterpriseDTO enterpriseDTO) {
        wxEnterpriseService.update(enterpriseDTO);
    }
    
    @Override
    public SecretSettingDTO getSecretSetting(String wxEnterpriseId, int secretType, String enterpriseId) {
        if (secretType == SecretTypeEnum.MEMBER_WAPP.getVal()) {
            return secretSettingService.getMemberSecretSetting(wxEnterpriseId, enterpriseId);
        } else {
            return secretSettingService.getSecretSetting(wxEnterpriseId, secretType);
        }
    }

    @Override
    public boolean saveSecretSetting(SecretSettingDTO secretSettingDTO) {
        return secretSettingService.saveSecretSetting(secretSettingDTO);
    }

    @Override
    public List<SecretSettingDTO> listSecret(String wxEnterpriseId) {
        return secretSettingService.listSecretSetting(wxEnterpriseId);
    }

    @Override
    public boolean delSecretSetting(String secretId) {
        return secretSettingService.delSecretSetting(secretId);
    }

    @Override
    public boolean saveMiniprogramSetting(MiniprogramSettingDTO miniprogramSettingDTO) {
        miniprogramSettingService
                .saveMiniprogramSetting(EntityUtil.changeEntityNew(TabMiniprogramSetting.class, miniprogramSettingDTO));
        return true;
    }

    @Override
    public List<MiniprogramSettingDTO> listMiniprogramSetting(String wxEnterpriseId) {
        List<TabMiniprogramSetting> ret = miniprogramSettingService.listMiniprogram(wxEnterpriseId);
        return EntityUtil.changeEntityListNew(MiniprogramSettingDTO.class, ret);
    }

    @Override
    public MiniprogramSettingDTO getMiniprogramSettingByEid(String wxEnterpriseId, String enterpriseId) {
        TabMiniprogramSetting miniprogramSetting = miniprogramSettingService.getMiniprogramSetting(wxEnterpriseId,
                enterpriseId);
        return EntityUtil.changeEntityNew(MiniprogramSettingDTO.class, miniprogramSetting);
    }

    @Override
    public MiniprogramSettingDTO getMiniprogramSettingByAppId(String wxEnterpriseId, String appId) {
        TabMiniprogramSetting miniprogramSetting = miniprogramSettingService
                .getMiniprogramSettingByAppId(wxEnterpriseId, appId);
        return EntityUtil.changeEntityNew(MiniprogramSettingDTO.class, miniprogramSetting);
    }

    @Override
    public boolean delMiniprogramSettingByEid(String id) {
        miniprogramSettingService.delMiniprogramSetting(id);
        return true;
    }

//    @Override
//    public WelcomeDTO getWelcome(String wxEnterpriseId) {
//        TabWelcome tabWelcome = welcomeMapper.selectByWxEnterpriseId(wxEnterpriseId);
//        return EntityUtil.changeEntityByJSON(WelcomeDTO.class, tabWelcome);
//    }

    @Override
    public boolean setWelcome(String wxEnterpriseId, Integer openFlag) {
        TabWelcome tabWelcome = welcomeMapper.selectByWxEnterpriseId(wxEnterpriseId);
        if (tabWelcome == null) {
            return true;
        }
        tabWelcome.setOpenFlag(openFlag);
        tabWelcome.setUpdateTime(new Date());
        welcomeMapper.updateByPrimaryKeySelective(tabWelcome);
        return true;
    }

    @Override
    public boolean delWelcome(String wxEnterpriseId) {
        TabWelcome tabWelcome = welcomeMapper.selectByWxEnterpriseId(wxEnterpriseId);
        if (tabWelcome == null) {
            return true;
        }
        tabWelcome.setStatusFlag(0);
        tabWelcome.setUpdateTime(new Date());
        welcomeMapper.updateByPrimaryKeySelective(tabWelcome);
        return true;
    }

    @Override
    public void agreeExternalUseridCallBack(String corpId, String serviceCorpId) {
        TabHaobanWxEnterprise tabHaobanWxEnterprise = wxEnterpriseService.getEnterpriseBycorpId(corpId);
        if (tabHaobanWxEnterprise == null) {
            return;
        }
        WxEnterpriseDTO wxEnterpriseDTO = new WxEnterpriseDTO();
        wxEnterpriseDTO.setWxEnterpriseId(tabHaobanWxEnterprise.getWxEnterpriseId());
        wxEnterpriseDTO.setAgreeExternalUseridFlag(1);
        wxEnterpriseDTO.setAgreeExternalUseridTime(new Date());
        wxEnterpriseDTO.setUpdateTime(new Date());
        wxEnterpriseService.update(wxEnterpriseDTO);
    }

    @Override
    public void agreeExternalUseridFlag(String wxEnterpriseId, Integer openFlag) {
        log.info("是否同意授权转换external_userid，运维操作：wxEnterpriseId:{}", wxEnterpriseId);
        WxEnterpriseDTO wxEnterpriseDTOOld = wxEnterpriseService.selectById(wxEnterpriseId);
        if (wxEnterpriseDTOOld == null) {
            return;
        }
        WxEnterpriseDTO wxEnterpriseDTO = new WxEnterpriseDTO();
        wxEnterpriseDTO.setWxEnterpriseId(wxEnterpriseId);
        wxEnterpriseDTO.setAgreeExternalUseridFlag(openFlag);
        wxEnterpriseDTO.setAgreeExternalUseridTime(new Date());
        wxEnterpriseDTO.setExternalFlag(openFlag);
        wxEnterpriseDTO.setUseridFlag(openFlag);
        wxEnterpriseDTO.setUpdateTime(new Date());
        wxEnterpriseService.update(wxEnterpriseDTO);
    }

    @Override
    public void wellDoneLoginAddPrivacy(StaffPrivacyUseLogDTO staffPrivacyUseLogDTO) {
        // 插入隐私协议
        StaffPrivacyUseLogBO staffPrivacyUseLogBO = new StaffPrivacyUseLogBO();
        BeanUtils.copyProperties(staffPrivacyUseLogDTO, staffPrivacyUseLogBO);
        String staffId = staffPrivacyUseLogDTO.getStaffId();
        if (StringUtils.isBlank(staffId) || "-1".equals(staffId)) {
            String wxOpenUseId = staffPrivacyUseLogDTO.getWxOpenUseId();
            StaffPrivacyUseLogBO privacyUseLogBO = staffPrivacyUseLogService.getByUserId(wxOpenUseId);
            if (privacyUseLogBO != null) {
                log.info("用户已经同意过隐私协议,wxOpenUseId:{}", wxOpenUseId);
                return;
            }
            staffPrivacyUseLogService.insert(staffPrivacyUseLogBO);
        } else {
            StaffPrivacyUseLogBO privacyUseLog = staffPrivacyUseLogService.getByStaffId(staffId);
            if (privacyUseLog != null) {
                log.info("用户已经同意过隐私协议,staffId:{}", staffId);
                return;
            }
            staffPrivacyUseLogService.insert(staffPrivacyUseLogBO);
        }
    }

    @Override
    public void updateWxSecurityType(String wxEnterpriseId) {
        this.wxEnterpriseService.updateWxSecurityType(wxEnterpriseId);
    }

    @Override
    public int calcSecretType(String wxEnterpriseId) {
        return this.wxEnterpriseService.calcSecretType(wxEnterpriseId);
    }

    @Override
    public SecretSettingDTO getSecretSettingById(String secretId) {
        return secretSettingService.getSecretSettingById(secretId);
    }

    @Override
    public void stopHaoban(String enterpriseId) {
        log.info("停用好办eid={}",enterpriseId);
        this.wxEnterpriseService.stopHaoban(enterpriseId);
        CommonMQDTO dto = new CommonMQDTO();
        dto.setType(1);
        Map<String,String> map = new HashMap<>() ;
        map.put("enterpriseId", enterpriseId) ;
        dto.setParams(map);
        this.haobanCommonMQApiService.putCommonMessage(dto);
    }
    
    @Override
    public boolean haobanIsStop(String eid) {
        Integer code =  this.enterpriseUseForbidService.selectPermissionStatus(eid,EnterpriseServiceEnum.HAO_BAN.getRightMenuCode()) ;
        log.info("好办是否到期停用={},{}",eid,code);
        if(code ==0 || code==1) {
            ServiceResponse<EnterpriseUsingPermissionDto> resp = this.enterpriseUseForbidService.getPermisssionByCode(eid, EnterpriseServiceEnum.HAO_BAN.getRightMenuCode()) ;
            log.info("返回权限信息={}",JSON.toJSONString(resp));
            if(resp.isSuccess()) {
                EnterpriseUsingPermissionDto dto = resp.getResult() ;
                if(null != dto.getServiceEndDate() && dto.getServiceEndDate().before(new Date())) {
                    log.info("过期停用={}",eid);
                    return true ;
                }
            }
            return false ;
        }
        return true ;
    }
    
    @Override
    public String getEndDate(String enterpriseId) {
        if(!haobanIsStop(enterpriseId)) {
            return null ;
        }
        ServiceResponse<EnterpriseUsingPermissionDto> resp =  this.enterpriseUseForbidService.getPermisssionByCode(enterpriseId, EnterpriseServiceEnum.HAO_BAN.getRightMenuCode()) ;
        log.info("返回权限信息={}",JSON.toJSONString(resp));
        if(resp.isSuccess()) {
            EnterpriseUsingPermissionDto dto = resp.getResult() ;
            if(null != dto.getServiceEndDate() && ( dto.getServiceEndDate().before(new Date()) ||  (dto.getStatus()!=0 && dto.getStatus()!=1)) ) {
                return  "好办服务已于"+DateUtil.dateToStr(dto.getServiceEndDate(), "yyyy-MM-dd")+"到期" ;
            }
        }
        return "好办服务已到期" ;
    }
}
