package com.persagy.bdtp.adm.test;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.persagy.bdtp.adm.common.AdmConst;
import com.persagy.bdtp.adm.dao.*;
import com.persagy.bdtp.adm.entity.*;
import com.persagy.bdtp.adm.entity.db.*;
import com.persagy.bdtp.adm.service.IAdmObjectService;
import com.persagy.bdtp.adm.service.ISyncApp;
import com.persagy.bdtp.adm.service.ISyncOldAdm;
import com.persagy.bdtp.adm.test.data.InfosCfgs;
import com.persagy.bdtp.adm.test.data.PipeCfgs;
import com.persagy.bdtp.adm.test.data.RelCfgs;
//import com.persagy.dmp.storage.utils.FileStorageHelper;
import com.persagy.dmp.common.model.response.CommonResult;
import com.persagy.dmp.define.client.DigitalObjectInfoClient;
import com.persagy.dmp.define.entity.ObjectInfoDefine;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest
public class AdmApplicationTests {

	@Test
	public void contextLoads() {
	}

	@Autowired
	private ISyncOldAdm syncOldAdm;

	@Test
	public void testHandleJobSpace(){
		syncOldAdm.handleJobSpace("Pj0002220002");
	}

	@Test
	public void testSyncOldAdm() {
		syncOldAdm.syncData("BR", "Pj0002220002");
	}

	@Test
	public void testUploadFloorMap() {
		syncOldAdm.uploadFloorMap("BR", "Pj0002220011");
	}

	@Autowired
	private IAdmObjectService objectService;

//	@Test
//	public void testDownloadFloorMap(){
//		List<AdmObject> floors = objectService.queryM2dByObjType("Pj0002220011", AdmConst.OBJ_TYPE_FLOOR);
//		for(AdmObject floor : floors) {
//			if(floor.getInfos() != null && floor.getInfos().get("floorMapId") != null) {
//				try {
//					InputStream inputStream = FileStorageHelper.downloadStream(floor.getInfos().get("floorMapId").asText());
//					BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("D:\\work_area\\images-minio\\" + floor.getInfos().get("floorMap").asText()));
//					int length = 0;
//					byte[] temp = new byte[1024 * 10];
//					while ((length = inputStream.read(temp)) != -1) {
//						bufferedOutputStream.write(temp, 0, length);
//					}
//					bufferedOutputStream.flush();
//					bufferedOutputStream.close();
//					inputStream.close();
//				}catch (Exception e) {
//					e.printStackTrace();
//				}
//				break;
//			}
//		}
//	}

	@Autowired
	private AdmInfosConfigMapper infosConfigMapper;
	@Test
	//@Transactional
	public void testInfosCfg(){
		String type = "se";

		List<AdmComponent> compList = componentMapper.selectList(null);
		HashMap<String, List<AdmComponent>> compMap = new HashMap<>();
		compList.stream().forEach(comp -> {
			List<AdmComponent> list = compMap.get(comp.getClassCode());
			if(list == null){
				list = new ArrayList<>();
				compMap.put(comp.getClassCode(), list);
			}
			list.add(comp);
		});

		infosConfigMapper.delete(new QueryWrapper<AdmInfosConfig>().eq("flag", type));

		List<AdmInfosConfig> list = new InfosCfgs().read(type);
		for(AdmInfosConfig item : list) {
			item.setFlag(type);

			setServeAreaToInfo(item.getInfos());

			List<AdmComponent> comps = compMap.get(item.getClassCode());
			if(comps != null)
				setCompsToInfo(item.getInfos(), null, comps);

			infosConfigMapper.insert(item);
		}
	}

	@Autowired
	private AdmRelsConfigMapper relsConfigMapper;
	@Test
	public void testRelsCfg(){
		String type = "ff";
		relsConfigMapper.delete(new QueryWrapper<AdmRelsConfig>().eq("flag", type));
		List<AdmRelsConfig> list = new RelCfgs().read(type);
		for(AdmRelsConfig item : list) {
			item.setFlag(type);
			relsConfigMapper.insert(item);
		}
	}

	@Autowired
	private AdmPipeConfigMapper pipeConfigMapper;
	@Test
	public void testPipeCfg(){
		String type = "ff";
		pipeConfigMapper.delete(new QueryWrapper<AdmPipeConfig>().eq("flag", type));
		List<AdmPipeConfig> list = new PipeCfgs().read(type);
		for(AdmPipeConfig item : list) {
			item.setFlag(type);
			pipeConfigMapper.insert(item);
		}
	}

