using System;
using System.Data;

namespace FourLayer.BusinessEntity
{
   public enum CustomerCardTypes
   {
      Mastercard,AmericanExpress,Visa,Discovery
   }
   public enum CustomerCardErrors
   {
      NoErrors, CardCancelled, OverCreditLimit, IsExpired
   }

   /// <summary>
   /// Hermetyzuje dane pojedynczego autora książki
   /// </summary>
   [Serializable]
   public class CustomerCard : AbstractEntity
   {

      // data members
      private string _cardName = "";
      private CustomerCardTypes _cardType;
      private DateTime _expDate;
      private decimal _creditLimit;
      private decimal _balance;
      private decimal _holds;
      private bool _isCancelled;


      public CustomerCard() { }
      public CustomerCard(string cardNumber, string cardName, CustomerCardTypes cardType,
         DateTime expDate, decimal creditLimit, decimal balance, decimal holds, 
         bool isCancelled)
         : base(cardNumber)
      {
         _cardName = cardName;
         _cardType = cardType;
         _expDate = expDate;
         _creditLimit = creditLimit;
         _balance = balance;
         _holds = holds;
         _isCancelled = isCancelled;
      }

      public string CardNumber
      {
         get { return (string)Key; }
         set { Key = value; }
      }
      public string CardName
      {
         get { return _cardName; }
         set { _cardName = value; }
      }
      public CustomerCardTypes CardType
      {
         get { return _cardType; }
         set { _cardType = value; }
      }
      public DateTime ExpDate
      {
         get { return _expDate; }
         set { _expDate = value; }
      }
      public decimal CreditLimit
      {
         get { return _creditLimit; }
         set { _creditLimit = value; }
      }
      public decimal Balance
      {
         get { return _balance; }
         set { _balance = value; }
      }
      public decimal Holds
      {
         get { return _holds; }
         set { _holds = value; }
      }
      public bool IsCancelled
      {
         get { return _isCancelled; }
         set { _isCancelled = value; }
      }

      public decimal Total
      {
         get { return Balance + Holds; }
      }
      public bool IsOverCreditLimit
      {
         get
         {
            if (Balance + Holds > CreditLimit)
               return true;
            else
               return false;
         }
      }
      public bool IsExpired
      {
         get 
         {
            if (ExpDate > DateTime.Now)
               return true;
            else
               return false;
         }
      }

      public override string ToString()
      {
         return CardNumber + "," + CardName;
      }
      public CustomerCardErrors Purchase(decimal purchase)
      {
         if (IsCancelled)
            return CustomerCardErrors.CardCancelled;
         if (IsExpired)
            return CustomerCardErrors.IsExpired;
         if (IsOverCreditLimit)
            return CustomerCardErrors.OverCreditLimit;
         if (purchase + Total> CreditLimit)
            return CustomerCardErrors.OverCreditLimit;

         Balance += purchase;
         return CustomerCardErrors.NoErrors;
      }
      public CustomerCardErrors Hold(decimal hold)
      {
         if (IsCancelled)
            return CustomerCardErrors.CardCancelled;
         if (IsExpired)
            return CustomerCardErrors.IsExpired;
         if (IsOverCreditLimit)
            return CustomerCardErrors.OverCreditLimit;
         if (hold + Total > CreditLimit)
            return CustomerCardErrors.OverCreditLimit;

         Holds += hold;
         return CustomerCardErrors.NoErrors;
      }
      public CustomerCardErrors Refund(decimal amount)
      {
         if (IsCancelled)
            return CustomerCardErrors.CardCancelled;
         if (IsExpired)
            return CustomerCardErrors.IsExpired;

         Balance -= amount;
         return CustomerCardErrors.NoErrors;
      }

      /// <summary>
      /// Sprawdza, czy stan obiektu jest prawidłowy
      /// </summary>
      protected override bool CheckIfSubClassStateIsValid
      {
         get
         {
            if (CardName == null)
            {
               AddBrokenRule("CustomerCard: Nazwa nie ma wartości");
               return false;
            }

            if (CardName.Length > 0)
               return true;
            else
            {
               AddBrokenRule("CustomerCard: Nazwa jest pusta");
               return false;
            }
         }
      }
   }
}
