package com.yeejoin.amos.boot.module.jczs.flc.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yeejoin.amos.boot.biz.common.constants.CommonConstant;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.biz.common.utils.QRCodeUtil;
import com.yeejoin.amos.boot.biz.common.utils.TreeParser;
import com.yeejoin.amos.boot.biz.common.workflow.feign.WorkflowFeignService;
import com.yeejoin.amos.boot.module.common.api.entity.OrgUsr;
import com.yeejoin.amos.boot.module.common.biz.service.impl.OrgUsrServiceImpl;
import com.yeejoin.amos.boot.module.jczs.api.common.BizCommonConstant;
import com.yeejoin.amos.boot.module.jczs.api.dto.BaseUnitLicenceDto;
import com.yeejoin.amos.boot.module.jczs.api.entity.BaseUnitLicence;
import com.yeejoin.amos.boot.module.jczs.api.entity.TzBaseEnterpriseInfo;
import com.yeejoin.amos.boot.module.jczs.api.enums.CompanyLevelEnum;
import com.yeejoin.amos.boot.module.jczs.api.mapper.TzBaseEnterpriseInfoMapper;
import com.yeejoin.amos.boot.module.jczs.biz.service.impl.*;
import com.yeejoin.amos.boot.module.jczs.biz.utils.RedisUtil;
import com.yeejoin.amos.boot.module.jczs.flc.api.dto.RegUnitIcDto;
import com.yeejoin.amos.boot.module.jczs.flc.api.dto.RegUnitInfoDto;
import com.yeejoin.amos.boot.module.jczs.flc.api.entity.RegUnitIc;
import com.yeejoin.amos.boot.module.jczs.flc.api.entity.RegUnitInfo;
import com.yeejoin.amos.boot.module.jczs.flc.api.feign.AccessFeignService;
import com.yeejoin.amos.boot.module.jczs.flc.api.feign.IdxFeignService;
import com.yeejoin.amos.boot.module.jczs.flc.api.feign.UgpServiceFeignClient;
import com.yeejoin.amos.boot.module.jczs.flc.api.mapper.RegUnitInfoMapper;
import com.yeejoin.amos.boot.module.jczs.flc.api.service.IRegUnitInfoService;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import com.yeejoin.amos.feign.privilege.model.RoleModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
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.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 单位注册信息表服务实现类
 *
 * @author system_generator
 * @date 2022-08-09
 */