	@Autowired
	private AdmComponentMapper componentMapper;
	@Test
	public void setCompToInfosCfg(){
		List<AdmComponent> compList = componentMapper.selectList(null);
		HashMap<String, List<AdmComponent>> compMap = new HashMap<>();
		compList.stream().forEach(comp -> {
			List<AdmComponent> list = compMap.get(comp.getClassCode());
			if(list == null){
				list = new ArrayList<>();
				compMap.put(comp.getClassCode(), list);
			}
			list.add(comp);
		});

		List<AdmInfosConfig> cfgList = infosConfigMapper.selectList(null);
		HashMap<String, AdmInfosConfig> cfgMap = new HashMap<>();
		cfgList.stream().forEach(cfg -> cfgMap.put(cfg.getClassCode(), cfg));

		for (Map.Entry<String, List<AdmComponent>> entry : compMap.entrySet()) {
			String classCode = entry.getKey();
			List<AdmComponent> comps = entry.getValue();
			AdmInfosConfig cfg = cfgMap.get(classCode);
			if(cfg != null){
				//不需要更新操作
//				List<Map> infos = (List)cfg.getInfos();
//				Map info = null;
//				for(Map m : infos) {
//					if("comp_type".equals(m.get("code"))){
//						info = m;
//						break;
//					}
//				}
//				setCompsToInfo(infos, info, comps);
//
//				infosConfigMapper.updateById(cfg);
			} else {
				cfg = new AdmInfosConfig();
				cfg.setId(IdUtil.simpleUUID());
				cfg.setObjType("equipment");
				cfg.setClassCode(classCode);
				AdmComponent comp0 = comps.get(0);
				cfg.setSystemCode(comp0.getSystemCode());
				cfg.setMajorCode(comp0.getSystemCode().substring(0, 2));
				List infos = new ArrayList<>();
				cfg.setInfos(infos);
				setCompsToInfo(infos, null, comps);

				infosConfigMapper.insert(cfg);
			}
		}
	}

	private void setCompsToInfo(List infos, Map info, List<AdmComponent> comps){
		if(info == null){
			info = new HashMap();
			info.put("group", "几何信息");
			info.put("code", "comp_type");
			info.put("label", "构件类型");
			info.put("dataType", "string");
			infos.add(info);
		}
		List<Map> ops = new ArrayList<>();
		for(AdmComponent comp : comps) {
			Map<String, String> map = new HashMap<>();
			ops.add(map);
			map.put("val", comp.getCompCode());
			map.put("txt", comp.getCompName());
		}
		info.put("options", ops);
	}

	private void setServeAreaToInfo(List infos){
		Map info = new HashMap();
		info.put("group", "静态信息");
		info.put("code", "serve_area");
		info.put("label", "服务区域");
		info.put("dataType", "string");
		info.put("inputType", "edit:serve_area");

		infos.add(info);
	}

	/**
	 * 为自定义新增设备类设置uuid
	 */
	@Autowired
	ObjectMapper objectMapper;
	@Autowired
	ResourceLoader resourceLoader;
	@Test
	public void testCustomEquip(){
		try{
			Resource resource = resourceLoader.getResource("classpath:equip.json");
			List<TypeDef> types = objectMapper.readValue(resource.getInputStream(), new TypeReference<List<TypeDef>>(){});
			types.stream().forEach(type -> type.setId(IdUtil.simpleUUID()));
			System.out.println(objectMapper.writeValueAsString(types));
		}catch (Exception e) {

		}
	}

	/**
	 * 为关系配置表增加direction字段
	 */
	@Test
	public void setRelCfgDirection(){
		try {
			List<Map> relDef = objectMapper.readValue(new File("D:\\work_area\\adm_1015\\rel_def.json"), List.class);
			List<AdmRelsConfig> cfgs = relsConfigMapper.selectList(null);
			for (AdmRelsConfig cfg : cfgs) {
				for(Map def : relDef) {
					if(cfg.getGraphCode().equals(def.get("graphCode")) && cfg.getRelCode().equals(def.get("code"))) {
						int d = ((Number)def.get("directional")).intValue();
						if(d == 0)
							cfg.setDirection("none");
						else if(d == 1) {
							String target = (String) def.get("targetObjs");
							if(StrUtil.isNotBlank(target) && target.indexOf('→') > 0)
								cfg.setDirection("fixed");
							else
								cfg.setDirection("optional");
						}
						break;
					}
				}

				if(cfg.getDirection() == null)
					cfg.setDirection("optional");

				relsConfigMapper.updateById(cfg);
			}
		} catch (Exception e) {

		}
	}

