using System;
using Avalonia.Collections;
using System.Reactive;
using Avalonia;
using Avalonia.Media;
using detect.gui.Commons;
using detect.gui.Models;
using ReactiveUI;
using Splat;

namespace detect.gui.ViewModels;

public class RoutableViewModelBase<T> : ViewModelBase, IRoutableViewModel
{
    public string? UrlPathSegment { get; } = Guid.NewGuid().ToString();

#pragma warning disable CS8766
    public IScreen? HostScreen { get; }
#pragma warning restore CS8766

    private string? _action;
    protected string? Action
    {
        get => _action;
        set => this.RaiseAndSetIfChanged(ref _action, value);
    }

    public MainViewModel? RootViewModel => HostScreen as MainViewModel;

    /// <summary>
    /// 列表
    /// </summary>
    private AvaloniaList<T>? _items;
    public AvaloniaList<T>? Items
    {
        get => _items;
        set => this.RaiseAndSetIfChanged(ref _items, value);
    }
    
    /// <summary>
    /// 对象
    /// </summary>
    private T? _item;
    public T? Item
    {
        get => _item;
        protected set => this.RaiseAndSetIfChanged(ref _item, value);
    }
    
    public Geometry? Icon
    {
        get
        {
            object? data = null;
            if (Item?.GetValue("Id") == null)
                Application.Current?.TryGetResource("RecordAddData", null, out data);
            else    
                Application.Current?.TryGetResource("RecordEditData", null, out data);
            return data as Geometry;
        }
    }
    public string Title => Item?.GetValue("Id") == null ? "新增窗口" : "修改窗口";
    
    public bool IsEdit => Action != null && (Action.Contains("Add") || Action.Contains("Edit"));
    public bool IsDelete => Action != null && Action.Contains("Delete");
    public bool IsDebug => Action != null && Action.Contains("Debug");

    protected RoutableViewModelBase(IScreen? screen = null)
    {
        HostScreen = screen ?? Locator.Current.GetService<IScreen>();

        this.WhenAnyValue(x => x.HostScreen).Subscribe(v => { this.RaisePropertyChanged(nameof(RootViewModel)); });

        this.WhenAnyValue(x => x.IsLoading).Subscribe(v =>
        {
            if (HostScreen == null) return;
            (HostScreen as MainViewModel)!.IsLoading = v;
        });

        this.WhenAnyValue(x => x.Action).Subscribe(v =>
        {
            this.RaisePropertyChanged(nameof(IsEdit));
            this.RaisePropertyChanged(nameof(IsDelete));
            this.RaisePropertyChanged(nameof(IsDebug));
        });
        
        this.WhenAnyValue(x => x.Item).Subscribe(v =>
        {
            this.RaisePropertyChanged(nameof(Icon));
            this.RaisePropertyChanged(nameof(Title));
        });
        
        GoToCommand = ReactiveCommand.Create<object>(GoTo);
        GoBackCommand = ReactiveCommand.Create(GoBack);
        CloseCommand = ReactiveCommand.Create(Close);
    }
    
    public ReactiveCommand<object, Unit> GoToCommand { get; }
    public ReactiveCommand<Unit, Unit> GoBackCommand { get; }
    public ReactiveCommand<Unit, Unit> CloseCommand { get; }

    public void GoTo(object param)
    {
        var viewModelName = param as string;
        // if (param is TaskModel) viewModelName = "TaskViewModel";
        RootViewModel?.Goto(viewModelName!, param is string ? null : param);
    }

    protected void GoBack()
    {
        RootViewModel?.GoBack();
    }
    
    protected void Close()
    {
        Item = default;
        Action = null;
    }
}