using System;
using System.Collections.Generic;
using System.Windows;
using Autodesk.Navisworks.Api;
using NavisApplication = Autodesk.Navisworks.Api.Application;

namespace NavisworksTransport.Utils
{
    /// <summary>
    /// NWD 文件导出工具类
    /// 提供通用的 NWD 导出功能，与具体业务场景解耦
    /// </summary>
    public static class NwdExportHelper
    {
        /// <summary>
        /// 导出指定对象到 NWD 文件
        /// 使用 ExecuteInIsolation 自动计算并隐藏无关节点
        /// </summary>
        /// <param name="objects">要导出的对象列表</param>
        /// <param name="filePath">导出文件路径</param>
        /// <param name="excludeHiddenItems">是否排除隐藏项，默认 true</param>
        /// <returns>导出文件路径，失败返回 null</returns>
        public static string ExportToNwd(List<ModelItem> objects, string filePath, bool excludeHiddenItems = true)
        {
            if (objects == null || objects.Count == 0)
                throw new ArgumentException("对象列表不能为空", nameof(objects));
            if (string.IsNullOrEmpty(filePath))
                throw new ArgumentException("文件路径不能为空", nameof(filePath));

            var document = NavisApplication.ActiveDocument;
            if (document == null)
            {
                LogManager.Warning("[NwdExportHelper] 没有活动文档");
                return null;
            }

            // 必须在主线程执行
            string result = null;
            System.Windows.Application.Current.Dispatcher.Invoke(() =>
            {
                // 准备要显示的项目
                var itemsToShow = new ModelItemCollection();
                foreach (var item in objects)
                    itemsToShow.Add(item);

                // 在隔离模式下执行导出
                result = VisibilityHelper.ExecuteInIsolation(itemsToShow, () =>
                {
                    var exportOptions = new NwdExportOptions
                    {
                        ExcludeHiddenItems = excludeHiddenItems
                    };

                    document.ExportToNwd(filePath, exportOptions);
                    LogManager.Info($"[NwdExportHelper] NWD导出完成: {objects.Count} 个对象 -> {filePath}");
                    return filePath;
                });
            });

            return result;
        }

        /// <summary>
        /// 使用预计算的隐藏节点列表导出到 NWD 文件
        /// 适用于已经遍历并计算好隐藏节点的场景（如剖面盒导出）
        /// </summary>
        /// <param name="objects">要导出的对象列表</param>
        /// <param name="itemsToHide">预计算的隐藏节点集合</param>
        /// <param name="filePath">导出文件路径</param>
        /// <param name="operationName">操作名称（用于日志）</param>
        /// <returns>导出文件路径，失败返回 null</returns>
        public static string ExportToNwdWithPrecomputedHiddenItems(
            List<ModelItem> objects, 
            ModelItemCollection itemsToHide, 
            string filePath, 
            string operationName = "NWD导出")
        {
            if (objects == null || objects.Count == 0)
                throw new ArgumentException("对象列表不能为空", nameof(objects));
            if (string.IsNullOrEmpty(filePath))
                throw new ArgumentException("文件路径不能为空", nameof(filePath));

            var document = NavisApplication.ActiveDocument;
            if (document == null)
            {
                LogManager.Warning($"[NwdExportHelper] {operationName}失败：没有活动文档");
                return null;
            }

            // 必须在主线程执行
            string result = null;
            System.Windows.Application.Current.Dispatcher.Invoke(() =>
            {
                // 使用预计算隐藏节点的方法
                result = VisibilityHelper.ExecuteWithPrecomputedHiddenItems(
                    itemsToHide,
                    () =>
                    {
                        var exportOptions = new NwdExportOptions
                        {
                            ExcludeHiddenItems = true
                        };

                        document.ExportToNwd(filePath, exportOptions);
                        
                        LogManager.Info($"[NwdExportHelper] {operationName}完成: {objects.Count} 个对象，隐藏 {itemsToHide?.Count ?? 0} 个节点 -> {filePath}");
                        return filePath;
                    },
                    operationName
                );
            });

            return result;
        }
    }
}
