from pydantic import BaseModel, Field
from typing import Optional
from sqlalchemy import Integer, Float, String, Enum, Text, ForeignKey
from sqlalchemy.orm import relationship, Mapped, mapped_column, Session
from app.models.main import Base

class DisplayRackingUnitBase(BaseModel):
    rack_id: int | None = Field(default=None)
    group_id: int | None = Field(default=None)
    store_format_type: str | None = Field(default=None)
    type_display_racking_unit: str | None = Field(default=None)
    #unit_type: str | None = Field(default=None)  
    number_of_units: int | None = Field(default=None)
    cost_per_unit: float | None = Field(default=None)
    total:float | None = Field(default=None)
    remarks: str | None = Field(default=None)

class TblDisplayRackingUnit(Base):
    __tablename__ = "tbl_display_racking_unit"

    rack_id: Mapped[int] = mapped_column("rack_id", Integer, primary_key=True, autoincrement=True)
    group_id: Mapped[int] = mapped_column(Integer, ForeignKey("tbl_group.group_id"), nullable=False)
    store_format_type: Mapped[str] = mapped_column(Enum("Store Format A", "Store Format B", name="store_format_type"), nullable=False)
    type_display_racking_unit:Mapped[str] = mapped_column(String(255), nullable=False)
    #unit_type: Mapped[str] = mapped_column(String(255), nullable=False)
    number_of_units: Mapped[int] = mapped_column(Integer, nullable=False)
    cost_per_unit: Mapped[float] = mapped_column(Float, nullable=False)
    total: Mapped[float] = mapped_column(Float, nullable=True)
    remarks: Mapped[str] = mapped_column(Text, nullable=False)

    group = relationship("TblGroup", back_populates="display_racking_units")

    @classmethod
    def create(cls, data: DisplayRackingUnitBase, db: Session) -> "TblDisplayRackingUnit":
        data_dict = data.model_dump()
        new_data = cls(**data_dict)
        db.add(new_data)
        db.flush()
        return new_data

    @classmethod
    def get_unit(cls, rack_id: int, db: Session) -> Optional["TblDisplayRackingUnit"]:
        return db.query(cls).filter(cls.rack_id == rack_id).first()

    @classmethod
    def update_unit(cls, rack_id: int, data: DisplayRackingUnitBase, db: Session) -> Optional["TblDisplayRackingUnit"]:
        existing = db.query(cls).filter(cls.rack_id == rack_id).first()
        if not existing:
            return None
        for key, value in data.model_dump(exclude_unset=True).items():
            setattr(existing, key, value)
        db.commit()
        db.refresh(existing)
        return existing

    @property
    def total_cost(self) -> float:
        return self.number_of_units * self.cost_per_unit
