using FISLib.Connect;
using FISLib.Test;
using System;
using Vinno.FIS.Sonopost.Features.Network;
using Vinno.FIS.Sonopost.Managers.Interfaces;
using Vinno.FIS.Sonopost.Settings;
using Vinno.IUS.Common.Log;
using Vinno.IUS.Common.Utilities;
using JsonHelper = Vinno.FIS.Sonopost.Helpers.JsonHelper;

namespace Vinno.FIS.Sonopost.Managers
{
    internal class TestManager : SonopostManager, ITestManager
    {
        private readonly ILoginManager _loginManager;
        private readonly ITestService _fisTestService;
        private readonly IConfigManager _configManager;

        public ServerNetworkCheckProgress CurrentProgress { get; private set; }

        public bool IsRunning { get; private set; }

        public TestManager()
        {
            _configManager = AppManager.Instance.GetManager<IConfigManager>();
            _loginManager = AppManager.Instance.GetManager<ILoginManager>();
            _fisTestService = AppManager.Instance.GetManager<IFISManager>().FISTestService;
            _fisTestService.TestStatusChanged += OnTestStatusChanged;
            _fisTestService.TestFinished += OnTestFinished;
        }

        public void Run()
        {
            Logger.WriteLineInfo($"Test Manager Run Invoke");
            CurrentProgress = new ServerNetworkCheckProgress();
            CurrentProgress.Network.Status = ServerNetworkCheckStatus.Handling;
            var ultrasoundMachineInfo = AppManager.Instance.GetManager<IFISManager>().UltrasoundMachineInfo;
            _fisTestService.CreateVCloudService(_configManager.VCloudServerAddress, _configManager.VCloudServerPort, ultrasoundMachineInfo.USSoftwareVersion, null, ultrasoundMachineInfo.USScreenWidth, ultrasoundMachineInfo.USScreenHeight, ultrasoundMachineInfo.DeviceType);
            var userName = DesBuilder.Decrypt(SonopostUserDefinedSettings.Instance.ServerSetting.UserName);
            _fisTestService.Excute(true, true, _loginManager.DeviceStatus == DeviceStatus.Logon ? userName : null);
            IsRunning = true;
        }

        public void Stop()
        {
            Logger.WriteLineInfo($"Test Manager Stop Invoke");
            _fisTestService.StopTest();
            _fisTestService.CloseVCloudService();
            IsRunning = false;
        }

        private void OnTestStatusChanged(object sender, FISVCloudServiceTestResult e)
        {
            Logger.WriteLineInfo($"Test Manager OnTestStatusChanged :{JsonHelper.ToJson(e)}");
            if (e.TestItemId.Equals(CurrentProgress.Network.Key))
            {
                HandleEachStep(e, CurrentProgress.Network);
            }
            else if (e.TestItemId.Equals(CurrentProgress.CloudServer.Key))
            {
                HandleEachStep(e, CurrentProgress.CloudServer);
            }
            else if (e.TestItemId.Equals(CurrentProgress.RemedicalService.Key))
            {
                HandleEachStep(e, CurrentProgress.RemedicalService);
            }
            else if (e.TestItemId.Equals(CurrentProgress.LiveServer.Key))
            {
                HandleEachStep(e, CurrentProgress.LiveServer);
            }
        }

        private void HandleEachStep(FISVCloudServiceTestResult e, ServerNetworkCheckStep current)
        {
            if (FISVCloudTestItemStatus.TestDone == e.Status)
            {
                current.Status = ServerNetworkCheckStatus.Success;
            }
            else if (FISVCloudTestItemStatus.TestBeginned == e.Status)
            {
                current.Status = ServerNetworkCheckStatus.Handling;
            }
            else
            {
                current.Status = ServerNetworkCheckStatus.Fail;
                current.ErrorMessage = e.ErrorMessage;
            }
        }

        private void OnTestFinished(object sender, EventArgs e)
        {
            Logger.WriteLineInfo($"Test Manager OnTestFinished ");
            _fisTestService.CloseVCloudService();
            IsRunning = false;
        }

        public override void DoDispose()
        {
            try
            {
                _fisTestService.TestStatusChanged -= OnTestStatusChanged;
                _fisTestService.TestFinished -= OnTestFinished;
            }
            catch (Exception ex)
            {
                Logger.WriteLineError($"TestManager DoDispose Error:{ex}");
            }
            base.DoDispose();
        }
    }
}