@Service
public class RegUnitInfoServiceImpl extends BaseService<RegUnitInfoDto, RegUnitInfo, RegUnitInfoMapper>
		implements IRegUnitInfoService {

	@Autowired
	RedisUtil redisUtil;

	@Autowired
	BaseUnitLicenceServiceImpl baseUnitLicenceService;

	@Autowired
	DataDictionaryServiceImpl iDataDictionaryService;

	@Autowired
	OrgUsrServiceImpl iOrgUsrService;

	@Autowired
	RegUnitIcServiceImpl regUnitIcService;

	@Autowired
	private TzsAuthServiceImpl tzsAuthServiceImpl;

	@Autowired
	TzBaseEnterpriseInfoServiceImpl tzBaseEnterpriseInfoService;
	@Autowired
	TzBaseEnterpriseInfoMapper tzBaseEnterpriseInfoMapper;

	@Autowired
	RestTemplate restTemplate;

	@Autowired
	AccessFeignService accessFeignService;

	@Autowired
	UgpServiceFeignClient ugpServiceFeignClient;

	@Autowired
	RegUnitInfoMapper regUnitInfoMapper;
    
    @Autowired
    StartPlatformTokenService startPlatformTokenService;

    @Autowired
	EquipmentCategoryServiceImpl equipmentCategoryService;

	@Autowired
	IdxFeignService idxFeignService;

	@Autowired
	WorkflowFeignService workflowFeignService;

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

	/**
	 * 使用单位的类型，数据来源：cb_data_dictionary code = 1232
	 */
	private static String USE_UNIT_TYPE_CODE = "1232";
	/**
	 * 生产单位的类型，数据来源：cb_data_dictionary code = 1230
	 */
	private static String PRODUCT_UNIT_TYPE_CODE = "1230";
	/**
	 * 充装单位的类型，数据来源：cb_data_dictionary code = 1231
	 */
	private static String FILLING_UNIT_TYPE_CODE = "1231";

	/**
	 * 单位类型，数据来源：cb_data_dictionary type = UNIT_TYPE
	 */
	private static String DICT_TYPE_UNIT_TYPE = "UNIT_TYPE_NEW";

	@Value("${org.filter.group.seq}")
	private Long groupSeq;

	@Value("${is.ugp}")
	private boolean isUgp;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public RegUnitInfoDto registerUnit(RegUnitInfoDto model) {
		if(ValidationUtil.isEmpty(model.getUnitCode())){
			model.setUnitCode(model.getForm().getString("unitCode"));
		}
		RegUnitInfo regUnitInfo = new RegUnitInfo();
		try {
			tzsAuthServiceImpl.setRequestContext();
			// 注册用统一信用码注册，默认证件类型为营业执照，数据来源：cb_data_dictionary code = 1060
			model.setUnitCodeType("1060");
			model.setUnitCodeTypeName("营业执照");
			Bean.copyExistPropertis(model, regUnitInfo);
			regUnitInfo.setUnitType(StringUtils.join(model.getUnitTypeList(), ","));
			regUnitInfo.setUnitTypeCode(StringUtils.join(model.getUnitTypeCodeList(), ","));

			// 3.2 自动创建：调用平台进行创建单位、用户信息
			this.createCompanyAndUser(regUnitInfo);
			//多线程同步ugp信息(tzs和ugp一起后放开)

			FutureTask<ResponseModel<Boolean>> future = null;
			if(isUgp) {
				String token = RequestContext.getToken();
				String appKey = RequestContext.getAppKey();
				String product = RequestContext.getProduct();
				Callable callable = new Callable() {
					@Override
					public Object call() throws Exception {
						RequestContext.setToken(token);
						RequestContext.setAppKey(appKey);
						RequestContext.setProduct(product);
						//同步企业至ugp，成功返回true，失败返回false
						return ugpServiceFeignClient.syncCompany(model);
					}
				};
				future = new FutureTask(callable);
				Thread thread = new Thread(future);
				thread.start();
			}


			// 1.插入单位注册许可信息表：tz_base_unit_licence
			List<BaseUnitLicenceDto> unitLicenceDtos = model.getUnitLicences();
			List<BaseUnitLicence> baseUnitLicences = unitLicenceDtos.stream().map(s -> {
				s.setUnitCode(model.getUnitCode());
				s.setUnitName(model.getName());
				BaseUnitLicence target = new BaseUnitLicence();
				Bean.copyExistPropertis(s, target);
				return target;
			}).collect(Collectors.toList());
			if (!baseUnitLicences.isEmpty()) {
				baseUnitLicenceService.saveOrUpdateBatch(baseUnitLicences);
			}
			// 2.插入工商单位信息表：tz_flc_reg_unit_ic
			RegUnitIc regUnitIc = new RegUnitIc();
			model.getRegUnitIc().setUnitCode(model.getUnitCode());
			model.getRegUnitIc().setUnitName(model.getName());
			Bean.copyExistPropertis(model.getRegUnitIc(), regUnitIc);
			regUnitIcService.saveOrUpdate(regUnitIc);
			// 3.调用平台进行创建单位、用户信息,同步用户信息
//            if (UnitReviewStateEnum.NO_NEED_REVIEW.getCode().equals(model.getState())) {
			// 3.1 创建企业信息
			this.createBaseEnterpriseInfo(model);


//            }
			if (!ObjectUtils.isEmpty(regUnitInfo.getAdminName())){
				regUnitInfo.setContactPerson(regUnitInfo.getAdminName());
			}
			if (!ObjectUtils.isEmpty(regUnitInfo.getAdminTel())){
				regUnitInfo.setContactPersonTel(regUnitInfo.getAdminTel());
			}
			// 4.插入注册单位基本信息表：tz_flc_reg_unit_info
			this.save(regUnitInfo);
			// 5.组织返回数据
			// 5.1企业基本信息
			Bean.copyExistPropertis(regUnitInfo, model);
			// 5.2行政许可数据
			model.setUnitLicences(Bean.toModels(baseUnitLicences, BaseUnitLicenceDto.class));
			// 5.3工商信息
			model.setRegUnitIc(Bean.toModel(regUnitIc, new RegUnitIcDto()));

			//获取多线程执行结果 true成功 false失败（tzs和ugp一起后放开）
			if(isUgp) {
				if (!future.get().getResult()) {
					throw new Exception("UGP信息同步失败");
				}
			}

		} catch (Exception e) {
			log.error(e.getMessage(), e);
			// 失败后回滚：删除已经创建的企业信息
			if (StringUtils.isNotEmpty(regUnitInfo.getAmosCompanySeq())) {
				FeignClientResult<CompanyModel> feignClientResult = Privilege.companyClient
						.seleteOne(Long.parseLong(regUnitInfo.getAmosCompanySeq()));
				if (feignClientResult != null) {
					Privilege.companyClient.deleteCompany(regUnitInfo.getAmosCompanySeq());
				}
			}
			// 失败后回滚：删除已经创建的管理员账号
			if (StringUtils.isNotEmpty(regUnitInfo.getAdminUserId())) {
				FeignClientResult<AgencyUserModel> feignClientResult = Privilege.agencyUserClient
						.queryByUserId(regUnitInfo.getAdminUserId());
				if (feignClientResult != null) {
					Privilege.agencyUserClient.multDeleteUser(regUnitInfo.getAdminUserId());
				}
			}
			throw new RuntimeException(e.getMessage());
		}
		return model;
	}

	private static String createQRCode(String unitCode) {
		String urlString = null;
		byte[] bytes = QRCodeUtil.generateQRCodeImageByteData(unitCode, 150);
		InputStream inputStream = new ByteArrayInputStream(bytes);
		try {
			MultipartFile file = new MockMultipartFile(unitCode+".png",unitCode+".png", ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);
			FeignClientResult<Map<String, String>> date = Systemctl.fileStorageClient.updateCommonFileFree(file, "tzs/qrcode");
			if (date != null) {
				Map<String, String> map = date.getResult();
				Iterator<String> it = map.keySet().iterator();
				urlString=it.next();
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new BadRequest(unitCode + ":生成二维码失败");
		}
		return urlString;
	}

	public void createBaseEnterpriseInfo(RegUnitInfoDto regUnitInfo) {
		// 1.查询管辖公司的信息
		FeignClientResult<CompanyModel> feignClientResult = Privilege.companyClient
				.seleteOne(Long.parseLong(regUnitInfo.getManagementUnitId()));
		CompanyModel managementCompany = feignClientResult.getResult();
		// 2.填充数据
		TzBaseEnterpriseInfo baseEnterpriseInfo = new TzBaseEnterpriseInfo();
		baseEnterpriseInfo.setUseUnitCertificate(regUnitInfo.getUnitCodeTypeName());
		baseEnterpriseInfo.setUnitType(StringUtils.join(regUnitInfo.getUnitTypeList(), "#"));
		baseEnterpriseInfo.setUseCode(regUnitInfo.getUnitCode());
		TzBaseEnterpriseInfo useCodeResult = tzBaseEnterpriseInfoMapper.selectOne(new QueryWrapper<TzBaseEnterpriseInfo>().eq("use_code", regUnitInfo.getUnitCode()));
		if (ObjectUtils.isEmpty(useCodeResult)) {
			baseEnterpriseInfo.setQrCode(createQRCode(regUnitInfo.getUnitCode()));
		} else {
			baseEnterpriseInfo.setQrCode(ObjectUtils.isEmpty(useCodeResult.getQrCode()) ? createQRCode(regUnitInfo.getUnitCode()) : useCodeResult.getQrCode());
		}
		baseEnterpriseInfo.setUseUnit(regUnitInfo.getName());
		baseEnterpriseInfo.setProvince(regUnitInfo.getProvince());
		baseEnterpriseInfo.setCity(regUnitInfo.getCity());
		baseEnterpriseInfo.setDistrict(regUnitInfo.getDistrict());
		baseEnterpriseInfo.setStreet(regUnitInfo.getStree());
		baseEnterpriseInfo.setCommunity(regUnitInfo.getCommunity());
		baseEnterpriseInfo.setAddress(regUnitInfo.getAddress());
		baseEnterpriseInfo.setLegalPerson(regUnitInfo.getLegalPerson());
		baseEnterpriseInfo.setLegalPhone(regUnitInfo.getLegalPersonTel());
		baseEnterpriseInfo.setUseContact(regUnitInfo.getAdminName());
		baseEnterpriseInfo.setContactPhone(regUnitInfo.getAdminTel());
		baseEnterpriseInfo.setLongitude(regUnitInfo.getLongitude());
		baseEnterpriseInfo.setLatitude(regUnitInfo.getLatitude());
		// 管辖机构信息
		baseEnterpriseInfo.setSuperviseCode(managementCompany.getCompanyCode());
		baseEnterpriseInfo.setSuperviseOrgCode(managementCompany.getOrgCode());
		// 这个表有两个字段所以赋值两字段
		baseEnterpriseInfo.setSuperviseOrgName(regUnitInfo.getManagementUnit());
		baseEnterpriseInfo.setGoverningBody(regUnitInfo.getManagementUnit());
		baseEnterpriseInfo.setDataSources("企业注册");
		baseEnterpriseInfo.setIndustry(regUnitInfo.getRegUnitIc().getIndustryName());
		baseEnterpriseInfo.setRegistrationAuthority(regUnitInfo.getRegUnitIc().getRegisteredOrgan());
		baseEnterpriseInfo.setApprovalTime(regUnitInfo.getRegUnitIc().getApprovedDate());
		baseEnterpriseInfo.setOperatingStatus(regUnitInfo.getRegUnitIc().getBusinessState());
		baseEnterpriseInfo.setSyncDate(new Date());
		baseEnterpriseInfo.setSyncState(0);
		LambdaQueryWrapper<TzBaseEnterpriseInfo> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(TzBaseEnterpriseInfo::getUseCode,regUnitInfo.getUnitCode());
		tzBaseEnterpriseInfoService.saveOrUpdate(baseEnterpriseInfo,wrapper);
	}

	@Override
	public RegUnitInfoDto unitCheck(String unitCode, String unitType,String companyName) {
		tzsAuthServiceImpl.setRequestContext();
		RequestContext.setToken(RequestContext.getToken());
		RequestContext.setAppKey(RequestContext.getAppKey());
		RequestContext.setProduct(RequestContext.getProduct());
        if (!ValidationUtil.isEmpty(companyName)) {
      	  FeignClientResult<CompanyModel> result =Privilege.companyClient.queryByCompanyName(companyName);
      	  if(result.getResult()!=null) 
      	  {
      		  throw new RuntimeException("重复的公司名称");
      	  }
        }
        
        if (!ValidationUtil.isEmpty(unitCode)) {
        	  FeignClientResult<CompanyModel> result =Privilege.companyClient.queryByCompanyCode(unitCode);
        	  if(result.getResult()!=null) 
        	  {
        		  throw new RuntimeException("重复的公司编码");
        	  }
          }
		// 1.校验重复性
//		RegUnitInfo regUnitInfo = this
//				.getOne(new LambdaQueryWrapper<RegUnitInfo>().eq(RegUnitInfo::getUnitCode, unitCode));
//		if (regUnitInfo != null) {
//			throw new RuntimeException("该单位已注册，请联系企业管理员！");
//		}
		// 2.组织返回数据
		RegUnitInfoDto regUnitInfoDto = new RegUnitInfoDto();
//            MultiValueMap<String, String> headers = new HttpHeaders();
//            headers.add("product","AMOS_STUDIO_WEB");
//            headers.add("appKey","AMOS_STUDIO");
//			headers.add("token",token);
//				RequestContext.setToken();
//				RequestContext.setAppKey();
//				RequestContext.setProduct();
//            RequestEntity requestEntity = new RequestEntity(
//                    null, //body部分数据
//                    headers, //头
//                    HttpMethod.GET,//请求方法
//                    URI.create("/accessapi/business/getData"));
//            ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(requestEntity,JSONObject.class);
//            JSONObject result = responseEntity.getBody();
		// 2.1 使用单位调用行政许可系统接口进行查询工商信息
		Map<String, Object> resultMap = accessFeignService.getData(unitCode).getResult();
		if(!ValidationUtil.isEmpty(resultMap)){
			// 2.2 工商信息组装
			String area = String.valueOf(resultMap.get("area"));
			String city = area.substring(0,area.indexOf("市")+1);
			String district = area.substring(city.length());
			if(district.equals("高新区")){
				district = "雁塔区";
			}
			regUnitInfoDto.setCity(city);
			regUnitInfoDto.setDistrict(district);
			regUnitInfoDto.setStree(String.valueOf(resultMap.get("street")));
			regUnitInfoDto.setCommunity(String.valueOf(resultMap.get("community")));
			regUnitInfoDto.setAddress(String.valueOf(resultMap.get("address")));
			regUnitInfoDto.setUnitCode(String.valueOf(resultMap.get("creditCode")));
			regUnitInfoDto.setName(String.valueOf(resultMap.get("unitName")));
			regUnitInfoDto.setLegalPerson(String.valueOf(resultMap.get("legalPeople")));
			String industryName = "";
			DataDictionary dataDictionary = iDataDictionaryService.getByCode(String.valueOf(resultMap.get("industryCode")),"HYXLDM");
			if(!ValidationUtil.isEmpty(dataDictionary)) {
				industryName = dataDictionary.getName();
			}
			String approveDate = String.valueOf(resultMap.get("approval_time"));
			approveDate = approveDate.contains("年")?approveDate.replace("年","-"):approveDate;
			approveDate = approveDate.contains("月")?approveDate.replace("月","-"):approveDate;
			approveDate = approveDate.contains("日")?approveDate.replace("日","-"):approveDate;
			RegUnitIcDto regUnitIcDto = new RegUnitIcDto();
			regUnitIcDto.setUnitCode(regUnitInfoDto.getUnitCode());
			try {
				regUnitIcDto.setApprovedDate(DateUtils.dateParse(approveDate,"yyyy-MM-dd"));
			} catch (ParseException e) {
				e.printStackTrace();
			}
			regUnitIcDto.setUnitName(regUnitInfoDto.getName());
			regUnitIcDto.setRegisteredOrgan(String.valueOf(resultMap.get("registration_authority")));
			regUnitIcDto.setBusinessState(String.valueOf(resultMap.get("operating_status")));
			regUnitIcDto.setProvince("陕西省");
			regUnitIcDto.setCity(regUnitInfoDto.getCity());
			regUnitIcDto.setDistrict(regUnitInfoDto.getDistrict());
			regUnitIcDto.setStree(regUnitInfoDto.getStree());
			regUnitIcDto.setCommunity(regUnitInfoDto.getCommunity());
			regUnitIcDto.setAddress(regUnitInfoDto.getAddress());
			regUnitIcDto.setLegalPerson(regUnitInfoDto.getLegalPerson());
			regUnitIcDto.setIndustryName(industryName);
			regUnitInfoDto.setRegUnitIc(regUnitIcDto);
		} else {
			regUnitInfoDto.setRegUnitIc(new RegUnitIcDto());
		}

		// 2.3 许可信息组装
		List<BaseUnitLicence> unitLicences = baseUnitLicenceService
				.list(new LambdaQueryWrapper<BaseUnitLicence>().eq(BaseUnitLicence::getUnitCode, unitCode));
		regUnitInfoDto.setUnitLicences(Bean.toModels(unitLicences, BaseUnitLicenceDto.class));
		return regUnitInfoDto;
	}

	@Override
	public List<DataDictionary> getUnitTypeList() {
		return iDataDictionaryService.getByType(DICT_TYPE_UNIT_TYPE);
	}

	@Override
	public Collection getManagementUnitTree(String orgCode) {
		List<LinkedHashMap> companyModels = (List<LinkedHashMap>) redisUtil.get(BizCommonConstant.COMPANY_TREE_REDIS_KEY);
		if (ValidationUtil.isEmpty(companyModels)) {
			tzsAuthServiceImpl.setRequestContext();
			companyModels = equipmentCategoryService.creatTree();
		}
		if (!ValidationUtil.isEmpty(orgCode)) {
            companyModels = findNodesByCondition(companyModels, "orgCode", orgCode, "children");
			companyModels = (List<LinkedHashMap>) companyModels.get(0).get("children");
		}
		return companyModels;
	}


//	public Collection getManagementUnitTree2(String orgCode) {
//		tzsAuthServiceImpl.setRequestContext();
//		// 组织架构中单位级别为：省级、地市级、区县级、的单位
//		List<CompanyModel> companyModels = new ArrayList<CompanyModel>();
//		if (StringUtils.isEmpty(orgCode)) {
//			if (redisUtil.hasKey(BizCommonConstant.COMPANY_TREE_REDIS_KEY)) {
//				companyModels = (List<CompanyModel>) redisUtil.get(BizCommonConstant.COMPANY_TREE_REDIS_KEY);
//			} else {
//				companyModels = (List<CompanyModel>) Privilege.companyClient.queryAgencyTree(null).getResult();
//				redisUtil.set(BizCommonConstant.COMPANY_TREE_REDIS_KEY, companyModels);
//			}
//		} else {
//			LinkedHashMap<Object, Object> l = (LinkedHashMap<Object, Object>) Privilege.companyClient
//					.queryByOrgcode(orgCode).getResult();
//			for (Map.Entry<Object, Object> it : l.entrySet()) {
//				CompanyModel companyModel = JSONObject.parseObject(JSONObject.toJSONString(it.getValue()),
//						CompanyModel.class);
//				if (companyModel != null) {
//					companyModels = (List<CompanyModel>) Privilege.companyClient
//							.querySubAgencyTree(companyModel.getSequenceNbr()).getResult();
//				}
//				break;
//			}
//		}
//		List<CompanyModel> result =
//				companyModels.stream().filter(c -> !ValidationUtil.isEmpty(CompanyLevelEnum.getEnum(c.getLevel()))).map(this::dealChildCompany)
//				.collect(Collectors.toList());
//		return result;
//	}

	public static List<LinkedHashMap> findNodesByCondition(List<LinkedHashMap> nodes, String conditionName,
	                                                       String condition, String childName) {
		return nodes.stream()
				.flatMap(node -> Stream.concat(
						node.get(conditionName).equals(condition) ? Stream.of(node) : Stream.empty(),
						node.get(childName) != null ? findNodesByCondition((List<LinkedHashMap>) node.get(childName),
								conditionName, condition, childName).stream() :
								Stream.empty()
				))
				.collect(Collectors.toList());
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean unitLogOut(String unitCode) {
		RegUnitInfo regUnitInfo = this
				.getOne(new LambdaQueryWrapper<RegUnitInfo>().eq(RegUnitInfo::getUnitCode, unitCode));
		if (regUnitInfo == null) {
			return Boolean.FALSE;
		}
		try {
			// 1.删除已经创建的企业信息
			if (StringUtils.isNotEmpty(regUnitInfo.getAmosCompanySeq())) {
				CompanyModel companyModel = Privilege.companyClient
						.seleteOne(Long.parseLong(regUnitInfo.getAmosCompanySeq())).getResult();
				if (companyModel != null) {
					Privilege.companyClient.deleteCompany(regUnitInfo.getAmosCompanySeq());
				}
			}
			// 2.删除已经创建的管理员账号
			FeignClientResult<AgencyUserModel> feignClientResult = Privilege.agencyUserClient
					.queryByUserId(regUnitInfo.getAdminUserId());
			if (feignClientResult != null) {
				Privilege.agencyUserClient.multDeleteUser(regUnitInfo.getAdminUserId());
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		// 3.企业注册表删除
		this.remove(new LambdaQueryWrapper<RegUnitInfo>().eq(RegUnitInfo::getUnitCode, unitCode));
		// 4.工商信息表删除
		regUnitIcService.remove(new LambdaQueryWrapper<RegUnitIc>().eq(RegUnitIc::getUnitCode, unitCode));
		// 5.许可信息删除
		baseUnitLicenceService
				.remove(new LambdaQueryWrapper<BaseUnitLicence>().eq(BaseUnitLicence::getUnitCode, unitCode));
		// 6.企业数据信息删除
		tzBaseEnterpriseInfoService
				.remove(new LambdaQueryWrapper<TzBaseEnterpriseInfo>().eq(TzBaseEnterpriseInfo::getUseCode, unitCode));
		// 7.机场单位表信息删除
		iOrgUsrService
				.remove(new LambdaQueryWrapper<OrgUsr>().eq(OrgUsr::getAmosOrgId, regUnitInfo.getAmosCompanySeq()));
		return Boolean.TRUE;
	}

	@Override
	public Boolean checkRepeatAccount(String userName) {
		return this.count(new LambdaQueryWrapper<RegUnitInfo>().eq(RegUnitInfo::getAdminLoginName, userName)) > 0;
	}

	@Override
	public Boolean checkRepeatPhone(String phoneNo) {
		return this.count(new LambdaQueryWrapper<RegUnitInfo>().eq(RegUnitInfo::getAdminTel, phoneNo)) > 0;
	}

	@Override
	public void updateAdminInfo(JSONObject dataResult) {
		RegUnitInfo regUnitInfo = regUnitInfoMapper.selectOne(new QueryWrapper<RegUnitInfo>().eq("admin_user_id", dataResult.get("userId")));
		if(!ObjectUtils.isEmpty(regUnitInfo)){
			regUnitInfo.setAdminTel(String.valueOf(dataResult.get("mobile")));
			regUnitInfo.setAdminName(String.valueOf(dataResult.get("realName")));
			regUnitInfoMapper.updateById(regUnitInfo);
		}
	}

	@Override
	public Boolean creatQrCode() {
		List<TzBaseEnterpriseInfo> tzBaseEnterpriseInfoList = tzBaseEnterpriseInfoMapper.selectList(new QueryWrapper<TzBaseEnterpriseInfo>().isNull("qr_code"));
		if (!ObjectUtils.isEmpty(tzBaseEnterpriseInfoList) && tzBaseEnterpriseInfoList.size() > 0) {
			for (TzBaseEnterpriseInfo tzBaseEnterpriseInfo : tzBaseEnterpriseInfoList) {
				String qrCode = createQRCode(tzBaseEnterpriseInfo.getUseCode());
				tzBaseEnterpriseInfoMapper.updateById(tzBaseEnterpriseInfo.setQrCode(qrCode));
			}
			return true;
		} else {
			return false;
		}
	}

	@Override
	public RegUnitInfoDto adminInfo(String unitCode) {
		// 管理员信息
		RegUnitInfo regUnitInfo = this.getOne(
				new LambdaQueryWrapper<RegUnitInfo>().eq(RegUnitInfo::getUnitCode, unitCode));
		RegUnitInfoDto regUnitInfoDto = new RegUnitInfoDto();
		if (regUnitInfo != null) {
			BeanUtils.copyProperties(regUnitInfo, regUnitInfoDto);
		}
		regUnitInfoDto.setAdminIdCardPhoto(ObjectUtils.isEmpty(regUnitInfo.getAdminIdCardPhoto()) ? new ArrayList() : JSON.parseArray(regUnitInfo.getAdminIdCardPhoto()));
		return regUnitInfoDto;
	}

	private CompanyModel dealChildCompany(CompanyModel cm) {
		cm.setChildren(this.getFilterChild(cm.getChildren() != null ? cm.getChildren() : new ArrayList()));
		cm.getChildren().stream().filter(n -> {
			CompanyModel c = JSONObject.parseObject(JSON.toJSONString(n), CompanyModel.class);
			return !ValidationUtil.isEmpty(CompanyLevelEnum.getEnum(c.getLevel()));
		}).map(n -> {
			CompanyModel c = JSONObject.parseObject(JSON.toJSONString(n), CompanyModel.class);
			return dealChildCompany(c);
		}).collect(Collectors.toList());
		return cm;
	}

	private List getFilterChild(Collection children) {
		return (List) children.stream().filter(n -> {
			CompanyModel c = JSONObject.parseObject(JSON.toJSONString(n), CompanyModel.class);
			return !ValidationUtil.isEmpty(CompanyLevelEnum.getEnum(c.getLevel()));
		}).map(s -> {
			CompanyModel c = JSONObject.parseObject(JSON.toJSONString(s), CompanyModel.class);
			c.setChildren(this.getFilterChild(c.getChildren() != null ? c.getChildren() : new ArrayList()));
			return c;
		}).collect(Collectors.toList());
	}

	private void createCompanyAndUser(RegUnitInfo regUnitInfo) {
		CompanyModel companyInfo = new CompanyModel();
		FeignClientResult<AgencyUserModel> userResult = null;
		try {
			FeignClientResult<List<RoleModel>> roleListResult = Privilege.roleClient.queryRoleList(null, null);
			List<RoleModel> allRoleList = roleListResult.getResult();
			List<RoleModel> userRoleList = new ArrayList<>();
			List<Long> roleIds = new ArrayList<>();
			Set<String> roleNameSet = new HashSet<>();
			// 3.1创建公司
			companyInfo.setAddress(dealNull2EmptyString(regUnitInfo.getProvince())
					+ dealNull2EmptyString(regUnitInfo.getCity()) + dealNull2EmptyString(regUnitInfo.getDistrict())
					+ dealNull2EmptyString(regUnitInfo.getStree()) + dealNull2EmptyString(regUnitInfo.getCommunity())
					+ dealNull2EmptyString(regUnitInfo.getAddress()));
			companyInfo.setAgencyCode("tzs");
			companyInfo.setParentId(Long.parseLong(regUnitInfo.getManagementUnitId()));
			companyInfo.setLevel("company");
			companyInfo.setCompanyName(regUnitInfo.getName());
			companyInfo.setCompanyCode(regUnitInfo.getUnitCode());
			companyInfo.setContact(regUnitInfo.getLegalPerson());
			companyInfo.setCompanyType(regUnitInfo.getUnitType());
			companyInfo.setLandlinePhone(regUnitInfo.getLegalPersonTel());
			FeignClientResult<CompanyModel> companyResult = Privilege.companyClient.create(companyInfo);
			if (companyResult == null || companyResult.getResult() == null) {
				throw new BadRequest("单位注册失败");
			}
			String adminUserName = regUnitInfo.getAdminName();
			String loginName = regUnitInfo.getAdminLoginName();
			String pwd = regUnitInfo.getAdminLoginPwd();
			String adminTel = regUnitInfo.getAdminTel();
			// 3.2 创建平台用户
			companyInfo = companyResult.getResult();
			AgencyUserModel agencyUserModel = new AgencyUserModel();
			agencyUserModel.setUserName(loginName);
			agencyUserModel.setRealName(adminUserName);
			agencyUserModel.setLockStatus("UNLOCK");
			agencyUserModel.setPassword(pwd);
			agencyUserModel.setRePassword(pwd);
			agencyUserModel.setAgencyCode("tzs");
			agencyUserModel.setMobile(adminTel);
			String unitTypeCode = regUnitInfo.getUnitTypeCode();
			// 根据unitTypeCode 获取应用和角色 数据字典配置
			String[] units = unitTypeCode.split(",");
			Set<String> appCodesSet = new HashSet<>();
			Map<Long, List<Long>> roleSeqMap = new HashMap<>();
			Map<Long, List<RoleModel>> orgRoles = new HashMap<>();
			for (String TypeCode : units) {
				DataDictionary unitType = iDataDictionaryService
						.getOne(new LambdaQueryWrapper<DataDictionary>().eq(DataDictionary::getCode, TypeCode));
				String appCode = unitType.getTypeDesc() != null ? unitType.getTypeDesc() : "";
				String[] appCodes = appCode.split(",");
				Collections.addAll(appCodesSet, appCodes);
				roleNameSet.add(unitType.getName());
//				userRoleList = allRoleList.stream().filter(r -> r.getRoleName().equals(unitType.getName()))
//						.collect(Collectors.toList());
				for (RoleModel roleModel : allRoleList.stream()
						.filter(r -> unitType.getExtend().contains(r.getSequenceNbr().toString())).collect(Collectors.toList())) {
					userRoleList.add(roleModel);
				}
				userRoleList.forEach(r -> {
					if (!roleIds.contains(r.getSequenceNbr())) {
						roleIds.add(r.getSequenceNbr());
					}
				});
				roleSeqMap.put(companyInfo.getSequenceNbr(), roleIds);
				orgRoles.put(companyInfo.getSequenceNbr(), userRoleList);
			}
			agencyUserModel.setAppCodes(new ArrayList<>(appCodesSet));
			agencyUserModel.setOrgRoles(orgRoles);
			agencyUserModel.setOrgRoleSeqs(roleSeqMap);
			userResult = Privilege.agencyUserClient.create(agencyUserModel);
			if (userResult == null || userResult.getResult() == null) {
				throw new BadRequest("单位注册失败");
			}
			String[] userIds = { userResult.getResult().getUserId() };
			regUnitInfo.setAdminUserId(userResult.getResult().getUserId());
			regUnitInfo.setAmosCompanySeq(companyInfo.getSequenceNbr().toString());
			// 3.3 org_user 创建组织机构
			OrgUsr org = new OrgUsr();
			org.setBizOrgCode(TreeParser.genTreeCode());
			org.setBizOrgType(CommonConstant.BIZ_ORG_TYPE_COMPANY);
			org.setBizOrgName(regUnitInfo.getName());
			org.setRecDate(new Date());
			org.setRecUserId(userResult.getResult().getUserId());
			org.setRecUserName(userResult.getResult().getUserName());
			org.setAmosOrgId(companyInfo.getSequenceNbr() + "");
			org.setAmosOrgCode(companyInfo.getOrgCode());
			iOrgUsrService.save(org);
//			if (groupSeq != null) {
//				Privilege.groupUserClient.create(groupSeq, Arrays.asList(userIds));
//			}
		} catch (Exception e) {
			// 删除已经创建的 企业信息
			if (companyInfo != null && companyInfo.getSequenceNbr() != null) {
				Privilege.companyClient.deleteCompany(companyInfo.getSequenceNbr() + "");
			}
			if (userResult != null && userResult.getResult() != null
					&& StringUtils.isNotEmpty(userResult.getResult().getUserId())) {
				Privilege.agencyUserClient.multDeleteUser(userResult.getResult().getUserId());
			}
			log.error(e.getMessage(), e);
			throw new RuntimeException(e.getMessage());
		}
	}


	@Override
	public String submit(Long pageId, String taskId, String planInstanceId, String topic, String tableName, Map<String, Object> objectMap) throws Exception {
		String roleId = "";
		// 根据指标taskId查询
		FeignClientResult<Map<String, Object>> taskMessage = idxFeignService.getTaskId(taskId);
		logger.info("idx返回任务信息,{}",  JSONObject.toJSONString(taskMessage));
		if ("200".equals(String.valueOf(taskMessage.getStatus())) && !ObjectUtils.isEmpty(taskMessage)) {
			Object id = taskMessage.getResult().get("processInstanceId");
			// 根据processInstanceId查询workFlow服务对应的taskId
			JSONObject flowTask = workflowFeignService.getTaskId(String.valueOf(id));
			logger.info("workFlow返回任务id,{}",  JSONObject.toJSONString(flowTask));
			if (!ObjectUtils.isEmpty(flowTask) && !ObjectUtils.isEmpty(flowTask.get("data"))) {
				JSONObject data = JSON.parseObject(JSON.toJSONString(flowTask.get("data")));
				Object id1 = data.get("id");
				// 根据taskId查询流程节点绑定角色id
				JSONObject result = workflowFeignService.getRoleId(String.valueOf(id1));
				logger.info("workFlow返回角色id,{}",  JSONObject.toJSONString(result));
				if (!ObjectUtils.isEmpty(result) && !ObjectUtils.isEmpty(result.get("result"))) {
					JSONObject result1 = JSON.parseObject(JSON.toJSONString(result.get("result")));
					roleId = String.valueOf(result1.get("roleId"));
				}
			}
		}
		// 企业下所有用户(上送工作流企业整改用户参数)
		ArrayList<String> flow = new ArrayList<>();
		// 企业下所有用户(更新任务)
		ArrayList<String> task = new ArrayList<>();
		// 查询第一个填报信息获取企业
		String companyName = "";
		// 查询流程第一个节点所选择的执行企业信息
		FeignClientResult<JSONObject> firstTask = idxFeignService.getFirstTask(taskId);
		logger.info("idx返回第一个节点任务信息,{}",  JSONObject.toJSONString(firstTask));
		if (!ObjectUtils.isEmpty(firstTask)) {
			companyName = String.valueOf(firstTask.getResult().get("CHECKED_COMPANY"));
		}
		if (!ObjectUtils.isEmpty(objectMap)) {
			FeignClientResult<CompanyModel> companyModelFeignClientResult = Privilege.companyClient.queryByCompanyName(companyName);
			if (!ObjectUtils.isEmpty(companyModelFeignClientResult.getResult()) && !ObjectUtils.isEmpty(companyModelFeignClientResult.getResult().getOrgCode())) {
				//FeignClientResult<Set<AgencyUserModel>> setFeignClientResult = Privilege.agencyUserClient.queryByOrgCode(companyModelFeignClientResult.getResult().getOrgCode(), null);
				Long sequenceNbr = companyModelFeignClientResult.getResult().getSequenceNbr();
				// 查询企业对应角色下的用户
				logger.info("向privilege发送参数roleId,companyId,{},{}",  roleId, sequenceNbr);
				FeignClientResult<List<AgencyUserModel>> listFeignClientResult = Privilege.agencyUserClient.queryByCompanyRoles(sequenceNbr, roleId, null, null);
				logger.info("privilege返回用户信息,{}",  JSONObject.toJSONString(listFeignClientResult));
				if (!ObjectUtils.isEmpty(listFeignClientResult) && !ObjectUtils.isEmpty(listFeignClientResult.getResult())){
					listFeignClientResult.getResult().forEach(item ->{
						flow.add(item.getUserName());
						task.add(item.getUserId());
					});
				}else {
					throw new BadRequest("没有对应企业整改执行人！");
				}

//				if (!ObjectUtils.isEmpty(setFeignClientResult)) {
//					setFeignClientResult.getResult().forEach(item -> {
//						flow.add(item.getUserName());
//						task.add(item.getUserId());
//					});
//				}
			}
		}
		String userIds = String.join(",", flow);
		String userIdsTask = String.join(",", task);
		// 添加被检查企业下的人员id
		objectMap.put("CHECKED_COMPANY_USERS", userIds);
		objectMap.put("CHECKED_COMPANY_USER_ids", userIdsTask);
		// 表单信息提交
		FeignClientResult<String> submit = idxFeignService.submit(pageId, taskId, planInstanceId,"CHECKED_COMPANY_USER_ids", topic, tableName, objectMap);
	//	if ("200".equals(String.valueOf(submit.getStatus()))) {
//			JSONObject jsonObject = new JSONObject();
//			jsonObject.put("title", "企业整改");
//			jsonObject.put("userIds", userIdsTask);
//			logger.info("idx执行任务更新参数,{}",  JSONObject.toJSONString(jsonObject));
//			//FeignClientResult<JSONObject> jsonObjectFeignClientResult = idxFeignService.updateAmosTask(taskId, jsonObject);
//			updateAmosTask(taskId, jsonObject);
//			//logger.info("idx执行任务更新任务返回参数,{}",  JSONObject.toJSONString(jsonObjectFeignClientResult));
//
//		}
		return "ok";
	}

	/***
	 * idx通用提交接口为异步，解决任务还未创建成功时执行更新失败
	 * @param taskId
	 * @param object
	 * @throws InterruptedException
	 */
	@Async
	void updateAmosTask(String taskId, JSONObject object) throws InterruptedException {
		Thread.sleep(1000*2);
		FeignClientResult<JSONObject> jsonObjectFeignClientResult = idxFeignService.updateAmosTask(taskId, object);
		logger.info("idx执行任务更新任务返回参数,{}",  JSONObject.toJSONString(jsonObjectFeignClientResult));
	}
	private String dealNull2EmptyString(String t) {
		return StringUtils.isEmpty(t) ? "" : t;
	}
}