using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;

using CommonHelpers.WASM;
using AFXUI;

using BookRegistry.Client.Shared;
using BookRegistry.Client.Pages;
using BookRegistry.Client.DB;

namespace BookRegistry.Client.Components {

//**************************************************************************************************
partial class BookCard {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

const int ReleaseYear_Min = -3000; // B.C.

bool IsInInputField =>
   BookNameEdit   .ContainsFocus ||
   ISBNEdit       .ContainsFocus ||
   ReleaseYearEdit.ContainsFocus ||
   AuthorDDL      .ContainsFocus ||
   CategoryDDL    .ContainsFocus ||
   GenreDDL       .ContainsFocus ||
   PublisherDDL   .ContainsFocus ||
   SeriesDDL      .ContainsFocus ||
   DescriptionTEXTAREA.ContainsFocus();

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

string? BookName_Validate(string text)
{
   if ( HString.StartsWithWhiteSpace( text ) )
      return "Book-name must not start from space.";
   if ( HString.ContainsDoubleWhiteSpace( text ) )
      return "Book-name must not contain double spaces.";
   if ( text.Length > DBConstants.NormalNameCapacity )
      return "Book-name is too long.";
   return null;
}
string? ISBN_Validate(string text)
{
   if ( HString.ContainsWhiteSpace( text ) )
      return "ISBN-field must not contain spaces.";
   foreach (char ch in text)
      if (!( HChar.IsDecimalDigit( ch ) || ch=='-' ))
         return "ISBN-field must consist only from decimal digits with hyphens.";
   if ( text.Length > DBConstants.NormalNameCapacity )
      return "ISBN is too long.";
   return null;
}
string? ReleaseYear_Validate(string text)
{
   if ( text == "" )
      return null;
   if ( HString.ContainsWhiteSpace( text ) )
      return "Release-year field must not contain spaces.";
   if ( !HInt32.TryParseInvariant( text, out var num ) )
      return "Release-year field must contain valid number.";
   int maxReleaseYear = DateTime.Now.Year;
   if ( !HOps.IsBetween( num, ReleaseYear_Min, maxReleaseYear ) )
      return HString.FormatAsText(
         "Release-year is unreal.\n"+
         "Valid range is: {0} (B.C.) .. {1} (current year).",
         ReleaseYear_Min, maxReleaseYear );
   return null;
}

string? AuthorId_Validate(Guid? id) =>
   id.HasValue ? null : "Book-author must be specified.";
string? CategoryId_Validate(Guid? id) =>
   id.HasValue ? null : "Book-category must be specified.";
string? GenreId_Validate(Guid? id) =>
   id.HasValue ? null : "Book-genre must be specified.";
string? PublisherId_Validate(Guid? id) =>
   id.HasValue ? null : "Book-publisher must be specified.";
string? SeriesId_Validate(Guid? id) =>
   id.HasValue ? null : "Book-series must be specified.";

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

void ValidateInput_EnableSubmission(bool forced=false)
{
   var list = new List<string>();

   PROCESS_EDIT( BookNameEdit    );
   PROCESS_EDIT( ISBNEdit        );
   PROCESS_EDIT( ReleaseYearEdit );

   PROCESS_DDL( AuthorDDL    );
   PROCESS_DDL( CategoryDDL  );
   PROCESS_DDL( GenreDDL     );
   PROCESS_DDL( PublisherDDL );
   PROCESS_DDL( SeriesDDL    );

   ErrorList.SetErrorMessages( list );
   EnableSubmission();

   void PROCESS_EDIT(AEditBox editBox)
   {
      if ( forced )
         editBox.ValidateInput();
      string? msg = editBox.ErrorMessage;
      if ( msg != null ) list.Add( msg );
   }
   void PROCESS_DDL(ADropDownList_IdName dropDownList)
   {
      if ( forced )
         dropDownList.ValidateInput();
      string? msg = dropDownList.ErrorMessage;
      if ( msg != null ) list.Add( msg );
   }
}

bool EnableSubmission()
{
   bool wasSubmissionEnabled = SubmissionEnabled;
   SubmissionEnabled = WasInputChanged && (
      BookNameEdit.HasText || ISBNEdit.HasText || ReleaseYearEdit.HasText ||
      AuthorDDL.IsSelected || CategoryDDL.IsSelected || GenreDDL.IsSelected ||
      PublisherDDL.IsSelected || SeriesDDL.IsSelected );
   if ( SubmissionEnabled != wasSubmissionEnabled )
      StateHasChanged();
   return SubmissionEnabled;
}

void SetInputChanged()
{
   if ( !WasInputChanged )
   {
      WasInputChanged = true;
      StateHasChanged();
   }
}

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

void EditBox_VMDisplay( AEditBox editBox, bool inputChange=false ) =>
GO(()=>{
   if ( inputChange )
      SetInputChanged();
   ErrorList.SetError( editBox.ErrorMessage );
   EnableSubmission();
});
void DropDownList_VMDisplay( ADropDownList_IdName dropDownList,
                             bool inputChange = false ) =>
GO(()=>{
   if ( inputChange )
      SetInputChanged();
   ErrorList.SetError( dropDownList.ErrorMessage );
   EnableSubmission();
});

void InputField_VMClear() => InputField_VMClear( false );
void InputField_VMClear(bool inputChange) =>
GO(()=>{
   if ( inputChange )
      SetInputChanged();
   ErrorList.Clear();
   EnableSubmission();
});

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

void App_FocusChanged() =>
GO(()=>{
   if ( !IsInInputField )
      ValidateInput_EnableSubmission();
});

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // BookCard
//**************************************************************************************************

} // BookRegistry.Client.Components
