from typing import Optional, List, Any
from datetime import datetime

from ....core.interfaces.dto import Dto
from ....core.interfaces.core import Core
from ....enums.financial.transactions import TransactionType, TransactionState, TransactionReason


from ..common.pay import Pay, PayDto


class Transaction[Properties: Any](Core[Properties]):
  saga: str  # Saga ID

  type: TransactionType
  state: TransactionState
  reason: TransactionReason

  amount: float

  payees: Optional[List[Pay[Properties]]]
  payers: Optional[List[Pay[Properties]]]

  failed_at: Optional[datetime]
  verified_at: Optional[datetime]
  canceled_at: Optional[datetime]

  invoice: Optional[str]


# ----------------------------------------
# Data Transfer Object Interface
# ----------------------------------------


class TransactionDto[Properties: Any](Dto[Properties]):
  saga: str  # Saga ID

  type: Optional[TransactionType]
  state: TransactionState
  reason: TransactionReason

  amount: float

  payees: Optional[List[PayDto[Properties]]]
  payers: Optional[List[PayDto[Properties]]]

  failed_at: Optional[datetime]
  verified_at: Optional[datetime]
  canceled_at: Optional[datetime]

  invoice: Optional[str]


class TransactionInitDto[Properties: Any](Dto[Properties]):
  saga: Optional[str]  # Saga ID

  type: Optional[TransactionType]
  state: Optional[TransactionState]
  reason: TransactionReason

  amount: float

  payees: Optional[List[PayDto[Properties]]]
  payers: Optional[List[PayDto[Properties]]]

  failed_at: Optional[datetime]
  verified_at: Optional[datetime]
  canceled_at: Optional[datetime]

  invoice: Optional[str]
