using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Net.Http;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.JSInterop;

using CommonHelpers.WASM;
using AFXUI;

using BookRegistry.Client.Shared;
using BookRegistry.Client.Components;
using BookRegistry.Client.DB;

namespace BookRegistry.Client.Pages {

//**************************************************************************************************
public partial class FetchDataPage: APageComponent {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Disposable accessor to "WeatherForecastService" instance —
// the only kind of service used by this page (and only by this page):
WeatherForecastService SRV => _WeatherForecastService_ ?? throw ServiceInstanceDisposedError;
WeatherForecastService? _WeatherForecastService_;
//==================================================================================================
//protected ElementReference?;
#nullable disable
protected AButton GetDataButton;
protected ACheckBox WithTestDelayCBox,SimulateErrorCBox;
#nullable restore
//==================================================================================================
static ObjectDisposedException ServiceInstanceDisposedError =>
   throw new ObjectDisposedException(
      $"Attempt to access \"{nameof(WeatherForecastService)}\"-instance, "+
      $"which has allready been disposed." );
//--------------------------------------------------------------------------------------------------

protected List<ForecastSummary_Item>? Summaries;
protected string? PageErrorMessage;

//==================================================================================================

static string NonBlockingPauseTooltip =>
   "WeatherForecast-controller (action “GetForecast”) will perform non-blocking delay:\n"+
   "“await Task.Delay(3000)” (in C#).";
static string StoredProcBehaviourTooltip =>
   "Stored procedure [BKRG::GetWeatherForecastSummaries] will return corresponding error "+
   "message dependent on client language (EN/RU), with artificial error status (GUID).";

//==================================================================================================

protected override void OnDispose()
{
   // Eliminating reference to service instance:
   _WeatherForecastService_ = null;
   App.OnKeyDown -= Window_OnKeyDown;
   base.OnDispose();
}

//==================================================================================================

protected override void OnInitialized() =>
go(()=>{
   base.OnInitialized();
   _WeatherForecastService_ = GetService<WeatherForecastService>();
   App.OnKeyDown += Window_OnKeyDown;
   UnlockOnLoad = false; // we must unlock input later (by CompletePageLoadingUnlock)
});

protected override void On_Load() =>
go(()=>{
/*
// Loading error test:
try {
   throw new ApplicationException( "Test error #1 has been thrown." );
}
catch (Exception e) {
   throw new ApplicationException( "Test error #2 has been thrown.", e );
}
*/
   WeatherForecastMI.ApplyToUI();
   Page_Prepare();
});

protected override Task On_AfterLoad_A() =>
go(async()=>{
   await ObtainData_A(-1);
   // exclusive-master (it is required when explicit exclusive lock is set globally)
});

//==================================================================================================

Task GetDataButton_OnClick_A() =>
go(async()=>{ // non-exclusive guard
   UPage.ClearSelection();
   await ObtainData_A(); // awaiting exclusive method
});

void CheckBox_OnClick() =>
GO(()=>{ // exclusive guard
   GetDataButton.Focus();
});

void Window_OnKeyDown(KeyboardEventArgs e) =>
go(()=>{ // non-exclusive guard
   if ( UInput.IsPureKey( e, "F9" ) && GetDataButton.IsEnabled )
      GetDataButton.Click();
});

Task ObtainData_A(int exclusive=1) =>
Do_A(exclusive,async()=>{using (ForeOperation.WithSaveFocus(GetDataButton)){ // explicit focusing
//-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   if ( exclusive == -1 )
      CompletePageLoadingUnlock(); // this will reset explicit exclusive lock (global flag)
   // Requesting weather forcast for one week (7 day summaries) starting from tomorrow:
   var args = new GetWeatherForecast_Args() {
      DateFrom = DateTime.Now + new TimeSpan(1,0,0,0), // plus 1 day to current time
      WithTestDelay = WithTestDelayCBox.Value,
      SimulateError = SimulateErrorCBox.Value
   };
   // Service call returns ServiceInvocationResult ( Response + Exception ):
   var sir = await SRV.ESC_GetForecast_A( args ); // this may throw UEscapeException
   if ( WasAbandoned_Notify_Deactivate( sir ) ) // this may throw UEscapeException
   {
   // Normal abandoment message is allready saved in busy-indicator tooltip of magistral layout.
      PageErrorMessage = "Forecast query was abandoned (cancelled by used).";
      goto RESET_DATA;
   }
   if ( await ESC_HasRequestError_ShowError_A( sir ) ) // this may throw UEscapeException
   {
   // The error is allready saved in busy-indicator tooltip of magistral layout.
      PageErrorMessage =
         "Forecast query has failed.\n"+
         "Error message is saved in busy-indicator tooltip (in top-right).";
      // Checking Web-server API error (status-code GUID from SQL stored-proc. or C#-controller)
      if ( sir.HasResponse && sir.ResponseNN.HasStatusCode ) // response here is definitely not null
      {
         var status = sir.ResponseNN.Status; // status-GUID of not-null API-response
         PageErrorMessage += string.Format( "\nStatus-code: {0}{1}", HGuid.Format( status ),
            status==SPCommonStatuses.ArtificialError ? // detecting: is artificial error?
               " (recognized as artificial DB-error)." : "" );
      }
      goto RESET_DATA;
   }
   Summaries = sir.ResponseNN.Items;
   PageErrorMessage =null;
   return;
RESET_DATA:
   Summaries = null;
//-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}});

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // FetchDataPage
//**************************************************************************************************

} // BookRegistry.Client.Pages
