package com.fdkankan.dxf.parse.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fdkankan.dxf.fdjson.vo.FdPoints;
import com.fdkankan.dxf.generate.DxfDocWriter;
import com.fdkankan.dxf.generate.Vector3;
import com.fdkankan.dxf.generate.enums.LineWidthEnum;
import com.fdkankan.dxf.generate.model.DxfArc;
import com.fdkankan.dxf.generate.model.DxfLine;
import com.fdkankan.dxf.generate.model.DxfPoint;
import com.fdkankan.dxf.generate.model.DxfText;
import com.fdkankan.dxf.generate.model.base.Color;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;

public class LaserMeterToDxfUtil {

    /**
     * 场景测量数据转换dxf
     * @param inFile  json输入文件
     * @param outPath dxf输出地址
     */

    public static void toDxf(File inFile, String outPath) throws Exception{
        String msg = FileUtil.readString(inFile, StandardCharsets.UTF_8);
        JSONArray jsonObject = JSONArray.parseArray(msg);
        toDxf(jsonObject,outPath);
    }
    public static void toDxf(String inPath, String outPath) throws Exception {
        JSONArray jsonObject = JSONArray.parseArray(inPath);
        toDxf(jsonObject,outPath);
    }

    /**
     *
     * @param jsonArray  线数组
     * @param outPath 输出路径
     * @throws Exception
     */

    public static void toDxf(JSONArray jsonArray, String outPath) throws Exception{

        DxfDocWriter dxfDocWriter = new DxfDocWriter();
        HashSet<Vector3> pointSet= new HashSet<>();

        for (Object obj : jsonArray) {
            JSONObject jsonObject = (JSONObject) (obj);
            JSONArray points = jsonObject.getJSONArray("points");
            String type = jsonObject.getString("type");
            if(type.contains("AREA") || type.contains("RECTANGLE")){
                for (int i = 0 ;i < points.size();i ++){
                    JSONObject point1 = (JSONObject) points.get(i);
                    JSONObject point2 = (JSONObject) points.get(  i+1 >= points.size()? 0 :i+1 );
                    drawLine(point1,point2,pointSet,dxfDocWriter);
                }
            }
            if(type.contains("SERIES") ){
                for (int i = 0 ;i < points.size();i ++){
                    if(i+1 >= points.size()){
                        continue;
                    }
                    JSONObject point1 = (JSONObject) points.get(i);
                    JSONObject point2 = (JSONObject) points.get(  i+1 >= points.size()? 0 :i+1 );
                    drawLine(point1,point2,pointSet,dxfDocWriter);
                }
            }
            if(type.contains("LINE") ){
                JSONObject point1 = (JSONObject) (points.get(0));
                JSONObject point2 = (JSONObject) (points.get(1));
                drawLine(point1,point2,pointSet,dxfDocWriter);
            }



        }

        for (Vector3 vector3 : pointSet) {
            DxfArc dxfArc = new DxfArc();
            dxfArc.setCenter(vector3);
            dxfArc.setRadius(0.5);
            dxfArc.setStartAngle(0);
            dxfArc.setEndAngle(360);
            dxfArc.setSolid(true);
            dxfArc.setSolidColor(new Color(255,255,255));
            dxfArc.setColor(new Color(255,255,255));
            dxfDocWriter.addEntity(dxfArc);
        }
        dxfDocWriter.save(outPath, true);

    }


    /**
     * 透视投影 模拟人眼视角，将三维点投影到二维平面，常用于计算机图形学。公式为：
     * x1 = x/z ,y1=y/z
     *
     * 正交投影 忽略z
     */
    public static void drawLine(JSONObject point1, JSONObject point2, HashSet<Vector3> pointSet,DxfDocWriter dxfDocWriter){
        Vector3 point3d1 = new Vector3(point1.getDouble("x"),point1.getDouble("y"),point1.getDouble("z"));
        Vector3 point3d2 = new Vector3(point2.getDouble("x"),point2.getDouble("y"),point2.getDouble("z"));
        Vector3 startPoint = new Vector3((point1.getDouble("x") ) * 100 ,(point1.getDouble("y")) * 100,0);
        Vector3 endPoint = new Vector3((point2.getDouble("x") ) * 100 ,(point2.getDouble("y")) * 100,0);
        pointSet.add(startPoint);
        pointSet.add(endPoint);
        drawLinePoint(startPoint,endPoint,dxfDocWriter);
        BigDecimal bigDecimal = BigDecimal.valueOf(distanceTo(point3d1, point3d2) ).setScale(4, RoundingMode.UP);
        DxfText dxfText = new DxfText();

//        Double x = (endPoint.getX() + startPoint.getX()) / 2  ;
//        Double y = (endPoint.getY() + startPoint.getY()) / 2;
//        double px = (2 * startPoint.getX() + endPoint.getX()) / 3;
//        double py = (2 * startPoint.getY() + endPoint.getY()) / 3;

        double px = startPoint.getX() + (2.0/5.0) * (endPoint.getX() - startPoint.getX());
        double py = startPoint.getY() + (2.0/5.0) * (endPoint.getY() - startPoint.getY());

        Vector3 vector3 = new Vector3(px   , py  , 0);
        dxfText.setStartPoint(vector3);
        dxfText.setText(bigDecimal.toString()+"m");
        dxfText.setAngle(angleBetween(startPoint,endPoint));
        dxfText.setHigh(bigDecimal.doubleValue() * 2);
        dxfText.setColor(new Color(255,255,255));
        dxfDocWriter.addEntity(dxfText);
    }

    public static void drawLinePoint(Vector3 point,Vector3 point2,DxfDocWriter dxfDocWriter){
        DxfLine dxfLine = new DxfLine();
        dxfLine.setStartPoint(new Vector3(point.getX(), point.getY(), 0));
        dxfLine.setEndPoint(new Vector3(point2.getX(), point2.getY(), 0));
        dxfLine.setColor(new Color(255,255,255));
        dxfDocWriter.addEntity(dxfLine);
    }


    // 计算两点之间的角度（相对于水平轴，单位为弧度）
    public static double angleBetween(Vector3 point, Vector3 point2) {
        //角度
        Double atan = Math.atan((point2.getY()-point.getY()) / (point2.getX()-point.getX())) / 3.14 * 180;
        return atan;
    }

    // 计算两点之间的线段长度
    public static double distanceBetween(Vector3 p1, Vector3 p2) {
        double deltaX = p2.getX() - p1.getX();
        double deltaY = p2.getY() - p1.getY();
        return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
    }

    // 计算两点之间的距离
    public static double distanceTo(Vector3 p1, Vector3 p2) {
        double dx = p1.getX() - p2.getX();
        double dy = p1.getY() - p2.getY();
        double dz = p1.getZ() - p2.getZ();
        return Math.sqrt(dx * dx + dy * dy + dz * dz);
    }

    public static void main(String[] args) throws Exception{
        String inPath ="D:\\cad\\work\\111\\1.json";
        String outPath ="D:\\cad\\work\\111\\"+new Date().getTime()+".dxf";
        LaserMeterToDxfUtil.toDxf(new File(inPath),outPath);
    }


}
