using MwFramework.Controls.Components;
using Stylet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace MainShell.Resources.CustomControl
{
    public class LoadingService : PropertyChangedBase
    {
        public static LoadingService Instance { get; } = new LoadingService();

        private bool _isBusy;
        private string _message;
        private double _progressValue;
        private bool _canCancel;
        private bool _isIndeterminate = true;
        private CancellationTokenSource _cts;

        public bool IsBusy { get => _isBusy; set => SetAndNotify(ref _isBusy, value); }
        public string Message { get => _message; set => SetAndNotify(ref _message, value); }
        public double ProgressValue { get => _progressValue; set => SetAndNotify(ref _progressValue, value); }
        public bool CanCancel { get => _canCancel; set => SetAndNotify(ref _canCancel, value); }
        public bool IsIndeterminate { get => _isIndeterminate; set => SetAndNotify(ref _isIndeterminate, value); }

        // 暴露给外部算法使用的 Token
        public CancellationToken Token => _cts?.Token ?? CancellationToken.None;

        // 取消命令
        public ICommand CancelCommand { get; }

        private LoadingService()
        {
            CancelCommand = new DelegateCommand(() => {
                _cts?.Cancel();
                Message = "正在取消...";
            });
        }

        public void Show(string message, bool isIndeterminate, bool canCancel)
        {
            _cts = new CancellationTokenSource();
            Message = message;
            IsIndeterminate = isIndeterminate;
            CanCancel = canCancel;
            ProgressValue = 0;
            IsBusy = true;
        }

        public void Hide()
        {
            IsBusy = false;
            _cts?.Dispose();
            _cts = null;
        }

        public void Report(double value) => Application.Current.Dispatcher.BeginInvoke(new Action(() =>
        {
            ProgressValue = value;
        }));
    }
}