	@Test
	public void testInfoCode(){
		List<AdmInfosConfig> list = infosConfigMapper.selectList(null);
		for(AdmInfosConfig cfg : list) {
			if(cfg.getInfos() != null){
				for(Object o : cfg.getInfos()) {
					if(o instanceof Map) {
						Map<String, Object> map = (Map) o;
						map.remove("name");
						map.remove("unit");
						map.remove("options");
						map.remove("dataType");
						String code = (String) map.remove("code");
						map.put("code", StrUtil.lowerFirst(code));
					}
				}
				infosConfigMapper.updateById(cfg);
			}
		}
	}

	@Autowired
	@Qualifier("syncAppImpl")
	private ISyncApp syncApp;

	@Test
	public void testBdtpObj() throws Exception{
		Object o = syncApp.downloadFrameData("HR", "Pj4501030001", "bdtp");
		System.out.println();
		System.out.println(objectMapper.writeValueAsString(o));
	}

	@Autowired
	private AdmUploadLogMapper logMapper;
	@Autowired
	private AdmClientFlagMapper clientFlagMapper;
	@Test
	public void testAutoInc(){
//		AdmUploadLog log = new AdmUploadLog("flag", "202111111111", "add");
//		ObjectNode data = objectMapper.createObjectNode();
//		data.put("id", 11111);
//		log.setData(data, objectMapper);
//		logMapper.insert(log);

		AdmClientFlag flag = new AdmClientFlag();
		//flag.setClientFlag("flag");
		flag.setUserId("bdtp");
		clientFlagMapper.insert(flag);
		System.out.println(flag.getId());
	}

	@Autowired
	private DigitalObjectInfoClient infoClient;
	@Test
	public void testMyInfos(){
		String groupCode = "JD";
		String projectId = "0";
		String userId = AdmConst.CREATOR_AUTO;

		List<ObjectInfoDefine> myInfos = new ArrayList<>();

//		myInfos.add(newInfo("equipContent", "文字描述", "STRING", groupCode));
//		myInfos.add(newInfo("equipPhoto", "设备图片", "STRING", groupCode));
//		myInfos.add(newInfo("equipCheck", "交付工作状态", "INTEGER", groupCode));
//		myInfos.add(newInfo("zRegion", "高度", "STRING", groupCode));
//		myInfos.add(newInfo("compType", "构件类型", "STRING", groupCode));

		myInfos.add(newInfo("containerId", "所属容器设备id", "STRING", groupCode));

		CommonResult<List<ObjectInfoDefine>> rtn = infoClient.createBatch(groupCode, projectId, AdmConst.APP_ID, userId, myInfos);
	}

	private ObjectInfoDefine newInfo(String code, String name, String dataType, String groupCode){
		ObjectInfoDefine info = new ObjectInfoDefine();
		info.setCode(code);
		info.setName(name);
		info.setAliasCode(StrUtil.upperFirst(code));
		info.setAliasName(name);
		info.setClassCode(AdmConst.OBJ_TYPE_EQUIPMENT);
		info.setDataType(dataType);
		info.setGroupCode(groupCode);

		info.setCategory("STATIC");
		info.setFirstTag("交付工具");
		info.setValid(1);

		return info;
	}

	@Test
	public void testLogData(){
		List<AdmUploadLog> logs = logMapper.selectList(new QueryWrapper<AdmUploadLog>().eq("operation", "add").eq("entity_type", "equipment"));
		ArrayList<Map> list = new ArrayList<>();
		for(AdmUploadLog log : logs) {
			System.out.println(log.getData());
			try{
				Map<String, Object> data = objectMapper.readValue(log.getData(), Map.class);
				Map<String, Object> location = (Map)data.get("location");
				Map<String, Object> map = new HashMap<>();
				map.put("id", data.get("id"));
				map.put("bimLocation", StrUtil.join(",", location.get("X"), location.get("Y"), location.get("Z")));
				list.add(map);
			}catch (Exception e){

			}
		}
		try{
			System.out.println(objectMapper.writeValueAsString(list));
		}catch (Exception e){

		}
	}

}
