using System.Text.Json.Nodes;
using System.Windows.Media.Media3D;
using HelixToolkit.Wpf.SharpDX;
using SharpDX;
using SharpDX.Direct3D11;
using SparkClient.Views.UserControl.ViewportData.Entity;
using SparkClient.Views.UserControl.ViewportData.Enum;
using GeometryModel3D = HelixToolkit.Wpf.SharpDX.GeometryModel3D;

namespace SparkClient.Views.UserControl.ViewportData.Helper;

public class ViewportManager
{
    /// <summary>
    /// 视图中三角形实体们
    /// </summary>
    public static List<Viewport3DTriangleEntity> ViewportTriangle = new List<Viewport3DTriangleEntity>();
    
    public static JsonObject DiamondData = new JsonObject();
    /// <summary>
    /// 模型正方向(从模型中心出发的方向)
    /// </summary>
    public static Vector3 PositiveDirection = new Vector3(0, 0, 0);
    /// <summary>
    /// 模型中心点
    /// </summary>
    public static Vector3 CenterVector = new Vector3(0, 0, 0);
    /// <summary>
    /// 腰的顶部线
    /// </summary>
    public static List<Vector3> GirdleTopLines = new List<Vector3>();
    /// <summary>
    /// 腰的底部线
    /// </summary>
    public static List<Vector3> GirdleBottomLines = new List<Vector3>();
    /// <summary>
    /// 模型盒子
    /// </summary>
    public static BoundingBox ModelBounds = new BoundingBox();
    /// <summary>
    /// 模型主体
    /// </summary>
    public static MeshGeometryModel3D MainModel3D = null;
    /// <summary>
    /// 模型边框线
    /// </summary>
    public static List<LineGeometryModel3D> MainModelLines = new List<LineGeometryModel3D>();
    /// <summary>
    /// 腰垂直线
    /// </summary>
    public static List<Tuple<Vector3, Vector3>> MainModelGirdleLines = new List<Tuple<Vector3, Vector3>>();
    public static Tuple<Vector3, Vector3> MainModelGirdleMaxLines = null;
    public static Tuple<Vector3, Vector3> MainModelGirdleMinLines = null;
    public static Tuple<Vector3, Vector3> MainModelGirdleAvgLines = null;
    
    /// <summary>
    /// 模型光照
    /// </summary>
    public static List<Light3D> MainModelLighting = new List<Light3D>();
    
    public static List<MeshGeometryModel3D> MainModelMeshes = new List<MeshGeometryModel3D>();
    
    
    public static ColorConfigEntity ColorConfig = new ColorConfigEntity();
    
    /// <summary>
    /// 模型控件对象映射
    /// </summary>
    private static Viewport3DX _viewport;
    public static void SetViewport3D(Viewport3DX viewport3D)
    {
        if (_viewport != null)
        {
            ClearDicModels();
            _viewport.Items.Clear();
            
        }

        _viewport = viewport3D;
    }
    public static Viewport3DX GetViewport3D()
    {
        if (_viewport == null)
            throw new Exception("Viewport is not set");
        return _viewport;
        
    }
    #region 模型选中交互管理
    //是否双击选中
    public static bool DoubleClickSelect = true;
    //开启选中边框线
    public static bool DoubleClickSelectShowBorder = true;
    //选中边框长度文字
    public static bool DoubleClickSelectShowBorderLength = false;
    //选中边框夹角文字
    public static bool DoubleClickSelectShowBorderAngle = false;
    
