using System;
using System.Reflection;
using System.Collections.Generic;
#if WASM
   using CommonHelpers.WASM;
namespace BookRegistry.Client.DB {
#else // !WASM:
   using System.Threading.Tasks;
   using CommonHelpers;
namespace BookRegistry.Server.DB {
#endif // !WASM

//**************************************************************************************************
/// <summary>
///  (stored procedure)
/// </summary>
public static class _SP {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
public static readonly Guid
   //Status_ = SPCommonStatuses.,
   //Status_ = new Guid( "" ),
*/
#if SERVER
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public const string Name = "BKRG::";
public static HSPResultOut_2<_Output,_Item,_Item>
   InvalidResult => new HSPResultOut_2<_Output,_Item,_Item>();
//==================================================================================================

public static async Task<(HSPResultOut_2<_Output,_Item,_Item>)> EXEC_A( ... )
{
   var p = new TParameters();
   return await HSPPerformer.Do_A<_Item>(Name,async delegate{
      var ( rp, cmd ) = HSP.PrepareCommand( p.X1, p.X2, p.X3, ... );
      List<_Item>? list_1 = null;
      List<_Item>? list_2 = null;
      HSP.SetParametersDescriptor( p );
      using (var rdr = await HSPCommandDispose.ExecuteReader_A( cmd ))
      if ( HSP.Success( rp ) )
      {
         list_1 = await HSP.RSetToList_A<_Item>( 1, rdr );
/*
         if ( list_1.Count != 1 )
            throw HDBExceptionsSPAuto.ExactlyOneRecordWasExpectedIn1stRSet;
*/
         if ( !rdr.NextResult() )
            throw HDBExceptionsSPAuto.SecondResultSetWasExpected;
         list_2 = await HSP.RSetToList_A<_Item>( 2, rdr );
/*
         if ( list_2.Count != 1 )
            throw HDBExceptionsSPAuto.ExactlyOneRecordWasExpectedIn2ndRSet;
*/
      }
      var output = HSP.Success( rp ) ? new _Output() : null;
      return new HSPResultOut_2<_Output,_Item,_Item>( rp, output, list_1, list_2 );
   });
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
internal class TParameters
{
   public readonly SqlParameter
       = HSqlParam.Out( "", SqlDbType. ),
       = HSqlParam.NullableOut( "", SqlDbType. ),
} // TParameters
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#endif // SERVER
} // _SP
//**************************************************************************************************

/// <summary>
/// Output values
/// </summary>
public class _Output: SPOutputBase
{
   public   {
      get => Get( N );
      set => N = value; } internal ? N = _ACCESSOR( P. );

   public   {
      get => Value( N );
      set => N = value; } internal ? N = _ACCESSOR( P. );

   public ?  = ACCESSOR_N( P. );

   static _SP.TParameters P => (_SP.TParameters)HSP.ParametersDescriptor;
} // _Output

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

/// <summary>
/// Result set #1 (model)
/// </summary>
public class _Item: ResultSetItemBase
{
   public   {
      get => Get( N );
      set => N = value; } internal ? N = _ACCESSOR();

   public   {
      get => Value( N );
      set => N = value; } internal ? N = _ACCESSOR();

   public ?  { get; set; } = ACCESSOR_N();

   public _Item _Duplicate() =>
      (_Item)MemberwiseClone();
} // _Item

/// <summary>
/// Result set #2 (model)
/// </summary>
public class _Item: ResultSetItemBase
{
   public   {
      get => Get( N );
      set => N = value; } internal ? N = _ACCESSOR();

   public   {
      get => Value( N );
      set => N = value; } internal ? N = _ACCESSOR();

   public ?  { get; set; } = ACCESSOR_N();

   public _Item _Duplicate() =>
      (_Item)MemberwiseClone();
} // _Item

//==================================================================================================
} // BookRegistry.Client/Server.DB
