from enum import Enum
from datetime import datetime
from decimal import Decimal
from typing import Dict
from sqlalchemy import ForeignKey, Numeric, JSON
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

__all__ = ["Direction", "PaymentType", "Base", "Sync", "Cart", "Item", "ItemOnCart"]


class Direction(Enum):
    push = 0
    pull = 1


class PaymentType(Enum):
    cash = 0
    card = 1


class Base(DeclarativeBase):
    pass


class Sync(Base):
    __tablename__ = "syncs"
    id: Mapped[int] = mapped_column(primary_key=True)
    direction: Mapped[Direction]
    sync_dt: Mapped[datetime] = mapped_column(default=datetime.now())


class Item(Base):
    __tablename__ = "items"
    upc: Mapped[int] = mapped_column(primary_key=True)
    unitprice: Mapped[Decimal] = mapped_column(Numeric(9, 2), nullable=False)
    discount_name: Mapped[str]
    discount_definition: Mapped[Dict[str, Dict[str, int]]] = mapped_column(
        JSON, nullable=True
    )


class Customer(Base):
    __tablename__ = "customers"
    id: Mapped[int] = mapped_column(primary_key=True)
    document: Mapped[str] = mapped_column(nullable=False)


class Cart(Base):
    __tablename__ = "carts"
    id: Mapped[int] = mapped_column(primary_key=True)
    checkin_dt: Mapped[datetime] = mapped_column(default=datetime.now())
    checkout_dt: Mapped[datetime] = mapped_column(nullable=True)
    total_amount: Mapped[Decimal] = mapped_column(Numeric(9, 2), nullable=True)
    payment_type: Mapped[PaymentType] = mapped_column(nullable=True)
    customer: Mapped[int] = mapped_column(ForeignKey("customers.id"), nullable=True)
    synced: Mapped[bool]


class ItemOnCart(Base):
    __tablename__ = "itemsoncart"
    id: Mapped[int] = mapped_column(primary_key=True)
    cart: Mapped[int] = mapped_column(ForeignKey("carts.id"))
    upc: Mapped[int] = mapped_column(ForeignKey("items.upc"))
    quantity: Mapped[int]
