using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using Microsoft.Win32;
using Autodesk.Navisworks.Api;
using NavisworksTransport.Core.Models;
using NavisworksTransport.Core.Services;

namespace NavisworksTransport.UI.WPF.ViewModels
{
    /// <summary>
    /// 时标对话框视图模型 - 支持完整的事件编辑
    /// </summary>
    public class TimeTagViewModel : INotifyPropertyChanged
    {
        private readonly TimeTagService _timeTagService;
        private readonly TimeTagExporter _exporter;
        private readonly TimeTagTimeLinerIntegration _timeLinerIntegration;
        private PathRoute _currentRoute;
        private TimeTagProfile _currentProfile;
        private TimeTagEvent _selectedEvent;
        private string _selectedProfileId;

        #region 属性

        public string RouteName => _currentRoute?.Name ?? "未知路径";

        public ObservableCollection<TimeTagProfile> Profiles { get; set; }

        public string SelectedProfileId
        {
            get => _selectedProfileId;
            set
            {
                _selectedProfileId = value;
                OnPropertyChanged();
                LoadProfile(value);
            }
        }

        public TimeTagProfile CurrentProfile
        {
            get => _currentProfile;
            set
            {
                _currentProfile = value;
                OnPropertyChanged();
                OnPropertyChanged(nameof(CanEdit));
                OnPropertyChanged(nameof(DefaultSpeed));
                OnPropertyChanged(nameof(TurnSpeedRatio));
                RefreshEvents();
            }
        }

        public ObservableCollection<TimeTagEvent> Events { get; set; }

        /// <summary>
        /// 当前选中的事件
        /// </summary>
        public TimeTagEvent SelectedEvent
        {
            get => _selectedEvent;
            set
            {
                _selectedEvent = value;
                OnPropertyChanged();
                OnPropertyChanged(nameof(CanEditEvent));
                OnPropertyChanged(nameof(IsSelectedDistanceEditable));
                OnPropertyChanged(nameof(IsSelectedEventTypeEditable));
                OnPropertyChanged(nameof(SelectedEventType));
                OnPropertyChanged(nameof(SelectedWaitTime));
                OnPropertyChanged(nameof(SelectedActionTime));
                OnPropertyChanged(nameof(SelectedDistance));
                OnPropertyChanged(nameof(SelectedDistanceDisplay));
            }
        }

        public bool CanEdit => CurrentProfile != null;
        public bool CanEditEvent => SelectedEvent != null && CurrentProfile != null;

        /// <summary>
        /// 选中事件的距离是否可编辑
        /// PointId为空表示手动添加的事件，距离可编辑
        /// PointId不为空表示关联路径点的事件，距离由路径点决定，不可编辑
        /// </summary>
        public bool IsSelectedDistanceEditable => SelectedEvent != null && string.IsNullOrEmpty(SelectedEvent.PointId);

        /// <summary>
        /// 选中事件的事件类型是否可编辑
        /// 同样基于PointId判断，自动生成的事件类型固定
        /// </summary>
        public bool IsSelectedEventTypeEditable => SelectedEvent != null && string.IsNullOrEmpty(SelectedEvent.PointId);

        public double DefaultSpeed
        {
            get => CurrentProfile?.DefaultSpeed ?? 1.0;
            set
            {
                if (CurrentProfile != null && Math.Abs(CurrentProfile.DefaultSpeed - value) > 0.001)
                {
                    CurrentProfile.DefaultSpeed = value;
                    OnPropertyChanged();
                    Recalculate();
                }
            }
        }

        public double TurnSpeedRatio
        {
            get => CurrentProfile?.TurnSpeedRatio ?? 0.5;
            set
            {
                if (CurrentProfile != null && Math.Abs(CurrentProfile.TurnSpeedRatio - value) > 0.01)
                {
                    CurrentProfile.TurnSpeedRatio = value;
                    OnPropertyChanged();
                    Recalculate();
                }
            }
        }

        public string TotalTimeText => CurrentProfile != null ? $"{CurrentProfile.TotalTime:F1} 秒" : "--";
        public string TotalDistanceText => _currentRoute != null ? $"{_currentRoute.TotalLength:F1} 米" : "--";
        public double TotalDistanceValue => _currentRoute?.TotalLength ?? 100;

        /// <summary>
        /// 事件类型列表
        /// </summary>
        public EventType[] EventTypes => (EventType[])Enum.GetValues(typeof(EventType));

        #endregion

        #region 选中事件的编辑属性

        public EventType SelectedEventType
        {
            get => SelectedEvent?.Type ?? EventType.Pass;
            set
            {
                // 只有手动添加的事件才能修改类型
                if (SelectedEvent != null && IsSelectedEventTypeEditable && SelectedEvent.Type != value)
                {
                    SelectedEvent.Type = value;
                    OnPropertyChanged();
                    SaveAndRecalculate();
                }
            }
        }

