using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;

using CommonHelpers;

namespace MyFlat {

//**************************************************************************************************
/// <summary>
/// Common structure for API-response with item collection (generic), message and status
/// </summary>
public partial class GeneralApiResponse<TItem>: GeneralApiResponse {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// public bool Success { get; set; }
// public bool HasError => !Success;
// public string? Message { get; set; }
// [HOptionalValue] public Guid Status { get; set; }
// public static string UndefinedMessage_SuccessfulCompletion;
// public static string UndefinedErrorMessage;

[JsonIgnore]
public bool HasItems => _Items_ != null;

/// <exception cref="InvalidOperationException" />
[JsonIgnore]
public List<TItem>? Items {
   get {
      if ( !Success )
         throw new InvalidOperationException(
            "\"Items\"-property is not accessible for operation, which has completed "+
            "with failure (\"GeneralApiResponse<TItem>\")." );
      return _Items_;
   }
   protected set => _Items_ = value;
}

/// <exception cref="InvalidOperationException" />
[JsonIgnore][HStrictResult]
public List<TItem> ItemsNN =>
   Items ?? throw new InvalidOperationException(
      "\"ItemsNN\"-property is unavailable, because request has not returned items "+
      "(\"GeneralApiResponse<TItem>\")." );

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

internal GeneralApiResponse() {}

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

internal GeneralApiResponse(string errorMessage)
: base( errorMessage )
{}
/// <exception cref="ArgumentException" />
internal GeneralApiResponse([HRequired] Guid status)
: base( status )
{}
/// <exception cref="ArgumentException" />
internal GeneralApiResponse([HRelOpt] string? errorMessage,[HRelOpt] Guid status)
: base( errorMessage, status )
{}

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

internal GeneralApiResponse(Exception e)
: base( e )
{}

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

internal GeneralApiResponse(bool success)
: base( success )
{}
internal GeneralApiResponse(bool success,string? message)
: base( success, message )
{}
internal GeneralApiResponse(bool success,[HOptional] Guid status)
: base( success, status )
{}
internal GeneralApiResponse(bool success,string? message,[HOptional] Guid status)
: base( success, message, status )
{}

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

internal GeneralApiResponse(GeneralApiResponse simpleResponse)
: base( simpleResponse )
{}

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

internal GeneralApiResponse(List<TItem>? list)
: this( list!=null, list )
{}
internal GeneralApiResponse(List<TItem>? list,string? message)
: this( list!=null, list, message )
{}
internal GeneralApiResponse(List<TItem>? list,[HOptional] Guid status)
: this( list!=null, list, status )
{}
internal GeneralApiResponse(List<TItem>? list,string? message,[HOptional] Guid status)
: this( list!=null, list, message, status )
{}

internal GeneralApiResponse(IEnumerable<TItem>? items)
: this( items!=null, items )
{}
internal GeneralApiResponse(IEnumerable<TItem>? items,string? message)
: this( items!=null, items, message )
{}
internal GeneralApiResponse(IEnumerable<TItem>? items,[HOptional] Guid status)
: this( items!=null, items, status )
{}
internal GeneralApiResponse(IEnumerable<TItem>? items,string? message,[HOptional] Guid status)
: this( items!=null, items, message, status )
{}

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

internal GeneralApiResponse(bool success,List<TItem>? list)
: base( success ) => _Items_ = list;

internal GeneralApiResponse(bool success,List<TItem>? list,string? message)
: base( success, message ) => _Items_ = list;

internal GeneralApiResponse(bool success,List<TItem>? list,[HOptional] Guid status)
: base( success, status ) => _Items_ = list;

internal GeneralApiResponse( bool success, List<TItem>? list,
                             string? message, [HOptional] Guid status )
: base( success, message, status ) => _Items_ = list;

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

internal GeneralApiResponse(bool success,IEnumerable<TItem>? items)
: base( success )
{
   if ( items != null )
      _Items_ = new List<TItem>( items );
}
internal GeneralApiResponse(bool success,IEnumerable<TItem>? items,string? message)
: base( success, message )
{
   if ( items != null )
      _Items_ = new List<TItem>( items );
}
internal GeneralApiResponse(bool success,IEnumerable<TItem>? items,[HOptional] Guid status)
: base( success, status )
{
   if ( items != null )
      _Items_ = new List<TItem>( items );
}
internal GeneralApiResponse( bool success, IEnumerable<TItem>? items,
                             string? message, [HOptional] Guid status )
: base( success, message, status )
{
   if ( items != null )
      _Items_ = new List<TItem>( items );
}

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

/// <exception cref="InvalidOperationException" />
public static new GeneralApiResponse<TItem> CreateServerError(string errorMessage) =>
   new GeneralApiResponse<TItem>( errorMessage ){
      SpecialCategory = SpecialCategory_ServerError };

//==================================================================================================
// JSON-serializable fields:

[JsonProperty(PropertyName="response_Items",Order=Int32.MinValue+4)]
List<TItem>? _Items_;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // GeneralApiResponse<TItem>
//**************************************************************************************************

} // MyFlat
