using System.Text.Json.Nodes;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Media3D;
using HandyControl.Controls;
using HelixToolkit.Wpf.SharpDX;
using Microsoft.Win32;
using SharpDX;
using SparkClient.Model.Helper;
using SparkClient.Views.UserControl.ViewportData.Entity;
using SparkClient.Views.UserControl.ViewportData.Enum;
using SparkClient.Views.UserControl.ViewportData.Helper;
using HelixToolkit.Wpf.SharpDX;
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using MathNet.Numerics;
using System.Windows.Media;


namespace SparkClient.Views.UserControl;

public partial class Viewport3D 
{

    public Viewport3D()
    {
        InitializeComponent();
        DataContext = this;
        this.Viewport3Dx.EffectsManager = new DefaultEffectsManager();
        Viewport3Dx.ShowViewCube = false;
        Viewport3Dx.ShowCoordinateSystem = false;
        ViewportManager.SetViewport3D(Viewport3Dx);
    }
    
    /// <summary>
    ///  初始化
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Viewport3D_OnLoaded(object sender, RoutedEventArgs e)
    {
        ViewportManager.SetViewport3D(Viewport3Dx);
        ViewportManager.LoadModelByEntities(new List<Viewport3DTriangleEntity>());
        
        //选项初始化 显示-后端-管理类 一致
        ViewportRightMenuSelectFaceFrame.IsEnabled = ViewportRightMenuSelectFace.IsChecked ;
        // ViewportRightMenuSelectFaceLengthText.IsEnabled = ViewportRightMenuSelectFace.IsChecked ;
        // ViewportRightMenuSelectFaceAngleText.IsEnabled = ViewportRightMenuSelectFace.IsChecked ;
        ViewportRightMenuSelectFaceText.IsEnabled = ViewportRightMenuSelectFace.IsChecked ;
        ViewportRightMenuSelectFaceKind.IsEnabled = ViewportRightMenuSelectFace.IsChecked ;
        ViewportRightMenuShowModelFace.IsChecked = true;
        ViewportRightMenuShowModelFrame.IsChecked = true;
        ViewportRightMenuShowLighting.IsChecked = true;
        ViewportRightMenuSelectFace.IsChecked = ViewportManager.DoubleClickSelect;
        ViewportRightMenuSelectFaceFrame.IsChecked = ViewportManager.DoubleClickSelectShowBorder;
        // ViewportRightMenuSelectFaceLengthText.IsChecked = ViewportManager.DoubleClickSelectShowBorderLength;
        // ViewportRightMenuSelectFaceAngleText.IsChecked = ViewportManager.DoubleClickSelectShowBorderAngle;
        ViewportRightMenuSelectFaceText.IsChecked = ViewportManager.DoubleClickSelectShowInfoText;
        ViewportRightMenuSelectFaceKind.IsChecked = ViewportManager.DoubleClickSelectShowPlaneType;


        var a  = Viewport3Dx.Items;
#if DEBUG
        Viewport3Dx.ShowViewCube = true;
        Viewport3Dx.ShowCoordinateSystem = true;
        Viewport3Dx.ShowCameraInfo = true;
        Viewport3Dx.ShowCameraTarget = !Viewport3Dx.ShowCameraTarget;
        Viewport3Dx.ShowFrameDetails = !Viewport3Dx.ShowFrameDetails;
        Viewport3Dx.ShowFrameRate = !Viewport3Dx.ShowFrameRate;
        Viewport3Dx.ShowTriangleCountInfo = !Viewport3Dx.ShowTriangleCountInfo;
#endif
    }
    

    /// <summary>
    /// 双击选择面
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Viewport3Dx_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (ViewportManager.DoubleClickSelect == false) return;
        
        var mousePosition = e.GetPosition(Viewport3Dx);
        var hits = Viewport3Dx.FindHits(mousePosition);
        // 如果没有命中任何 3D 对象
        if (hits == null || hits.Count == 0)
        {
            ViewportManager.ClearDicModels();
            return;
        }

