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


class Article(Base):
    __tablename__ = "articles"

    article_number: Mapped[str] = mapped_column(String(255), primary_key=True)

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

    composition: Mapped[str] = mapped_column(String(255))
    brand: Mapped[str] = mapped_column(String(255))

    @property
    def date_to(self) -> str:
        return self.delivery_date_to.strftime("%d.%m.%Y")

    @property
    def date_from(self) -> str:
        return self.delivery_date_from.strftime("%d.%m.%Y")

    @property
    def brand_designation(self) -> str:
        """
        brand designation according to brand number
        :return: brand designation
        """
        if self.brand == "1":
            return "Gate G1 One"
        elif self.brand == "35":
            return "Roadsign"
        elif self.brand == "46":
            return "Hucke"
        else:
            raise ValueError(f"unknown brand number {self.brand}")

    # todo: missing classification

    color_sizes: Mapped[List["ArticleDetail"]] = relationship(
        back_populates="article",
        cascade="all, delete-orphan"
    )

    season_nr: Mapped[int] = mapped_column(ForeignKey("seasons.code"))
    season: Mapped["Season"] = relationship(
        back_populates="articles"
    )

    group_nr: Mapped[int] = mapped_column(ForeignKey("groups.code"))
    group: Mapped["Group"] = relationship(
        back_populates="articles"
    )

    theme_group_nr: Mapped[int] = mapped_column(ForeignKey("theme_groups.code"))
    theme_group: Mapped["ThemeGroup"] = relationship(
        back_populates="articles"
    )

    def __repr__(self) -> str:
        return self.article_number


class Picture(Base):
    __tablename__ = "pictures"

    id: Mapped[int] = mapped_column(primary_key=True)
    type: Mapped[str] = mapped_column(String(255))
    ref_id: Mapped[str] = mapped_column(String(255))
    path: Mapped[str] = mapped_column(String(255))


class ThemeGroup(Category):
    __tablename__ = "theme_groups"

    articles: Mapped[List["Article"]] = relationship(
        back_populates="theme_group",
        cascade="all, delete-orphan"
    )


class Group(Category):
    __tablename__ = "groups"

    articles: Mapped[List["Article"]] = relationship(
        back_populates="group",
        cascade="all, delete-orphan"
    )


class Season(Category):
    __tablename__ = "seasons"

    articles: Mapped[List["Article"]] = relationship(
        back_populates="season",
        cascade="all, delete-orphan"
    )

    def __eq__(self, other):
        return self.code == other.code

    def __hash__(self):
        return hash(self.code)


class ArticleDetail(Base):
    __tablename__ = "article_details"

    ean: Mapped[str] = mapped_column(String(255), primary_key=True)
    variant_number: Mapped[str] = mapped_column(String(255))

    article_number: Mapped[str] = mapped_column(ForeignKey("articles.article_number"))
    article: Mapped[Article] = relationship(
        back_populates="color_sizes"
    )

    # classification 2
    gender: Mapped[int] = mapped_column(Integer())
    # classification 4
    unlimited_sell: Mapped[bool] = mapped_column(Boolean())
    quantity: Mapped[int] = mapped_column(Integer())

    size: Mapped[int] = mapped_column(Integer())
    size_register: Mapped[int] = mapped_column(Integer())

    # blocked: Mapped[bool] = mapped_column(Boolean())

    color_code: Mapped[int] = mapped_column(ForeignKey("colors.code"))
    color: Mapped["Color"] = relationship(
        back_populates="article_details"
    )

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

    pricelists: Mapped[List["Pricelist"]] = relationship(
        back_populates="article_detail"
    )

    @property
    def gender_str(self):
        if self.gender == 1:
            return "male"
        else:
            return "female"

    @property
    def size_group(self):
        """
        Size group according to size of this article
        :return: size group 1-4
        """
        if 78 >= self.size >= 48:
            return 1
        elif 40 >= self.size >= 24:
            return 2
        elif 128 >= self.size >= 90:
            return 3
        else:
            return 4

    @property
    def picture_reference(self):
        return self.ean


class Color(Category):
    __tablename__ = "colors"
    article_details: Mapped[List["ArticleDetail"]] = relationship(
        back_populates="color"
    )

    @property
    def picture_reference(self):
        return self.code


class Pricelist(Base):
    __tablename__ = "pricelists"

    code: Mapped[int] = mapped_column(primary_key=True)

    price: Mapped[float] = mapped_column(DECIMAL(8, 2))
    article_detail_ean: Mapped[str] = mapped_column(ForeignKey("article_details.ean"), primary_key=True)
    article_detail: Mapped["ArticleDetail"] = relationship(
        back_populates="pricelists"
    )