        public double SelectedWaitTime
        {
            get => SelectedEvent?.WaitTime ?? 0;
            set
            {
                if (SelectedEvent != null && Math.Abs(SelectedEvent.WaitTime - value) > 0.01)
                {
                    SelectedEvent.WaitTime = value;
                    OnPropertyChanged();
                    SaveAndRecalculate();
                }
            }
        }

        public double SelectedActionTime
        {
            get => SelectedEvent?.ActionTime ?? 0;
            set
            {
                if (SelectedEvent != null && Math.Abs(SelectedEvent.ActionTime - value) > 0.01)
                {
                    SelectedEvent.ActionTime = value;
                    OnPropertyChanged();
                    SaveAndRecalculate();
                }
            }
        }

        /// <summary>
        /// 选中事件的距离显示（只读）
        /// </summary>
        public string SelectedDistanceDisplay => SelectedEvent != null ? $"{SelectedEvent.Distance:F2} m" : "--";

        public double SelectedDistance
        {
            get => SelectedEvent?.Distance ?? 0;
            set
            {
                // 只有手动添加的事件（PointId为空）才能编辑距离
                if (SelectedEvent != null && IsSelectedDistanceEditable && Math.Abs(SelectedEvent.Distance - value) > 0.01)
                {
                    SelectedEvent.Distance = Math.Max(0, Math.Min(value, _currentRoute?.TotalLength ?? value));
                    OnPropertyChanged();
                    OnPropertyChanged(nameof(SelectedDistanceDisplay));
                    // 距离改变需要重新排序
                    ReorderEventsAndRecalculate();
                }
            }
        }

        #endregion

        #region 命令

        public ICommand CreateProfileCommand { get; }
        public ICommand DeleteProfileCommand { get; }
        public ICommand RefreshCommand { get; }
        public ICommand ExportCommand { get; }
        public ICommand ImportToTimeLinerCommand { get; }
        public ICommand InsertEventCommand { get; }
        public ICommand DeleteEventCommand { get; }

        #endregion

        public TimeTagViewModel(TimeTagService timeTagService, PathRoute route)
        {
            _timeTagService = timeTagService ?? throw new ArgumentNullException(nameof(timeTagService));
            _exporter = new TimeTagExporter();
            _timeLinerIntegration = new TimeTagTimeLinerIntegration(timeTagService);
            _currentRoute = route;
            
            Profiles = new ObservableCollection<TimeTagProfile>();
            Events = new ObservableCollection<TimeTagEvent>();

            CreateProfileCommand = new RelayCommand(() => CreateProfile());
            DeleteProfileCommand = new RelayCommand(() => DeleteProfile(), () => CurrentProfile != null);
            RefreshCommand = new RelayCommand(() => RefreshProfiles());
            ExportCommand = new RelayCommand(() => Export(), () => CurrentProfile != null);
            ImportToTimeLinerCommand = new RelayCommand(() => ImportToTimeLiner(), () => CurrentProfile != null);
            InsertEventCommand = new RelayCommand(() => InsertEvent(), () => CurrentProfile != null && _currentRoute != null);
            DeleteEventCommand = new RelayCommand(() => DeleteEvent(), () => SelectedEvent != null);

            RefreshProfiles();
        }

        private void RefreshProfiles()
        {
            if (_currentRoute == null) return;

            Profiles.Clear();
            var profiles = _timeTagService.GetProfiles(_currentRoute.Id);
            foreach (var profile in profiles)
            {
                Profiles.Add(profile);
            }

            if (Profiles.Count > 0 && string.IsNullOrEmpty(SelectedProfileId))
            {
                SelectedProfileId = Profiles[0].Id;
            }
        }

        private void LoadProfile(string profileId)
        {
            if (string.IsNullOrEmpty(profileId))
            {
                CurrentProfile = null;
                return;
            }

            var profile = Profiles.FirstOrDefault(p => p.Id == profileId);
            
            // 从数据库加载后需要重新计算时间
            if (profile != null && _currentRoute != null)
            {
                _timeTagService.UpdateProfile(profile, _currentRoute);
            }
            
            CurrentProfile = profile;
        }

        private void RefreshEvents()
        {
            Events.Clear();
            if (CurrentProfile?.Events != null)
            {
                foreach (var evt in CurrentProfile.Events.OrderBy(e => e.Distance))
                {
                    Events.Add(evt);
                }
            }
            OnPropertyChanged(nameof(TotalTimeText));
        }

        private void CreateProfile()
        {
            if (_currentRoute == null) return;

            string profileName = $"配置 {Profiles.Count + 1}";
            var newProfile = _timeTagService.CreateProfile(_currentRoute.Id, profileName, _currentRoute);
            
            Profiles.Add(newProfile);
            SelectedProfileId = newProfile.Id;
        }

