using System;
using System.Reactive;
using ReactiveUI;

namespace detect.gui.ViewModels;

public class PageModelBase : ReactiveObject
{
    /// <summary>
    /// 每页大小
    /// </summary>
    private int _pageSize = 10;

    public int PageSize
    {
        get => _pageSize;
        set => this.RaiseAndSetIfChanged(ref _pageSize, value);
    }

    /// <summary>
    /// 当前页号
    /// </summary>
    private int _pageNum = 1;

    public int PageNum
    {
        get => _pageNum;
        set => this.RaiseAndSetIfChanged(ref _pageNum, value);
    }

    /// <summary>
    /// 总页数
    /// </summary>
    private int _pageCount;

    public int PageCount
    {
        get => _pageCount;
        set => this.RaiseAndSetIfChanged(ref _pageCount, value);
    }

    /// <summary>
    /// 总记录数
    /// </summary>
    private int _recordCount;

    public int RecordCount
    {
        get => _recordCount;
        set => this.RaiseAndSetIfChanged(ref _recordCount, value);
    }

    /// <summary>
    /// 开始序号
    /// </summary>
    private int _startIndex;

    public int StartIndex
    {
        get => _startIndex;
        set => this.RaiseAndSetIfChanged(ref _startIndex, value);
    }

    /// <summary>
    /// 结束序号
    /// </summary>
    private int _endIndex;

    public int EndIndex
    {
        get => _endIndex;
        set => this.RaiseAndSetIfChanged(ref _endIndex, value);
    }

    public bool CanFirst => PageNum != 1 && PageCount > 1;
    public bool CanLeft => PageNum != 1 && PageCount > 1;
    public bool CanRight => PageNum != PageCount && PageCount > 1;
    public bool CanLast => PageNum != PageCount && PageCount > 1;

    protected PageModelBase()
    {
        FirstCommand = ReactiveCommand.Create(()=> GoPage("first"));
        LeftCommand = ReactiveCommand.Create(()=> GoPage("left"));
        RightCommand = ReactiveCommand.Create(()=> GoPage("right"));
        LastCommand = ReactiveCommand.Create(()=> GoPage("last"));
        
        this.WhenAnyValue(x => x.PageNum, x => x.PageCount)
            .Subscribe(v =>
            {
                this.RaisePropertyChanged(nameof(CanFirst));
                this.RaisePropertyChanged(nameof(CanLeft));
                this.RaisePropertyChanged(nameof(CanRight));
                this.RaisePropertyChanged(nameof(CanLast));
            });
    }
    
    public ReactiveCommand<Unit, Unit>? FirstCommand { get; set; }
    public ReactiveCommand<Unit, Unit>? LeftCommand { get; set; }
    public ReactiveCommand<Unit, Unit>? RightCommand { get; set; }
    public ReactiveCommand<Unit, Unit>? LastCommand { get; set; }
    
    private void GoPage(string action)
    {
        switch (action)
        {
            case "first":
                FirstPage();
                break;
            case "left":
                LeftPage();
                break;
            case "right":
                RightPage();
                break;
            case "last":
                LastPage();
                break;
        }
    }

    public void FirstPage()
    {
        PageNum = 1;
        DoSearch?.Invoke(false);
    }

    private void LeftPage()
    {
        PageNum--;
        if (PageNum == 0) PageNum = 1;
        DoSearch?.Invoke(false);
    }

    private void RightPage()
    {
        PageNum++;
        if (PageNum > PageCount) PageNum = PageCount;
        DoSearch?.Invoke(false);
    }

    private void LastPage()
    {
        PageNum = PageCount;
        DoSearch?.Invoke(false);
    }

    public Func<bool, bool>? DoSearch { get; set; }
}