"""Ürün modülü ORM tanımları: ProductCategory, Product, ProductVariant.

Sadece tablo şeması — iş mantığı YOK.
"""
from datetime import UTC, datetime

from sqlalchemy import (
    DECIMAL,
    JSON,
    Boolean,
    DateTime,
    Enum,
    ForeignKey,
    Integer,
    String,
    Text,
    UniqueConstraint,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.database import Base, TimestampMixin, UUIDMixin

STOCK_STATUS_VALUES = ("in_stock", "low", "out_of_stock")
EMBEDDING_STATUS_VALUES = ("pending", "indexed", "failed")


class ProductCategory(UUIDMixin, Base):
    __tablename__ = "product_categories"
    __table_args__ = (UniqueConstraint("tenant_id", "slug", name="uq_tenant_slug"),)

    tenant_id: Mapped[str] = mapped_column(
        String(36), ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False
    )
    name: Mapped[str] = mapped_column(String(200), nullable=False)
    slug: Mapped[str] = mapped_column(String(200), nullable=False)
    parent_id: Mapped[str | None] = mapped_column(
        String(36), ForeignKey("product_categories.id", ondelete="SET NULL"), nullable=True
    )
    created_at: Mapped[datetime] = mapped_column(
        DateTime,
        default=lambda: datetime.now(UTC).replace(tzinfo=None),
        nullable=False,
    )


class Product(UUIDMixin, TimestampMixin, Base):
    __tablename__ = "products"

    tenant_id: Mapped[str] = mapped_column(
        String(36), ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True
    )
    category_id: Mapped[str | None] = mapped_column(
        String(36), ForeignKey("product_categories.id", ondelete="SET NULL"), nullable=True
    )

    title: Mapped[str] = mapped_column(String(500), nullable=False)
    description: Mapped[str | None] = mapped_column(Text, nullable=True)
    bullet_points: Mapped[list | None] = mapped_column(JSON, nullable=True)
    sku: Mapped[str | None] = mapped_column(String(100), nullable=True)
    barcode: Mapped[str | None] = mapped_column(String(100), nullable=True)

    price: Mapped[float] = mapped_column(DECIMAL(10, 2), nullable=False)
    compare_at_price: Mapped[float | None] = mapped_column(DECIMAL(10, 2), nullable=True)
    currency: Mapped[str] = mapped_column(String(3), default="TRY", server_default="TRY")

    stock_quantity: Mapped[int] = mapped_column(Integer, default=0, server_default="0")
    stock_status: Mapped[str] = mapped_column(
        Enum(*STOCK_STATUS_VALUES, name="stock_status"),
        default="in_stock",
        server_default="in_stock",
    )
    low_stock_threshold: Mapped[int] = mapped_column(Integer, default=5, server_default="5")

    is_active: Mapped[bool] = mapped_column(Boolean, default=True, server_default="1")
    images: Mapped[list | None] = mapped_column(JSON, nullable=True)

    embedding_status: Mapped[str] = mapped_column(
        Enum(*EMBEDDING_STATUS_VALUES, name="embedding_status"),
        default="pending",
        server_default="pending",
    )
    embedding_updated_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)

    meta: Mapped[dict | None] = mapped_column(JSON, nullable=True)
    deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, index=True)

    variants: Mapped[list["ProductVariant"]] = relationship(
        back_populates="product", cascade="all, delete-orphan", lazy="selectin"
    )


class ProductVariant(UUIDMixin, Base):
    __tablename__ = "product_variants"

    product_id: Mapped[str] = mapped_column(
        String(36), ForeignKey("products.id", ondelete="CASCADE"), nullable=False, index=True
    )
    title: Mapped[str] = mapped_column(String(300), nullable=False)
    sku: Mapped[str | None] = mapped_column(String(100), nullable=True)
    price: Mapped[float] = mapped_column(DECIMAL(10, 2), nullable=False)
    stock_quantity: Mapped[int] = mapped_column(Integer, default=0, server_default="0")
    attributes: Mapped[dict | None] = mapped_column(JSON, nullable=True)
    is_active: Mapped[bool] = mapped_column(Boolean, default=True, server_default="1")

    product: Mapped["Product"] = relationship(back_populates="variants")