        private void DeleteProfile()
        {
            if (CurrentProfile == null) return;

            var result = System.Windows.MessageBox.Show(
                $"确定要删除配置 \"{CurrentProfile.Name}\" 吗？",
                "确认删除",
                System.Windows.MessageBoxButton.YesNo,
                System.Windows.MessageBoxImage.Question);

            if (result != System.Windows.MessageBoxResult.Yes) return;

            _timeTagService.DeleteProfile(CurrentProfile.Id);
            Profiles.Remove(CurrentProfile);
            
            if (Profiles.Count > 0)
            {
                SelectedProfileId = Profiles[0].Id;
            }
            else
            {
                SelectedProfileId = null;
            }
        }

        #region 事件操作

        /// <summary>
        /// 插入新事件
        /// 如果有选中事件，在选中事件后插入；否则在末尾插入
        /// 不能插入在终点之后
        /// </summary>
        private void InsertEvent()
        {
            if (CurrentProfile == null || _currentRoute == null) return;

            double distance;
            int insertIndex;

            if (SelectedEvent != null)
            {
                // 在选中事件后插入
                var currentIndex = Events.IndexOf(SelectedEvent);
                
                // 检查是否选中了终点，不能在终点后插入
                if (SelectedEvent.Type == EventType.End || currentIndex >= Events.Count - 1)
                {
                    System.Windows.MessageBox.Show("不能在终点之后插入事件", "提示", 
                        System.Windows.MessageBoxButton.OK, 
                        System.Windows.MessageBoxImage.Information);
                    return;
                }

                distance = SelectedEvent.Distance + 5;
                insertIndex = currentIndex + 1;
                
                // 确保不超过下一点
                var nextEvent = Events[currentIndex + 1];
                if (nextEvent != null)
                {
                    // 取中间位置，但至少留1米间距
                    distance = Math.Min(distance, (SelectedEvent.Distance + nextEvent.Distance) / 2);
                    distance = Math.Max(distance, SelectedEvent.Distance + 1);
                }
            }
            else
            {
                // 没有选中事件，在起点后插入（默认位置）
                if (Events.Count >= 2)
                {
                    var firstEvent = Events[0];
                    var secondEvent = Events[1];
                    distance = (firstEvent.Distance + secondEvent.Distance) / 2;
                    insertIndex = 1;
                }
                else
                {
                    distance = _currentRoute.TotalLength / 2;
                    insertIndex = 1;
                }
            }

            // 确保不超出路径总长
            distance = Math.Min(distance, _currentRoute.TotalLength - 1);

            var newEvent = new TimeTagEvent
            {
                Id = Guid.NewGuid().ToString(),
                ProfileId = CurrentProfile.Id,
                Name = $"事件{Events.Count + 1}",
                Type = EventType.Wait,
                Distance = distance,
                WaitTime = 5,
                ActionTime = 0,
                SortOrder = insertIndex + 1
            };

            CurrentProfile.Events.Add(newEvent);
            
            // 重新排序并选中
            ReorderEventsAndRecalculate();
            SelectedEvent = newEvent;
        }

        /// <summary>
        /// 删除选中事件
        /// </summary>
        private void DeleteEvent()
        {
            if (SelectedEvent == null || CurrentProfile == null) return;

            // 不能删除起点和终点
            if (SelectedEvent.Type == EventType.Start || SelectedEvent.Type == EventType.End)
            {
                System.Windows.MessageBox.Show("不能删除起点或终点事件", "提示", 
                    System.Windows.MessageBoxButton.OK, 
                    System.Windows.MessageBoxImage.Information);
                return;
            }

            var result = System.Windows.MessageBox.Show(
                $"确定要删除事件 \"{SelectedEvent.Name}\" 吗？",
                "确认删除",
                System.Windows.MessageBoxButton.YesNo,
                System.Windows.MessageBoxImage.Question);

            if (result != System.Windows.MessageBoxResult.Yes) return;

            CurrentProfile.Events.Remove(SelectedEvent);
            Events.Remove(SelectedEvent);
            SelectedEvent = null;
            
            SaveAndRecalculate();
        }

        /// <summary>
        /// 重新排序事件并重新计算
        /// </summary>
        private void ReorderEventsAndRecalculate()
        {
            if (CurrentProfile == null) return;

            // 保存当前选中事件的ID
            var selectedEventId = SelectedEvent?.Id;

            // 按距离排序并更新SortOrder
            var sortedEvents = CurrentProfile.Events.OrderBy(e => e.Distance).ToList();
            for (int i = 0; i < sortedEvents.Count; i++)
            {
                sortedEvents[i].SortOrder = i + 1;
            }

            SaveAndRecalculate();
            RefreshEvents();
            
            // 恢复选中状态
            if (selectedEventId != null)
            {
                SelectedEvent = Events.FirstOrDefault(e => e.Id == selectedEventId);
            }
        }

