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

from ....core.enums.state import State
from ....core.interfaces.dto import Dto
from ....core.interfaces.core import Core
from ....enums.financial.invoices import InvoiceType


from ..common.pay import Pay, PayDto
from .item import InvoiceItem, InvoiceItemDto


class Invoice[Properties: Any](Core[Properties]):
  type: InvoiceType

  title: Optional[str]

  paid: Optional[float]
  amount: float

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

  currency: Optional[str]
  items: Optional[List[InvoiceItem[Properties]]]

  state: State

  profit: Optional[float]
  discount: Optional[float]

  closed_at: Optional[datetime]
  expires_at: Optional[datetime]

  replication: Optional[int]
  subscription: Optional[str]  # cron expression


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


class InvoiceDto[Properties: Any](Dto[Properties]):
  type: Optional[InvoiceType]

  title: Optional[str]

  paid: Optional[float]
  amount: float

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

  currency: Optional[str]
  items: Optional[List[InvoiceItemDto[Properties]]]

  state: Optional[State]

  profit: Optional[float]
  discount: Optional[float]

  closed_at: Optional[datetime]
  expires_at: Optional[datetime]

  replication: Optional[int]
  subscription: Optional[str]  # cron expression
