using System;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.AspNetCore.Components;

using CommonHelpers.WASM;
using AFXUI;

namespace BookRegistry.Client {

//**************************************************************************************************
public abstract partial class XServiceBase {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected static HttpClient HTTP => Services.HttpClient;
//==================================================================================================

public string? ServiceBaseName { get; protected set; }

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

/// <exception cref="HUnsuccessException" />
protected XServiceBase()
{
   var typeName = GetType().Name;
   var serviceNameSuffix = "Service";
   int nameSuffixLen = serviceNameSuffix.Length;
   if (!( typeName.EndsWith( serviceNameSuffix ) && typeName.Length > nameSuffixLen ))
      throw HUnsuccessExceptionCreator.Create(
         "Incorrect service-type name: \"{0}\".",
         typeName );
   ServiceBaseName = typeName.Remove( typeName.Length - nameSuffixLen );
}

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

/// <exception cref="ArgumentNullException" />
protected string AddressOf([HRequired] string? methodName) =>
   AddressOf( true, methodName );

/// <exception cref="ArgumentNullException" />
protected string AddressOf(bool alterActionName,[HRequired] string? methodName)
{
   methodName = HArgChecking.NN( methodName );
   string actionName = methodName;
   if ( alterActionName )
   {
      int len = methodName.Length;
      actionName =
         methodName.EndsWith( "_A" ) ? methodName.Remove( len-2 ) :
         methodName.EndsWith( "Async" ) ? methodName.Remove( len-5 ) :
         methodName;
      if ( methodName.StartsWith( "ESC_" ) )
         actionName = actionName.Substring( 4 );
   }
   if ( HString.IsBlank( actionName ) )
      throw new ArgumentException(
         "Empty or invalid action name for server call.",
         nameof( methodName ) );
   return ServiceBaseName != null ?
      $"{ServiceBaseName}/{actionName}":
      actionName;
}

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

/// <exception cref="InvalidOperationException" />
protected void SetOperationText(string operationText) =>
   SetOperationText( true, operationText );
/// <exception cref="InvalidOperationException" />
protected void SetOperationText(string operationTextFmt,params object?[] parameters) =>
   SetOperationText( true, operationTextFmt, parameters );

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidOperationException" />
protected void SetOperationTextAuto([HRequired][CallerMemberName] string? methodName=null) =>
   SetOperationTextAuto( true, HArgChecking.NN( methodName ) );

//--------------------------------------------------------------------------------------------------

/// <exception cref="InvalidOperationException" />
protected void SetOperationText( bool allowCancellation, string operationText ) =>
   ForeOperation.SetText( allowCancellation, operationText );
/// <exception cref="InvalidOperationException" />
protected void SetOperationText( bool allowCancellation,
                                 string operationTextFmt, params object?[] parameters ) =>
   ForeOperation.SetText( allowCancellation, operationTextFmt, parameters );

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidOperationException" />
protected void SetOperationTextAuto( bool allowCancellation,
                                     [HRequired][CallerMemberName] string? methodName=null ) =>
   ForeOperation.SetText( allowCancellation, AddressOf( HArgChecking.NN( methodName ) ) );

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

protected void AssignAuthorizationHeader(GeneratedToken_Info token) =>
   HTTP.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
      "bearer", token.EncodedJwt );

protected void ResetAuthorizationHeader() =>
   HTTP.DefaultRequestHeaders.Authorization = null;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // XServiceBase
//**************************************************************************************************

} // BookRegistry.Client
