from datetime import datetime, date
from src.data.model.db.base_db import Base, Category, User
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy import String, ForeignKey, Date, Integer, Boolean, Float
from typing import List
from src.data.model.db.article import ArticleDetail


class Payment(Category):
    __tablename__ = "payments"
    partners: Mapped[List["Partner"]] = relationship(back_populates="payment")


class Shipping(Category):
    __tablename__ = "shipping_terms"
    partners: Mapped[List["Partner"]] = relationship(back_populates="shipping")


class SalesOrderTypePartner(Base):
    __tablename__ = "sales_order_type_partners"
    code: Mapped[int] = mapped_column(ForeignKey("sales_order_types.code"), primary_key=True)
    sales_order_type: Mapped["SalesOrderType"] = relationship(back_populates="partners")
    partner_num: Mapped[int] = mapped_column(ForeignKey("partners.partner_num"), primary_key=True)
    pricelist_code: Mapped[int] = mapped_column(ForeignKey("pricelists.code"))


class SalesOrderType(Category):
    __tablename__ = "sales_order_types"
    partners: Mapped[List["SalesOrderTypePartner"]] = relationship(back_populates="sales_order_type")


class Agent(User):
    __tablename__ = "agents"
    agent_num: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(255))

    orders: Mapped[List["Order"]] = relationship(back_populates="agent")
    shopping_carts: Mapped[List["ShoppingCart"]] = relationship(back_populates="agent")


class Partner(User):
    __tablename__ = "partners"

    name: Mapped[str] = mapped_column(String(255))
    partner_num: Mapped[int] = mapped_column(primary_key=True)

    payment_code: Mapped[int] = mapped_column(ForeignKey("payments.code"))
    payment: Mapped["Payment"] = relationship(back_populates="partners")

    shipping_code: Mapped[int] = mapped_column(ForeignKey("shipping_terms.code"))
    shipping: Mapped["Shipping"] = relationship(back_populates="partners")

    allow_orders: Mapped[bool] = mapped_column(Boolean())
    orders: Mapped[List["Order"]] = relationship(back_populates="partner")

    surcharge_code: Mapped[int] = mapped_column(Integer())

    shopping_carts: Mapped[List["ShoppingCart"]] = relationship(back_populates="partner")

    classification1: Mapped[str] = mapped_column(String(255), nullable=True)
    classification2: Mapped[str] = mapped_column(String(255), nullable=True)

    impuls_representation: Mapped[str] = mapped_column(String(255), nullable=True)


class AgentPartner(Base):
    __tablename__ = "agent_partners"
    partner_num: Mapped[int] = mapped_column(ForeignKey("partners.partner_num"), primary_key=True)
    agent_num: Mapped[int] = mapped_column(ForeignKey("agents.agent_num"), primary_key=True)


class Order(Base):
    __tablename__ = "orders"

    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    date: Mapped[datetime] = mapped_column(Date())

    agent_id: Mapped[int] = mapped_column(ForeignKey("agents.agent_num"), nullable=True)
    agent: Mapped["Agent"] = relationship(back_populates="orders")

    partner_id: Mapped[int] = mapped_column(ForeignKey("partners.partner_num"))
    partner: Mapped["Partner"] = relationship(back_populates="orders")

    details: Mapped[List["OrderDetail"]] = relationship(back_populates="order")
    processed: Mapped[bool] = mapped_column(Boolean())


class OrderDetail(Base):
    __tablename__ = "order_details"

    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    order_id: Mapped[int] = mapped_column(ForeignKey("orders.id"))
    order: Mapped["Order"] = relationship(back_populates="details")

    quantity: Mapped[int] = mapped_column(Integer())

    ean: Mapped[str] = mapped_column(ForeignKey("article_details.ean"))
    article_detail: Mapped["ArticleDetail"] = relationship()

    sales_order_type_code: Mapped[int] = mapped_column(ForeignKey("sales_order_types.code"))
    price: Mapped[float] = mapped_column(Float())

    delivery_date_from: Mapped[date] = mapped_column(Date())
    delivery_date_to: Mapped[date] = mapped_column(Date())

    partner_delivery_number: Mapped[str] = mapped_column(String(255), nullable=True)


"""
Shopping cart 
"""
class ShoppingCart(Base):
    __tablename__ = "shopping_carts"

    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)

    ean: Mapped[str] = mapped_column(ForeignKey("article_details.ean"))
    article: Mapped["ArticleDetail"] = relationship()

    sales_order_type_code: Mapped[int] = mapped_column(ForeignKey("sales_order_types.code"))
    quantity: Mapped[int] = mapped_column(Integer())

    agent_id: Mapped[int] = mapped_column(ForeignKey("agents.agent_num"), nullable=True)
    agent: Mapped["Agent"] = relationship(back_populates="shopping_carts")

    partner_id: Mapped[int] = mapped_column(ForeignKey("partners.partner_num"))
    partner: Mapped["Partner"] = relationship(back_populates="shopping_carts")

    delivery_date_from: Mapped[date] = mapped_column(Date())
    delivery_date_to: Mapped[date] = mapped_column(Date())

    partner_delivery_number: Mapped[str] = mapped_column(String(255), nullable=True)

    price: Mapped[float] = mapped_column(Float())