    public static bool DoubleClickSelectShowInfoText = true;
    //选中同类面
    public static bool DoubleClickSelectShowPlaneType = true;
    //选中三角形代码
    public static string ChooseTriangleCode = string.Empty;
    //通过选中添加的元素
    public static List<GeometryModel3D> ChooseAddModels = new List<GeometryModel3D>();
    /// <summary>
    /// 重置选中的面
    /// </summary>
    public static void ResetChooseAddModels(string valType = "")
    {
        if (string.IsNullOrWhiteSpace(ChooseTriangleCode))
        {
            ClearDicModels();
            return;
        }

        ClearDicModels();
        HashSet<SelShowType> models = new HashSet<SelShowType>();
        models.Add(SelShowType.SelPanel);
        if(DoubleClickSelectShowBorder) models.Add(SelShowType.Border);
        if (DoubleClickSelectShowInfoText) models.Add(SelShowType.LengthText);
        // if (DoubleClickSelectShowBorderAngle) models.Add(SelShowType.BorderAngle);
        if (DoubleClickSelectShowPlaneType) models.Add(SelShowType.IsTypePanel);
        ChooseAddModels.AddRange( ViewportHelperPro.GentrateChosenView(ChooseTriangleCode,valType, models.ToArray()));
        ChooseAddModels.ForEach(e => _viewport.Items.Add(e));
    }
    /// <summary>
    /// 清除所有的选中效果
    /// </summary>
    public static void ClearDicModels()
    {
        foreach (var item in ChooseAddModels)
        {
            _viewport.Items.Remove(item);
        }
        ChooseAddModels.Clear();
    }

    /// <summary>
    /// 模拟面选中
    /// </summary>
    /// <param name="planTypeStr"></param>
    public static void MockSelectFacet(string planTypeStr)
    {
        PlaneType planeType = PlaneType.Crown;
        if (DicValueParamToFacet.ContainsKey(planTypeStr))
        {
            planeType = DicValueParamToFacet[planTypeStr];
        }
        else
        {
            ClearDicModels();
            return;
        }
        
        List<Viewport3DTriangleEntity> entities = ViewportHelperPro.GenerateLineTextModelsByType(planeType);
        if (entities.Count <= 0)
        {
            ClearDicModels();
        } 
        ChooseTriangleCode = entities[0].TriangleCode;
        ResetChooseAddModels(planTypeStr);
    }

    #region 面 - 数据固定绑定
    // 选中面 -> 数据
    public static Dictionary<PlaneType, string> DicFacetToValueParam = new Dictionary<PlaneType, string>()
    {
        { PlaneType.UpperMainFacet,"CROWN_ANGLE"},
        { PlaneType.PavilionMainFacet, "PAV_ANGLE"},
        { PlaneType.StarFacet, "STAR"},
        { PlaneType.TableFacet, "TABLE"},
        { PlaneType.Culet, "COC"},
        { PlaneType.LowerGirdleFact, "LOWER_HALVES_RATIO"},
    };
    // 数据 -> 面
    public static Dictionary<string, PlaneType> DicValueParamToFacet = new Dictionary<string, PlaneType>()
    {
        {"CROWN_ANGLE", PlaneType.UpperMainFacet},
        {"PAV_ANGLE", PlaneType.PavilionMainFacet},
        //新加
        {"TOTAL_DEPTH", PlaneType.PavilionMainFacet},
        {"TABLE", PlaneType.TableFacet},
        {"CROWN_HEIGHT", PlaneType.UpperMainFacet},
        {"PAV_DEPTH", PlaneType.PavilionMainFacet},
        {"STAR", PlaneType.StarFacet},
        {"LOWER_HALVES_RATIO", PlaneType.LowerGirdleFact},
        {"CULET", PlaneType.Culet},
        {"TOC", PlaneType.TableFacet},
        {"COC", PlaneType.Culet},
        {"TWIST", PlaneType.UpperMainFacet},
        {"CULET_TO_TABLE", PlaneType.Culet},
        
        {"GIRDLE_BEZEL", PlaneType.Girdle},
        {"GIRDLE_BONE", PlaneType.Girdle},
        {"GIRDLE_VALLEY", PlaneType.Girdle},
        
        
    };
    #endregion
    #endregion
    
    #region 统一控制方法