        #endregion

        private void Recalculate()
        {
            if (CurrentProfile == null || _currentRoute == null) return;

            _timeTagService.UpdateProfile(CurrentProfile, _currentRoute);
            OnPropertyChanged(nameof(TotalTimeText));
            
            // 刷新事件列表以更新累计时间
            var selectedId = SelectedEvent?.Id;
            RefreshEvents();
            
            if (selectedId != null)
            {
                SelectedEvent = Events.FirstOrDefault(e => e.Id == selectedId);
            }
        }

        private void SaveAndRecalculate()
        {
            if (CurrentProfile == null) return;

            _timeTagService.UpdateProfile(CurrentProfile, _currentRoute);
            Recalculate();
        }

        private void Export()
        {
            if (CurrentProfile == null || _currentRoute == null) return;

            var dialog = new SaveFileDialog
            {
                Title = "导出时标配置",
                FileName = $"{CurrentProfile.Name}_{DateTime.Now:yyyyMMdd_HHmmss}",
                DefaultExt = ".json",
                Filter = "JSON文件 (*.json)|*.json|CSV文件 (*.csv)|*.csv|所有文件 (*.*)|*.*"
            };

            if (dialog.ShowDialog() == true)
            {
                try
                {
                    _exporter.ExportToFile(CurrentProfile, _currentRoute, dialog.FileName);
                    
                    string message = $"导出成功:\n{dialog.FileName}\n\n" +
                                   $"总时间: {CurrentProfile.TotalTime:F1} 秒\n" +
                                   $"总距离: {_currentRoute.TotalLength:F1} 米\n" +
                                   $"事件数: {CurrentProfile.Events?.Count ?? 0}";
                    
                    System.Windows.MessageBox.Show(message, "导出完成", 
                        System.Windows.MessageBoxButton.OK, 
                        System.Windows.MessageBoxImage.Information);
                    
                    LogManager.Info($"时标配置已导出: {dialog.FileName}");
                }
                catch (Exception ex)
                {
                    LogManager.Error($"导出失败: {ex.Message}");
                    System.Windows.MessageBox.Show($"导出失败: {ex.Message}", "错误",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                }
            }
        }

        /// <summary>
        /// 导入到 TimeLiner
        /// </summary>
        private void ImportToTimeLiner()
        {
            if (CurrentProfile == null || _currentRoute == null) return;

            // 检查 TimeLiner 是否可用
            if (!_timeLinerIntegration.IsTimeLinerAvailable)
            {
                System.Windows.MessageBox.Show(
                    "TimeLiner 不可用。请确保 Navisworks TimeLiner 插件已加载。",
                    "TimeLiner 不可用",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Warning);
                return;
            }

            // 获取当前选中的模型元素（可选）
            var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
            var selectedItems = doc?.CurrentSelection?.SelectedItems;
            ModelItem movingObject = null;
            if (selectedItems != null && selectedItems.Count > 0)
            {
                movingObject = selectedItems.First();
            }

            var result = System.Windows.MessageBox.Show(
                movingObject != null 
                    ? $"将时标配置 \"{CurrentProfile.Name}\" 导入到 TimeLiner 吗？\n\n已选中物体: {movingObject.DisplayName}\n总时间: {CurrentProfile.TotalTime:F1}秒\n事件数: {CurrentProfile.Events?.Count ?? 0}"
                    : $"将时标配置 \"{CurrentProfile.Name}\" 导入到 TimeLiner 吗？\n\n未选中运输物体，将创建信息任务（无动画）。\n总时间: {CurrentProfile.TotalTime:F1}秒\n事件数: {CurrentProfile.Events?.Count ?? 0}",
                "导入到 TimeLiner",
                System.Windows.MessageBoxButton.YesNo,
                System.Windows.MessageBoxImage.Question);

            if (result != System.Windows.MessageBoxResult.Yes) return;

            try
            {
                bool success = _timeLinerIntegration.ImportToTimeLiner(CurrentProfile, _currentRoute, movingObject);
                
                if (success)
                {
                    System.Windows.MessageBox.Show(
                        "时标配置已成功导入到 TimeLiner！\n\n请在 Navisworks 的 TimeLiner 窗口中查看任务。",
                        "导入成功",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Information);
                }
                else
                {
                    System.Windows.MessageBox.Show(
                        "导入失败，请查看日志了解详情。",
                        "导入失败",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"导入 TimeLiner 失败: {ex.Message}");
                System.Windows.MessageBox.Show($"导入失败: {ex.Message}", "错误",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
            }
        }

        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }
}