        // 获取第一个命中的对象
        var hit = hits[0];
        // 检查是否是 MeshGeometryModel3D
        if (hit.ModelHit is MeshGeometryModel3D modelHit)
        {
            // 获取几何信息
            var geometry = modelHit.Geometry as HelixToolkit.Wpf.SharpDX.MeshGeometry3D;
            if (geometry != null)
            {
                // 获取命中的三角形索引
                var triangleIndex = hit.TriangleIndices;

                // 获取三角形顶点
                var vertex1 = geometry.Positions[triangleIndex.Item1];
                var vertex2 = geometry.Positions[triangleIndex.Item2];
                var vertex3 = geometry.Positions[triangleIndex.Item3];
                
                ViewportManager.ChooseTriangleCode = CommonHelper.GenerateTriangleCode(vertex1, vertex2, vertex3);
                ViewportManager.ResetChooseAddModels();
            }
        }
        else
        {
            ViewportManager.ClearDicModels();
        }
    }

    /// <summary>
    /// 顶部按钮 - 视角切换
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    /// <exception cref="NotImplementedException"></exception>
    private void BtnAngle_OnClick(object sender, RoutedEventArgs e)
    {
        var directionName = ((Button)sender).Name.ToString();
        var directionValue = (int) TbCustomizeRevolve.Value;
        
        var center = ViewportManager.ModelBounds.Center;
        var maxDimension = ViewportManager.ModelBounds.Size.Length();
        var distance = maxDimension * 1.2; // 调整相机到模型的距离,保证视野范围内
        // 获取当前相机
        var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.OrthographicCamera;
        
        switch (directionName)
        {
            case "BtnFrontView":
                //测
                camera.Position =  new Point3D(center.X, center.Y, center.Z + distance);  // 从前面看,Z轴正方向
                camera.UpDirection = new Vector3D(0, -1, 0);    
                break;
                break;
            case "BtnTopView":
                //顶、
                camera.Position = new Point3D(center.X, center.Y - distance, center.Z); // 从底部看,Y轴负方向
                camera.UpDirection = new Vector3D(0, 0, -1);
               
                break;
            case "BtnBottomView":
                //低
                camera.Position = new Point3D(center.X, center.Y + distance, center.Z);  // 从顶部看,Y轴正方向
                camera.UpDirection = new Vector3D(0, 0, 1);   
                break;
            case "BtnFrontdView":
                //测
                camera.Position =  new Point3D(center.X, center.Y, center.Z + distance);  // 从前面看,Z轴正方向
                camera.UpDirection = new Vector3D(0, 1, 0);    
                break;
         
        }
        camera.LookDirection = new Vector3D(center.X -  camera.Position.X, center.Y -  camera.Position.Y, center.Z -  camera.Position.Z);
    }
    /// <summary>
    /// 顶部按钮 - 功能
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    /// <exception cref="NotImplementedException"></exception>
    private async void BtnFunction_OnClick(object sender, RoutedEventArgs e)
    {
        var directionName = ((Button)sender).Name.ToString();
        var directionValue = (int) TbCustomizeRevolve.Value;
        

        
        switch (directionName)
        {
            case "BtnFcuntion1View":
                //测
                
                break;
            case "BtnFcuntion2View":
                //顶
                
                break;
            case "BtnFcuntion3View":
                //低
                var center = ViewportManager.ModelBounds.Center;
                var maxDimension = ViewportManager.ModelBounds.Size.Length();
                var distance = maxDimension *1.2; // 调整相机到模型的距离,保证视野范围内
                var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.OrthographicCamera;
                camera.Position =  new Point3D(center.X, center.Y, center.Z);  // 从前面看,Z轴正方向
                camera.Width = ViewportManager.calCameraWidth();
                camera.UpDirection = new Vector3D(0, -1, 0);    
                camera.LookDirection = new Vector3D(center.X -  camera.Position.X, center.Y -  camera.Position.Y, center.Z -  camera.Position.Z);
                ViewportHelperPro.RotateModel(new Vector3D(0,-1,0));
                await Task.Delay(5000);
                ViewportHelperPro.RotateModel(new Vector3D(-1,0,0));
                break;
         
        }
        
    }
    
    /// <summary>
    /// 按钮调整相机方向[底部按钮]
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void BtnDirection_OnClick(object sender, RoutedEventArgs e)
    {
        var directionName = ((Button)sender).Name.ToString();
        var directionValue = (int)TbCustomizeRevolve.Value; // 旋转角度(单位:度)

        // 获取当前相机和模型中心
        var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.OrthographicCamera;
        if (camera == null) return;

        var modelCenter = ViewportManager.CenterVector; // 模型中心
        var currentPosition = camera.Position;

        // 将相机位置转换为极坐标
        var dx = currentPosition.X - modelCenter.X;
        var dy = currentPosition.Y - modelCenter.Y;
        var dz = currentPosition.Z - modelCenter.Z;

        var radius = Math.Sqrt(dx * dx + dy * dy + dz * dz); // 相机与模型中心的距离
        var azimuth = Math.Atan2(dz, dx) * 180.0 / Math.PI;  // 方位角(水平平面上的角度)
        var elevation = Math.Atan2(dy, Math.Sqrt(dx * dx + dz * dz)) * 180.0 / Math.PI; // 仰角(垂直方向的角度)

        switch (directionName)
        {
            case "BtnTop":
                //上
                elevation += directionValue;
                break;
            case "BtnBottom":
                //下
                elevation -= directionValue;
                break;
            case "BtnLeft":
                //左
                azimuth -= directionValue;
                break;
            case "BtnRight":
                //右
                azimuth += directionValue;
                break;
        }
        // 限制仰角范围在 -89.9 到 89.9 度,避免超出范围导致位置错误
        elevation = Math.Clamp(elevation, -89.9, 89.9);
        azimuth = (azimuth + 360) % 360; // 方位角在 0 到 360 范围内循环

        // 将极坐标转换回直角坐标
        var newX = modelCenter.X + radius * Math.Cos(elevation * Math.PI / 180.0) * Math.Cos(azimuth * Math.PI / 180.0);
        var newY = modelCenter.Y + radius * Math.Sin(elevation * Math.PI / 180.0);
        var newZ = modelCenter.Z + radius * Math.Cos(elevation * Math.PI / 180.0) * Math.Sin(azimuth * Math.PI / 180.0);

        // 更新相机位置和视角
        camera.Position = new Point3D(newX, newY, newZ);
        camera.LookDirection = new Vector3D(modelCenter.X - newX, modelCenter.Y - newY, modelCenter.Z - newZ);
        // camera.UpDirection = new Vector3D(0, 1, 0); // 保持 Y 轴为上方向

    }

    // private void BtnDirection_OnClick(object sender, RoutedEventArgs e)
    // {
    //     var directionName = ((Button)sender).Name.ToString();
    //     var directionValue = (int)TbCustomizeRevolve.Value; // 旋转角度(单位:度)
    //
    //     if(directionValue == 0) return;
    //     // 获取当前相机和模型中心
    //     var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.PerspectiveCamera;
    //     if (camera == null) return;
    //
    //     var modelCenter = ViewportManager.CenterVector; // 模型中心
    //     var currentPosition = camera.Position;
    //
    //     // 将相机位置转换为极坐标
    //     var dx = currentPosition.X - modelCenter.X;
    //     var dy = currentPosition.Y - modelCenter.Y;
    //     var dz = currentPosition.Z - modelCenter.Z;
    //
    //     var radius = Math.Sqrt(dx * dx + dy * dy + dz * dz); // 相机与模型中心的距离
    //     var azimuth = Math.Atan2(dz, dx) * 180.0 / Math.PI;  // 方位角(水平平面上的角度)
    //     var elevation = Math.Atan2(dy, Math.Sqrt(dx * dx + dz * dz)) * 180.0 / Math.PI; // 仰角(垂直方向的角度)
    //
    //     switch (directionName)
    //     {
    //         case "BtnTop":
    //             //上
    //             elevation += directionValue;
    //             break;
    //         case "BtnBottom":
    //             //下
    //             elevation -= directionValue;
    //             break;
    //         case "BtnLeft":
    //             //左
    //             azimuth -= directionValue;
    //             break;
    //         case "BtnRight":
    //             //右
    //             azimuth += directionValue;
    //             break;
    //     }
    //     // 限制仰角范围在 -89.9 到 89.9 度,避免超出范围导致位置错误
    //     // elevation = elevation > 90 || elevation < -90 ?  ? elevation + 90 : elevation - 90: elevation;
    //     // elevation = elevation;
    //     int isFan = 1;
    //     if (elevation > 90 || elevation < -90)
    //     {
    //         if (elevation < -90)
    //         {
    //             elevation += 90;
    //         }
    //         else
    //         {
    //             elevation -= 90;
    //             isFan = -1;
    //         }
    //     }
    //
    //     azimuth = (azimuth + 360) % 360; // 方位角在 0 到 360 范围内循环
    //
    //     // 将极坐标转换回直角坐标
    //     var newX = modelCenter.X + radius * Math.Cos(elevation * Math.PI / 180.0) * Math.Cos(azimuth * Math.PI / 180.0);
    //     var newY = modelCenter.Y + radius * Math.Sin(elevation * Math.PI / 180.0);
    //     var newZ = modelCenter.Z + radius * Math.Cos(elevation * Math.PI / 180.0) * Math.Sin(azimuth * Math.PI / 180.0);
    //
    //     // 更新相机位置和视角
    //     camera.Position = new Point3D(newX, newY, newZ);
    //     camera.LookDirection = new Vector3D(modelCenter.X - newX, modelCenter.Y - newY, modelCenter.Z - newZ);
    //     camera.UpDirection = new Vector3D(camera.UpDirection.X, camera.UpDirection.Y * isFan, camera.UpDirection.Z); // 保持 Y 轴为上方向
    //     
    //     
    //     
    // }

    
    #region 右键菜单事件绑定
    /// <summary>
    /// 右键选择
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void MenuItem_OnCheckedChanged(object sender, RoutedEventArgs e)
    {
        ViewportRightMenuSelectFaceFrame.IsEnabled = ViewportRightMenuSelectFace.IsChecked ;
        // ViewportRightMenuSelectFaceLengthText.IsEnabled = ViewportRightMenuSelectFace.IsChecked ;
        // ViewportRightMenuSelectFaceAngleText.IsEnabled = ViewportRightMenuSelectFace.IsChecked ;
        ViewportRightMenuSelectFaceText.IsEnabled = ViewportRightMenuSelectFace.IsChecked ;
        ViewportRightMenuSelectFaceKind.IsEnabled = ViewportRightMenuSelectFace.IsChecked ;
        
        var controlName = ((MenuItem)sender).Name.ToString();
        var checkResult = (bool)((MenuItem)sender).IsChecked;
        switch (controlName)
        {
            case "ViewportRightMenuShowModelFace":
                //显示模型面
                ViewportManager.ShowMainModel3D(checkResult);
                // ViewportRightMenuShowModelFace.IsChecked = !checkResult;
                // ViewportManager.ShowMainModel3DByType(!checkResult);
                break;
            case "ViewportRightMenuShowModelFaceByType":
                //显示模型面
                // ViewportManager.ShowMainModel3D(!checkResult);
                // ViewportRightMenuShowModelFaceByType.IsChecked = !checkResult;
                ViewportManager.ShowMainModel3DByType(checkResult);
                break;
            case "ViewportRightMenuShowModelFrame":
                //显示模型边框
                ViewportManager.ShowMainModelLines(checkResult);
                break;
            case "ViewportRightMenuShowLighting":
                //显示光照
                ViewportManager.ShowMainModelLighting(checkResult);
                break;
            case "ViewportRightMenuShowDefectFace":
                //显示瑕疵面
                ViewportManager.MarkSpecificFaces(checkResult);
                break;
            case "ViewportRightMenuShowFront":
                //显示正方向箭头
                ViewportManager.PointTowardsTheFront(checkResult);
                break;
            case "ViewportRightMenuSelectFace":
                //双击选择面
                ViewportManager.DoubleClickSelect = checkResult;
                ViewportManager.ClearDicModels();
                break;
            case "ViewportRightMenuSelectFaceFrame":
                //双击选择面的边框
                ViewportManager.DoubleClickSelectShowBorder = checkResult;
                ViewportManager.ResetChooseAddModels();
                break;
            case "ViewportRightMenuSelectFaceLengthText":
                //双击选择面的边框长度文字
                ViewportManager.DoubleClickSelectShowBorderLength = checkResult;
                ViewportManager.ResetChooseAddModels();
                break;
            case "ViewportRightMenuSelectFaceText":
                //双击选择面的边框长度文字
                ViewportManager.DoubleClickSelectShowInfoText = checkResult;
                ViewportManager.ResetChooseAddModels();
                break;
            case "ViewportRightMenuSelectFaceAngleText":
                //双击选择面的边框夹角文字
                ViewportManager.DoubleClickSelectShowBorderAngle = checkResult;
                ViewportManager.ResetChooseAddModels();
                break;
            case "ViewportRightMenuSelectFaceKind":
                //双击选择面的选择同类面
                ViewportManager.DoubleClickSelectShowPlaneType = checkResult;
                ViewportManager.ResetChooseAddModels();
                break;
            case "ViewportRightMenuShowMeshLines":
                ViewportManager.ShowMeshLines(checkResult, ViewportHelperPro.IsCrown());
                break;
        }
    }
    /// <summary>
    /// 右键按钮
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void MenuItem_OnClick(object sender, RoutedEventArgs e)
    {
        var controlName = ((MenuItem)sender).Name.ToString();
        switch (controlName)
        {
            case "ViewportRightMenuFront":
                //切换到正面
                var Camear =
                    ViewportHelperPro.CalculateCamera(ViewportManager.PositiveDirection, ViewportManager.ModelBounds);
                Viewport3Dx.Camera.Position = Camear.Position;
                Viewport3Dx.Camera.LookDirection = Camear.LookDirection;
                Viewport3Dx.Camera.UpDirection = new Vector3D(Camear.UpDirection.X, Camear.UpDirection.Y*-1, Camear.UpDirection.Z);
                break;
            case "ViewportRightMenuSaveViewToPNG":
                //保存图片
                var saveFileDialog = new SaveFileDialog
                {
                    Filter = "PNG Files (*.png)|*.png",
                    Title = MultilingualHelper.getString("ViewportSelectPath"),
                    DefaultExt = "png"
                };

                if (saveFileDialog.ShowDialog() != true)
                {
                    return; // 用户取消
                }
        
                string filePath = saveFileDialog.FileName;

                try
                {
                    ViewportHelperPro.SaveViewportAsImage(Viewport3Dx, filePath);
                    System.Windows.MessageBox.Show(MultilingualHelper.getString("ViewportSaveSucceed"));
                }
                catch (Exception ex)
                {
                    System.Windows.MessageBox.Show($"{MultilingualHelper.getString("ViewportSaveFail")}:{ex.Message}", MultilingualHelper.getString("ViewportSaveFail"), System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                }
        

                break;
        }
    }
    #endregion
    // <sys:String x:Key="ViewportSaveSucceed">保存成功</sys:String>
    // <sys:String x:Key="ViewportSaveFail">保存失败</sys:String>
    // <sys:String x:Key="ViewportSelectPath">选择路径</sys:String>
    
    #region 页面隐式交互
    
    public static readonly DependencyProperty ViewportDataProperty =
        DependencyProperty.Register(
            nameof(ViewportData),
            typeof(ViewportData.ViewportData),
            typeof(Viewport3D),
            new PropertyMetadata(null, OnViewportDataChanged));
    
    public ViewportData.ViewportData ViewportData
    {
        get => (ViewportData.ViewportData)GetValue(ViewportDataProperty);
        set => SetValue(ViewportDataProperty, value);
    }
    private static void OnViewportDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is Viewport3D control && e.NewValue is ViewportData.ViewportData data)
        {
            control.Initialize(data);
        }
    }
    
    
    private void Initialize(ViewportData.ViewportData vpData)
    {
       
    }
    
    private System.Windows.Point _mouseDownPosition;
    private bool _isDragging = false;
    private void UIElement_OnPreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (_isDragging)
        {
            _isDragging = false; 
            MainBorder.ContextMenu.Visibility = Visibility.Hidden;
            return;
        }
        MainBorder.ContextMenu.Visibility = Visibility.Visible;

    }

    private void UIElement_OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
        _mouseDownPosition = e.GetPosition(Viewport3Dx);
        _isDragging = false; 
        if (MainBorder.ContextMenu.Visibility == Visibility.Visible)
        {
            MainBorder.ContextMenu.Visibility = Visibility.Hidden;
            MainBorder.ContextMenu.IsOpen = false;
        }
    }
    
    private void Viewport3Dx_OnPreviewMouseMove(object sender, MouseEventArgs e)
    {
        if (e.RightButton == MouseButtonState.Pressed)
        {
            var currentPosition = e.GetPosition(Viewport3Dx);
            var distance = (currentPosition - _mouseDownPosition).Length;
            MainBorder.ContextMenu.Visibility = Visibility.Hidden;
            MainBorder.ContextMenu.IsOpen = false;
            if (distance > 5) 
            {
                _isDragging = true;
            }
        }
    }
    private void TbCustomizeRevolve_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        e.Handled = !CommonHelper.IsTextNumeric(e.Text);
    }

    private void TbCustomizeRevolve_OnPreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Tab || e.Key == Key.Left || e.Key == Key.Right)
        {
            e.Handled = false; // 不拦截
        }
        else
        {
            e.Handled = !CommonHelper.IsKeyNumeric(e.Key);
        }
    }

    private void TbCustomizeRevolve_OnTextChanged(object sender, TextChangedEventArgs e)
    {
        var textBox = sender as System.Windows.Controls.TextBox;

        if (int.TryParse(textBox.Text, out int value))
        {
            if (value < 0)
            {
                textBox.Text = "0"; // 如果小于0,重置为0
            }
            else if (value > 360)
            {
                textBox.Text = "360"; // 如果大于360,重置为360
            }
            textBox.SelectionStart = textBox.Text.Length; // 保持光标在文本末尾
        }
        else if (!string.IsNullOrWhiteSpace(textBox.Text))
        {
            textBox.Text = "0";
        }
    }
    
    #endregion


    private void TbCustomizeRevolve_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        //Viewport3Dx.ShowCameraInfo = !Viewport3Dx.ShowCameraInfo;
        //Viewport3Dx.ShowCameraTarget = !Viewport3Dx.ShowCameraTarget ;
        //Viewport3Dx.ShowFrameDetails = !Viewport3Dx.ShowFrameDetails;
        //Viewport3Dx.ShowFrameRate = !Viewport3Dx.ShowFrameRate;
        //Viewport3Dx.ShowTriangleCountInfo = !Viewport3Dx.ShowTriangleCountInfo;
    }

}