    public static MeshGeometryModel3D PointTowardsTheFrontModel = new MeshGeometryModel3D();
    public static void PointTowardsTheFront(bool isPoint)
    {
        if (isPoint)
        {
            var camera = ViewportHelperPro.CalculateCamera(PositiveDirection, ModelBounds);
            PointTowardsTheFrontModel = ViewportHelperPro.CreateArrow(camera.Position.ToVector3(),  ModelBounds.Center, ModelBounds);
            _viewport.Items.Add(PointTowardsTheFrontModel);
        }
        else
        {
            _viewport.Items.Remove(PointTowardsTheFrontModel);
        }
    }

    public static MeshGeometryModel3D MarkFacesModel = new MeshGeometryModel3D();
    public static void MarkSpecificFaces(bool isMark)
    {
        if (isMark)
        {
            MarkFacesModel = ViewportHelperPro.GenerateTypePanelHot(PlaneType.Error);
            _viewport.Items.Add(MarkFacesModel);
        }
        else
        {
            _viewport.Items.Remove(MarkFacesModel);
        }
    }

    /// <summary>
    /// 初始化加载模型
    /// </summary>
    /// <param name="viewport"></param>
    /// <param name="entities"></param>
    public static void LoadModelByEntities(List<Viewport3DTriangleEntity> entities)
    {
        if (entities.Count == 0 && ViewportTriangle.Count != 0)
        {
            entities.AddRange(ViewportTriangle);
        }
        
        //重置
        _viewport.Items.Clear();
        ChooseTriangleCode = string.Empty;
        ChooseAddModels.Clear();
        ResetChooseAddModels();
        
        //刷新三角形
        ViewportTriangle.Clear();
        ViewportTriangle.AddRange(entities);
        
        //初始化
        MainModel3D = ViewportHelperPro.GenerateModelByEntity(_viewport, entities);
        MainModelLines = ViewportHelperPro.GentrateLineByEntity(_viewport, entities);
        MainModelLighting = ViewportHelperPro.GenerateLightingForModel(_viewport);
        MainModelMeshes = ViewportHelperPro.GenerateModelByEntityGroupByType(entities);
        MainModelLines.AddRange(ViewportHelperPro.GentrateLineGirdleByEntity(entities)); 
        //切换相机视角
        _viewport.Camera = ViewportHelperPro.CalculateCamera(PositiveDirection, ModelBounds);
        _viewport.Camera.UpDirection = new Vector3D(0, -1, 0);
        _viewport.RenderHost.MSAA = MSAALevel.Maximum;
    }

    /// <summary>
    /// 是否显示主体模型
    /// </summary>
    /// <param name="isShow"></param>
    public static void ShowMainModel3D(bool isShow)
    {
        if (MainModel3D == null) return;
        if (_viewport == null) return;
        if (isShow)
        {
            if(_viewport.Items.Contains(MainModel3D))
                return;
            else
                _viewport.Items.Add(MainModel3D);
        }
        else
        {
            _viewport.Items.Remove(MainModel3D);
        }
    }
    
    /// <summary>
    /// 是否显示主体模型
    /// </summary>
    /// <param name="isShow"></param>
    public static void ShowMainModel3DByType(bool isShow)
    {
        if (MainModel3D == null) return;
        if (_viewport == null) return;
        if (isShow)
        {
            MainModelMeshes.ForEach(e =>
            {
                if(!_viewport.Items.Contains(e))
                    _viewport.Items.Add(e);
            });
        }
        else
        {
            MainModelMeshes.ForEach(e =>
            {
                _viewport.Items.Remove(e);                                                     
            });
        }
    }
    

    public static void ShowMainModelLines(bool isShow)
    {
        if (_viewport == null) return;
        if (isShow)
        {
            MainModelLines.ForEach(e =>
            {
                if(!_viewport.Items.Contains(e))
                    _viewport.Items.Add(e);
            });
        }
        else
        {
            MainModelLines.ForEach(e => _viewport.Items.Remove(e));
        }
    }

