namespace HistoryView.ViewModels;

internal partial class LoadingViewModel : ObservableObject
{
    public LoadingViewModel(IEventAggregator eventAggregator,
        LanguageLoader languageLoader,
        HubSender connector, UserInformation userInfo)
    {
        this.languageLoader = languageLoader;
        this.eventAggregator = eventAggregator;
        this.connector = connector;
        this.userInformation = userInfo;
        Task.Factory.StartNew(Init);
    }

    private readonly IEventAggregator eventAggregator;
    private readonly LanguageLoader languageLoader;
    private readonly HubSender connector;
    private readonly UserInformation userInformation;

    private async void Init()
    {
        UpdateProgerssBar(0, "Loading Base Config");

        if (!BaseConfigFileLoader.Load(out BasicInfo? basicInfo) ||
               basicInfo is null ||
               string.IsNullOrEmpty(basicInfo.DBConnectionString) ||
               string.IsNullOrEmpty(basicInfo.ServerAddress))
        {
            MessageBox.Show("Load Base Config Failed");
            return;
        }

        UpdateProgerssBar(20, "Connecting Server");

        if (!connector.Initialize(basicInfo.ServerAddress, basicInfo.ServerPort, "UIHub", 5))
        {
            MessageBox.Show("Connect to Server Failed");
            App.Current.Dispatcher.InvokeShutdown();
        }

        Thread.Sleep(500);
        UpdateProgerssBar(40, "Loading Languages");
        this.languageLoader.LoadLanguages(FilePaths.LanguageConfigFilePath);

        Thread.Sleep(500);
        UpdateProgerssBar(60, "Loading Configurations");
        await this.connector.RequestHardwares();
        Thread.Sleep(500);

        UpdateProgerssBar(80, "Loading Hareware infomations");
        await this.connector.RequestConfigFiles();
        Thread.Sleep(500);

        UpdateProgerssBar(100, "Loading settings");
        Thread.Sleep(500);

        this.userInformation.UserName = UserAuthority.Engineer.ToString();
        this.userInformation.Authority = UserAuthority.Engineer;
        eventAggregator.GetEvent<WindowSwitch>().Page = Pages.MainWindow;
        eventAggregator.GetEvent<WindowSwitch>().Publish();
    }

    [ObservableProperty]
    private string? _Hint;

    [ObservableProperty]
    private double _ProgressValue;

    private void UpdateProgerssBar(double number, string? hint = default)
    {
        Application.Current.Dispatcher.Invoke(() =>
        {
            this.ProgressValue = number;
            this.Hint = hint;
        });
    }
}
