package com.fdkankan.model.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fdkankan.common.util.FileUtils;
import com.fdkankan.model.bean.PointBean;
import com.fdkankan.model.bean.SegmentBean;
import com.fdkankan.model.bean.VertexBean;
import com.fdkankan.model.bean.WallBean;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class CreateHouseJsonUtil {

	/**
	 * 根据用户上传的户型图json文件生成houseType.json
	 * @param filePath
	 * @return
	 */
	public static JSONObject createHouseTypeJsonByUser(String filePath) {
		JSONObject house = init();
		JSONArray floors = house.getJSONArray("floors");
		String type = readType(filePath);
		if (!StrUtil.isEmpty(type) && "cad".equals(type)) {
			JSONArray floorJson = readFloorJson(filePath);

			for(int i = 0; i < floorJson.size(); ++i) {
				JSONObject floor = floorJson.getJSONObject(i);
				JSONObject floorData = convert(floor, i);
				floors.add(floorData);
			}

			return house;
		} else {
			return null;
		}
	}

	/**
	 * 根据floorplan_cad.json文件生成houseType.json
	 * @param filePath
	 * @return
	 */
	public static JSONObject createHouseTypeJsonByCad(String filePath) {

		JSONArray floors = readFloorJson(filePath);
		if(CollUtil.isEmpty(floors)){
			return null;
		}

		JSONObject house = new JSONObject();
		house.put("name", "houseType.json");
		house.put("version", "2.1");

		JSONArray targetFloors = new JSONArray();
		house.put("floors", targetFloors);

		for(int i = 0; i < floors.size(); i++){
			JSONObject floor = (JSONObject)floors.get(i);
			JSONArray[] pointsAndWalls = createHouseTypeJsonHandler(floor);
			JSONArray points = pointsAndWalls[0];
			JSONArray walls = pointsAndWalls[1];
			JSONObject targetFloor = new JSONObject();
			targetFloor.put("points", points);
			targetFloor.put("walls", walls);
			targetFloors.add(targetFloor);
		}

		return house;
	}

	private static String readType(String filePath) {
		try {
			JSONObject floorplanUser = FileUtils.readJson(filePath);
			String type = floorplanUser.getString("type");
			return type;
		} catch (IOException var3) {
			return null;
		}
	}

	private static JSONArray[] createHouseTypeJsonHandler(JSONObject floor){

		JSONArray[] result = new JSONArray[2];

		//处理点
		Map<Integer, VertexBean> vertexMap = new HashMap<>();
		Map<String, PointBean> pointMap = new HashMap<>();
		Map<Integer, String> vpMap = new HashMap<>();
		JSONArray vertexArr = floor.getJSONArray("vertex-xy");
		for(int i = 0; i < vertexArr.size(); i++){
			Object o = vertexArr.get(i);

			VertexBean vertexBean = JSON.parseObject(JSON.toJSONString(o), VertexBean.class);
			Integer vertexId = vertexBean.getId();
			vertexMap.put(vertexId, vertexBean);

			String pointId = "Point" + i;
			pointMap.put(pointId, PointBean.builder().vectorId(pointId).x(vertexBean.getX()).y(vertexBean.getY()).build());

			vpMap.put(vertexId, pointId);
		}

		//处理墙
		Map<Integer, SegmentBean> segmentMap = new HashMap<>();
		Map<String, WallBean> wallMap = new HashMap<>();
		Map<Integer, String> swMap = new HashMap<>();
		JSONArray segmentArr = floor.getJSONArray("segment");
		Map<String, String> startMap = new HashMap<>();
		Map<String, String> endMap = new HashMap<>();
		for(int i = 0; i < segmentArr.size(); i++){
			Object o = segmentArr.get(i);

			SegmentBean segmentBean = JSON.parseObject(JSON.toJSONString(o), SegmentBean.class);
			String startPointId = vpMap.get(segmentBean.getA());
			String endPointId = vpMap.get(segmentBean.getB());
			segmentBean.setStartPointId(startPointId);
			segmentBean.setEndPointId(endPointId);

			Integer segmentId = segmentBean.getId();
			segmentMap.put(segmentId, segmentBean);

			String wallId = "Wall" + i;
			WallBean wallBean = WallBean.builder()
				.vectorId(wallId)
				.start(segmentBean.getStartPointId())
				.end(segmentBean.getEndPointId())
				.children(new String[]{})
				.width(0.2d)
				.build();
			wallMap.put(wallId, wallBean);

			startMap.put(wallBean.getStart(), wallBean.getVectorId());
			endMap.put(wallBean.getEnd(), wallBean.getVectorId());

			swMap.put(segmentId, wallId);
		}

		Collection<PointBean> pointBeans = pointMap.values();
		for (PointBean pointBean : pointBeans) {
			Map<String, String> parent = new HashMap<>();
			String startParent = startMap.get(pointBean.getVectorId());
			String endParent = endMap.get(pointBean.getVectorId());
			parent.put(startParent, "start");
			parent.put(endParent, "end");
			pointBean.setParent(parent);
		}
		JSONArray pointArr = JSON.parseArray(JSON.toJSONString(pointBeans));
		result[0] = pointArr;

		Collection<WallBean> wallBeans = wallMap.values();
		JSONArray wallArr = JSON.parseArray(JSON.toJSONString(wallBeans));
		result[1] = wallArr;

		return result;

	}

	private static JSONObject init() {
		JSONObject outContent = new JSONObject();
		outContent.put("name", "houseType.json");
		outContent.put("version", "2.1");

		outContent.put("floors", new JSONArray());
		outContent.put("newVectorId", null);
		outContent.put("setting", null);
		outContent.put("boundingBox", null);
		return outContent;
	}

	private static JSONArray readFloorJson(String filePath) {
		try {
			JSONObject floorplan = FileUtils.readJson(filePath);
			JSONArray floors = floorplan.getJSONArray("floors");
			return floors;
		} catch (IOException e) {

			return null;
		}
	}

	private static JSONObject convert(JSONObject floorJson,int floor) {
		JSONArray rooms = floorJson.getJSONArray("rooms");
		JSONObject walls = floorJson.getJSONObject("walls");
		JSONObject points = floorJson.getJSONObject("points");
		JSONObject symbols = floorJson.getJSONObject("symbols");

		JSONArray _points = convertPoints(points);
		JSONArray _walls = convertWalls(walls);
		JSONArray _symbols = convertSymbols(symbols,floor);
		JSONArray _rooms = convertRooms(rooms,floor);


		JSONObject floorData = new JSONObject();
		floorData.put("points", _points);
		floorData.put("walls", _walls);
		floorData.put("symbols", _symbols);
		floorData.put("rooms", _rooms);
		return floorData;
	}

	private static JSONArray convertPoints(JSONObject points) {

	   JSONArray _points = new JSONArray();
       for (Map.Entry<String, Object> entry: points.entrySet()) {
    	   JSONObject pointValue = (JSONObject)entry.getValue();
    	   JSONObject _pointValue = new JSONObject();
    	   _pointValue.put("x", pointValue.getFloat("x"));
    	   _pointValue.put("y", pointValue.getFloat("y"));
    	   _pointValue.put("parent", pointValue.getJSONObject("parent"));
    	   _pointValue.put("vectorId", pointValue.getString("vectorId"));

    	   _points.add(_pointValue);
       }

       return _points;
	}

	private static JSONArray convertWalls(JSONObject walls) {

	   JSONArray _walls = new JSONArray();
       for (Map.Entry<String, Object> entry: walls.entrySet()) {
    	   JSONObject wallValue = (JSONObject)entry.getValue();
    	   JSONObject _wallValue = new JSONObject();
    	   _wallValue.put("start", wallValue.getString("start"));
    	   _wallValue.put("end", wallValue.getString("end"));
    	   _wallValue.put("children", wallValue.getJSONArray("children"));
    	   _wallValue.put("vectorId", wallValue.getString("vectorId"));
    	   _wallValue.put("width", 0.2);
    	   //leftEdgeId
    	   //rightEdgeId
    	   _walls.add(_wallValue);
       }

       return _walls;
	}

	//门/窗
	private static JSONArray convertSymbols(JSONObject symbols,int floor) {
	   JSONArray _symbols = new JSONArray();
       for (Map.Entry<String, Object> entry: symbols.entrySet()) {
    	   JSONObject symbolValue = (JSONObject)entry.getValue();
    	   JSONObject _symbolValue = new JSONObject();
    	   _symbolValue.put("start", symbolValue.getJSONObject("startPoint"));
    	   _symbolValue.put("end", symbolValue.getJSONObject("endPoint"));
    	   _symbolValue.put("parent", symbolValue.getString("parent"));
    	   _symbolValue.put("openSide", symbolValue.getString("openSide"));
    	   _symbolValue.put("vectorId", symbolValue.getString("vectorId"));
    	   											_symbolValue.put("points2d", symbolValue.getJSONArray("points2d"));
    	   _symbolValue.put("geoType", symbolValue.getString("geoType"));
    	   _symbolValue.put("floor", floor);

    	   //"groundClearance": -0.7,
		   //"height": 1.3,

    	   _symbols.add(_symbolValue);
       }

       return _symbols;
	}

	private static JSONArray convertRooms(JSONArray rooms,int floor) {
		JSONArray _rooms = new JSONArray();

		for(int i=0;i<rooms.size();++i) {
			JSONObject room = rooms.getJSONObject(i);
			String name = room.getString("name");
			JSONObject center = room.getJSONObject("center");
			String roomId = room.getString("roomId");
			JSONArray wallIds = room.getJSONArray("wallIds");
			JSONArray wallPointIDs = room.getJSONArray("wallPointIDs");
			String parent = room.getString("parent");

			JSONObject _room = new JSONObject();
			_room.put("name", name);
			_room.put("roomId", roomId);
			_room.put("center", center);
			_room.put("wallIds", wallIds);
			_room.put("wallPointIDs", wallPointIDs);
			_room.put("parent", parent);

			_rooms.add(_room);
		}
		return _rooms;
	}
}