    public static void ShowMainModelLighting(bool isShow)
    {
        if (_viewport == null) return;
        if (isShow)
        {
            MainModelLighting.ForEach(e =>
            {
                if(!_viewport.Items.Contains(e))
                    _viewport.Items.Add(e);
            });
        }
        else
        {
            MainModelLighting.ForEach(e => _viewport.Items.Remove(e));
        }
    }
    public static void Translucent(bool isShow)
    {
        if (_viewport == null) return;
        if (isShow)
        {
            MainModel3D.Material = _glassMaterial;
        }
        else
        {
            MainModel3D.Material = _material;
        }
    }
    
    public static void TranslucentTex(bool isShow)
    {
        if (_viewport == null) return;
        if (isShow)
        {
            string texturePath2 = "pack://Appliction:,,,/Res/morning_racing_circuit_16k.dds";
            
            var texture2 = TextureModel.Create(texturePath2);
       
            var material = new PBRMaterial
            {
                AlbedoColor = new SharpDX.Color4(0.0f, 1.0f, 1.0f, 1.0f), // 白色基色
                MetallicFactor = 0.0f,
                RoughnessFactor = 0.5f,
                ReflectanceFactor = 0.2f,
                RenderEnvironmentMap = false,
                // AlbedoMap = texture, 
                IrradianceMap = texture2,
                RenderIrradianceMap = true,
            };
            MainModel3D.Material = material;
        }
        else
        {
            MainModel3D.Material = _material;
        }
    }
    public static void LockCameraView(bool isShow)
    {
        /*Generate Ruler
         * FixedPosition:用于静态视角,用户无法互动。
         * WalkAround:用于用户自由控制相机位置。
         * Inspect:用于观察和检查物体,用户可以旋转和缩放,但不能平移。(默认)
         */
        // Viewport3Dx.CameraMode = CameraMode.Inspect;
        if (_viewport == null) return;
        if (isShow)
        {
            _viewport.CameraMode = CameraMode.FixedPosition;
        }
        else
        {
            _viewport.CameraMode = CameraMode.Inspect;
        }
    }

    #endregion
    
    
     #region 预制颜色
    /// <summary>
    /// 材质:半透明蓝
    /// </summary>
    private static PBRMaterial _glassMaterial = new PBRMaterial
    {
        // 半透明蓝色
        AlbedoColor = new Color4(0.0f, 0.0f, 1.0f, 0.5f), 
        // 设置为非金属
        MetallicFactor = 0.0, 
        // 光滑表面
        RoughnessFactor = 0.05, 
        // 环境光遮蔽
        AmbientOcclusionFactor = 1.0,
        // 强反射
        ReflectanceFactor = 0.9, 
        // 清漆效果(类似折射效果)
        ClearCoatStrength = 0.8, 
        ClearCoatRoughness = 0.05, 
        // 启用环境贴图以增强反射
        RenderEnvironmentMap = true, 
        // 启用阴影效果
        RenderShadowMap = true
    };

    /// <summary>
    /// 默认灰色自发光
    /// </summary>
    private static PBRMaterial _material = new PBRMaterial
    {
        AlbedoColor = new Color4(0,0,0,1f), // 黑色,避免其他光照影响
        EmissiveColor = ColorConfig.MainFacetColor , // LightGray #D3D3D3
        MetallicFactor = 0.0, // 非金属
        RoughnessFactor = 1.0, // 高粗糙度,避免反射效果
        ReflectanceFactor = 0.0, // 无反射
        ClearCoatStrength = 0.0, // 无清漆效果
        ClearCoatRoughness = 1.0, // 高粗糙度
        SurfaceMapSampler = new SamplerStateDescription
        {
            Filter = Filter.MinMagMipLinear,
            AddressU = TextureAddressMode.Wrap,
            AddressV = TextureAddressMode.Wrap,
            AddressW = TextureAddressMode.Wrap
        }
    };
    
    #endregion
}
public enum SelShowType
{
    Border = 0,
    LengthText = 1,
    BorderAngle = 2,
    IsTypePanel = 3,
    SelPanel = 4,
}