using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using TodoList.Models;
using TodoList.Services;

namespace TodoList.ViewModels
{
    public partial class MainViewModel : ObservableObject, IRecipient<TaskAddedMessage>
    {
        private readonly IDataService _dataService;
        private readonly SettingsService _settingsService;

        [ObservableProperty]
        private ObservableCollection<TodoItem> tasks = new();

        [ObservableProperty]
        private bool showCompleted = false;

        [ObservableProperty]
        private string newContent;

        [ObservableProperty]
        private TodoPriority newPriority = TodoPriority.Medium;

        [ObservableProperty]
        private bool isEditDialogOpen;

        [ObservableProperty]
        private TodoItem editingTask;

        [ObservableProperty]
        private string editContent;

        [ObservableProperty]
        private TodoPriority editPriority = TodoPriority.Medium;
        
        [ObservableProperty]
        private bool isSettingsOpen;

        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(FullShortcut))]
        private string shortcutKey;

        [ObservableProperty]
        [NotifyPropertyChangedFor(nameof(FullShortcut))]
        private string shortcutModifiers;

        [ObservableProperty]
        private SortBy sortBy = SortBy.Priority;

        [ObservableProperty]
        private Models.SortOrder sortOrder = Models.SortOrder.Descending;

        public string FullShortcut
        {
            get
            {
                var mods = ShortcutModifiers?.Replace(",", " + ");
                return string.IsNullOrEmpty(mods) ? ShortcutKey : $"{mods} + {ShortcutKey}";
            }
        }

        public MainViewModel(IDataService dataService, SettingsService settingsService)
        {
            _dataService = dataService;
            _settingsService = settingsService;
            ShortcutKey = _settingsService.Settings.ShortcutKey;
            ShortcutModifiers = _settingsService.Settings.ShortcutModifiers;

            WeakReferenceMessenger.Default.Register(this);
            LoadTasksCommand.Execute(null);
        }

        [RelayCommand]
        private void OpenSettings()
        {
            IsSettingsOpen = true;
            ShortcutKey = _settingsService.Settings.ShortcutKey;
            ShortcutModifiers = _settingsService.Settings.ShortcutModifiers;
        }

        [RelayCommand]
        private void CloseSettings()
        {
            IsSettingsOpen = false;
        }

        [RelayCommand]
        private void SaveSettings()
        {
            if (!string.IsNullOrWhiteSpace(ShortcutKey))
            {
                _settingsService.Settings.ShortcutKey = ShortcutKey.ToUpper();
                _settingsService.Settings.ShortcutModifiers = ShortcutModifiers;
                _settingsService.SaveSettings();
            }
            IsSettingsOpen = false;
        }

        async partial void OnShowCompletedChanged(bool value)
        {
            await LoadTasksAsync();
        }

        async partial void OnSortByChanged(SortBy value)
        {
            await LoadTasksAsync();
        }

        async partial void OnSortOrderChanged(Models.SortOrder value)
        {
            await LoadTasksAsync();
        }

        [RelayCommand]
        private async Task AddTaskAsync()
        {
            if (string.IsNullOrWhiteSpace(NewContent)) return;

            var newTask = new TodoItem
            {
                Content = NewContent,
                Priority = NewPriority,
                IsCompleted = false,
                SyncStatus = SyncStatus.Pending
            };

            await _dataService.SaveTaskAsync(newTask);
            NewContent = string.Empty;
            NewPriority = TodoPriority.Medium;
            await LoadTasksAsync();
        }

        [RelayCommand]
        private async Task LoadTasksAsync()
        {
            var allTasks = await _dataService.LoadTasksAsync();
            
            var filtered = ShowCompleted 
                ? allTasks 
                : allTasks.Where(t => !t.IsCompleted).ToList();

            IOrderedEnumerable<TodoItem> sorted;
            
            if (SortBy == SortBy.Priority)
            {
                sorted = SortOrder == Models.SortOrder.Ascending 
                    ? filtered.OrderBy(t => t.Priority).ThenBy(t => t.CreatedAt)
                    : filtered.OrderByDescending(t => t.Priority).ThenBy(t => t.CreatedAt);
            }
            else if (SortBy == SortBy.CreatedAt)
            {
                sorted = SortOrder == Models.SortOrder.Ascending 
                    ? filtered.OrderBy(t => t.CreatedAt)
                    : filtered.OrderByDescending(t => t.CreatedAt);
            }
            else
            {
                sorted = SortOrder == Models.SortOrder.Ascending 
                    ? filtered.OrderBy(t => t.CompletedAt).ThenBy(t => t.CreatedAt)
                    : filtered.OrderByDescending(t => t.CompletedAt).ThenBy(t => t.CreatedAt);
            }

            Tasks.Clear();
            foreach (var t in sorted)
            {
                Tasks.Add(t);
            }
        }

        [RelayCommand]
        private async Task ToggleCompleteAsync(TodoItem item)
        {
            if (item == null) return;
            
            if (item.IsCompleted)
            {
                item.CompletedAt = DateTime.Now;
            }
            else
            {
                item.CompletedAt = null;
            }
            
            item.SyncStatus = SyncStatus.Pending;
            await _dataService.SaveTaskAsync(item);
            await LoadTasksAsync();
        }

        [RelayCommand]
        private async Task DeleteAsync(TodoItem item)
        {
            if (item == null) return;
            await _dataService.DeleteTaskAsync(item.Id);
            Tasks.Remove(item);
        }

        [RelayCommand]
        private void OpenEditDialog(TodoItem item)
        {
            if (item == null) return;
            EditingTask = item;
            EditContent = item.Content;
            EditPriority = item.Priority;
            IsEditDialogOpen = true;
        }

        [RelayCommand]
        private void CloseEditDialog()
        {
            IsEditDialogOpen = false;
            EditingTask = null;
            EditContent = string.Empty;
            EditPriority = TodoPriority.Medium;
        }

        [RelayCommand]
        private async Task SaveEditAsync()
        {
            if (EditingTask == null || string.IsNullOrWhiteSpace(EditContent)) return;

            EditingTask.Content = EditContent;
            EditingTask.Priority = EditPriority;
            EditingTask.SyncStatus = SyncStatus.Pending;

            await _dataService.SaveTaskAsync(EditingTask);
            await LoadTasksAsync();
            CloseEditDialog();
        }

        public async void Receive(TaskAddedMessage message)
        {
            await LoadTasksAsync();
        }
    }

    public class TaskAddedMessage
    {
    }
}
