using System;
using System.IO;
using System.Linq;
using System.Reflection;
using Autodesk.Navisworks.Api;

namespace NavisworksTransport.Core
{
    /// <summary>
    /// 虚拟车辆管理器 - 负责创建和管理虚拟车辆几何体
    /// 通过追加预制的单位立方体NWC文件并缩放来创建指定尺寸的虚拟车辆
    /// </summary>
    public class VirtualVehicleManager
    {
        private static VirtualVehicleManager _instance;
        private static readonly object _lock = new object();

        /// <summary>
        /// 单例实例
        /// </summary>
        public static VirtualVehicleManager Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_lock)
                    {
                        if (_instance == null)
                        {
                            _instance = new VirtualVehicleManager();
                        }
                    }
                }
                return _instance;
            }
        }

        private ModelItem _virtualVehicleModelItem;
        private Model _virtualVehicleModel;
        private bool _isVirtualVehicleActive;

        /// <summary>
        /// 当前虚拟车辆ModelItem
        /// </summary>
        public ModelItem CurrentVirtualVehicle => _virtualVehicleModelItem;

        /// <summary>
        /// 虚拟车辆是否激活
        /// </summary>
        public bool IsVirtualVehicleActive => _isVirtualVehicleActive;

        private VirtualVehicleManager()
        {
            _isVirtualVehicleActive = false;
        }

        /// <summary>
        /// 创建虚拟车辆立方体
        /// </summary>
        /// <param name="lengthMeters">长度（米）- X方向</param>
        /// <param name="widthMeters">宽度（米）- Y方向</param>
        /// <param name="heightMeters">高度（米）- Z方向</param>
        /// <returns>创建的ModelItem</returns>
        public ModelItem CreateVirtualVehicle(double lengthMeters, double widthMeters, double heightMeters)
        {
            try
            {
                LogManager.Info($"=== 创建虚拟车辆 ===");
                LogManager.Info($"目标尺寸: {lengthMeters:F2}m × {widthMeters:F2}m × {heightMeters:F2}m");

                // 1. 清理之前的虚拟车辆
                RemoveVirtualVehicle();

                // 2. 获取单位立方体文件路径
                var unitCubePath = GetUnitCubeFilePath();
                if (string.IsNullOrEmpty(unitCubePath) || !File.Exists(unitCubePath))
                {
                    throw new FileNotFoundException($"找不到单位立方体文件: {unitCubePath}");
                }

                LogManager.Info($"单位立方体文件: {unitCubePath}");

                // 3. 记录追加前的模型数量
                var doc = Application.ActiveDocument;
                int modelCountBefore = doc.Models.Count;
                LogManager.Info($"追加前模型数量: {modelCountBefore}");

                // 4. 追加单位立方体文件
                if (!doc.TryAppendFile(unitCubePath))
                {
                    throw new InvalidOperationException($"无法追加文件: {unitCubePath}");
                }

                // 5. 获取新追加的模型
                int modelCountAfter = doc.Models.Count;
                LogManager.Info($"追加后模型数量: {modelCountAfter}");

                if (modelCountAfter <= modelCountBefore)
                {
                    throw new InvalidOperationException("追加文件后模型数量未增加");
                }

                _virtualVehicleModel = doc.Models.Last();
                _virtualVehicleModelItem = _virtualVehicleModel.RootItem;

                LogManager.Info($"虚拟车辆模型: {_virtualVehicleModel.FileName}");
                LogManager.Info($"虚拟车辆根项: {_virtualVehicleModelItem.DisplayName}");

                // 6. 获取实际的几何体项（可能在子节点中）
                var geometryItem = FindFirstGeometryItem(_virtualVehicleModelItem);
                if (geometryItem != null && !geometryItem.Equals(_virtualVehicleModelItem))
                {
                    LogManager.Info($"找到几何体项: {geometryItem.DisplayName}");
                    _virtualVehicleModelItem = geometryItem;
                }

                // 7. 缩放到目标尺寸
                ScaleVirtualVehicle(lengthMeters, widthMeters, heightMeters);

                _isVirtualVehicleActive = true;

                LogManager.Info($"虚拟车辆创建成功");
                return _virtualVehicleModelItem;
            }
            catch (Exception ex)
            {
                LogManager.Error($"创建虚拟车辆失败: {ex.Message}", ex);
                RemoveVirtualVehicle();
                throw;
            }
        }

        /// <summary>
        /// 缩放虚拟车辆到目标尺寸
        /// 使用DocumentModels.SetModelUnitsAndTransform方法进行模型级缩放
        /// </summary>
        private void ScaleVirtualVehicle(double lengthMeters, double widthMeters, double heightMeters)
        {
            if (_virtualVehicleModel == null || _virtualVehicleModelItem == null) return;

            var doc = Application.ActiveDocument;

            // 获取当前包围盒（单位立方体应该是1m x 1m x 1m）
            var boundingBox = _virtualVehicleModelItem.BoundingBox();
            double currentLength = boundingBox.Max.X - boundingBox.Min.X;
            double currentWidth = boundingBox.Max.Y - boundingBox.Min.Y;
            double currentHeight = boundingBox.Max.Z - boundingBox.Min.Z;

            // 获取单位转换因子（米到模型单位）
            double metersToUnits = Utils.UnitsConverter.GetMetersToUnitsConversionFactor(doc.Units);

            // 当前尺寸（米）
            double currentLengthMeters = currentLength / metersToUnits;
            double currentWidthMeters = currentWidth / metersToUnits;
            double currentHeightMeters = currentHeight / metersToUnits;

            LogManager.Info($"当前尺寸: {currentLengthMeters:F2}m × {currentWidthMeters:F2}m × {currentHeightMeters:F2}m");
            LogManager.Info($"目标尺寸: {lengthMeters:F2}m × {widthMeters:F2}m × {heightMeters:F2}m");

            // 计算缩放比例
            double scaleX = currentLengthMeters > 0 ? lengthMeters / currentLengthMeters : lengthMeters;
            double scaleY = currentWidthMeters > 0 ? widthMeters / currentWidthMeters : widthMeters;
            double scaleZ = currentHeightMeters > 0 ? heightMeters / currentHeightMeters : heightMeters;

            LogManager.Info($"缩放比例: X={scaleX:F2}, Y={scaleY:F2}, Z={scaleZ:F2}");

            // 使用Transform3DComponents进行缩放
            // 获取当前模型的变换并分解
            Transform3D currentTransform = _virtualVehicleModel.Transform;
            Transform3DComponents transformComponents = currentTransform.Factor();

            // 获取当前值
            Vector3D currentTranslation = transformComponents.Translation;
            Rotation3D currentRotation = transformComponents.Rotation;
            Vector3D currentScale = transformComponents.Scale;

            LogManager.Info($"当前变换 - 平移: ({currentTranslation.X:F2}, {currentTranslation.Y:F2}, {currentTranslation.Z:F2})");
            LogManager.Info($"当前变换 - 缩放: ({currentScale.X:F2}, {currentScale.Y:F2}, {currentScale.Z:F2})");

            // 设置新的缩放值（在原有缩放基础上乘以新的缩放比例）
            transformComponents.Scale = new Vector3D(
                currentScale.X * scaleX,
                currentScale.Y * scaleY,
                currentScale.Z * scaleZ
            );

            // 组合成新的变换
            Transform3D newTransform = transformComponents.Combine();

            // 获取当前模型单位
            Units currentUnits = _virtualVehicleModel.Units;

            // 应用新的变换
            doc.Models.SetModelUnitsAndTransform(_virtualVehicleModel, currentUnits, newTransform, false);

            // 验证缩放结果
            var newBoundingBox = _virtualVehicleModelItem.BoundingBox();
            double newLength = newBoundingBox.Max.X - newBoundingBox.Min.X;
            double newWidth = newBoundingBox.Max.Y - newBoundingBox.Min.Y;
            double newHeight = newBoundingBox.Max.Z - newBoundingBox.Min.Z;

            double newLengthMeters = newLength / metersToUnits;
            double newWidthMeters = newWidth / metersToUnits;
            double newHeightMeters = newHeight / metersToUnits;

            LogManager.Info($"缩放后尺寸: {newLengthMeters:F2}m × {newWidthMeters:F2}m × {newHeightMeters:F2}m");
        }

        /// <summary>
        /// 移除虚拟车辆（隐藏模型，因为Navisworks API不支持直接删除追加的模型）
        /// </summary>
        public void RemoveVirtualVehicle()
        {
            try
            {
                if (_virtualVehicleModelItem != null)
                {
                    // Navisworks API不支持直接删除追加的模型
                    // 使用隐藏方式处理
                    var doc = Application.ActiveDocument;
                    var modelItems = new ModelItemCollection { _virtualVehicleModelItem };
                    doc.Models.SetHidden(modelItems, true);
                    
                    LogManager.Info($"已隐藏虚拟车辆模型");
                }

                // 清理引用但不尝试删除模型
                _virtualVehicleModel = null;
                _virtualVehicleModelItem = null;
                _isVirtualVehicleActive = false;
            }
            catch (Exception ex)
            {
                LogManager.Error($"隐藏虚拟车辆失败: {ex.Message}");
                _virtualVehicleModel = null;
                _virtualVehicleModelItem = null;
                _isVirtualVehicleActive = false;
            }
        }

        /// <summary>
        /// 获取单位立方体文件路径
        /// </summary>
        private string GetUnitCubeFilePath()
        {
            // 方法1：从插件目录获取
            var assemblyLocation = Assembly.GetExecutingAssembly().Location;
            var pluginDir = Path.GetDirectoryName(assemblyLocation);
            
            // 尝试多个可能的位置
            var possiblePaths = new[]
            {
                Path.Combine(pluginDir, "resources", "unit_cube.nwc"),
                Path.Combine(pluginDir, "unit_cube.nwc"),
                Path.Combine(pluginDir, "..", "resources", "unit_cube.nwc"),
                // 开发时的位置
                @"c:\Users\Tellme\apps\NavisworksTransport\resources\unit_cube.nwc"
            };

            foreach (var path in possiblePaths)
            {
                var fullPath = Path.GetFullPath(path);
                if (File.Exists(fullPath))
                {
                    LogManager.Info($"找到单位立方体文件: {fullPath}");
                    return fullPath;
                }
            }

            LogManager.Warning($"在以下位置未找到单位立方体文件:");
            foreach (var path in possiblePaths)
            {
                LogManager.Warning($"  - {Path.GetFullPath(path)}");
            }

            return null;
        }

        /// <summary>
        /// 查找第一个包含几何体的ModelItem
        /// </summary>
        private ModelItem FindFirstGeometryItem(ModelItem root)
        {
            if (root.HasGeometry)
                return root;

            foreach (var child in root.Children)
            {
                var result = FindFirstGeometryItem(child);
                if (result != null)
                    return result;
            }

            return null;
        }

        /// <summary>
        /// 清理资源
        /// </summary>
        public void Cleanup()
        {
            RemoveVirtualVehicle();
        }
    }
}
