from sqlalchemy.dialects.mysql import TINYINT
from sqlalchemy import BigInteger, String, JSON, UniqueConstraint, Index, ForeignKey, DECIMAL, Integer
from sqlalchemy.dialects.mysql import DATETIME as MYSQL_DATETIME
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.core.models.base import Base, TimestampMixin, TenantMixin


class Customer(Base, TenantMixin, TimestampMixin):
    """买家客户"""

    __tablename__ = "customers"
    __table_args__ = (
        UniqueConstraint("tenant_id", "email", name="uk_customers_tenant_email"),
        Index("ix_customers_created", "created_at"),
        Index("ix_customers_member_level", "member_level_id"),
        {
            "mysql_engine": "InnoDB",
            "mysql_charset": "utf8mb4",
            "mysql_collate": "utf8mb4_unicode_ci",
        },
    )

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
    email: Mapped[str] = mapped_column(String(255), nullable=False)
    name: Mapped[str] = mapped_column(String(100), nullable=False, comment="显示名称")
    phone: Mapped[str | None] = mapped_column(String(30), nullable=True)
    is_active: Mapped[int] = mapped_column(TINYINT(1), nullable=False, default=1, comment="是否激活（禁用则无法登录）")
    member_level_id: Mapped[int | None] = mapped_column(
        BigInteger, ForeignKey("member_levels.id", ondelete="SET NULL"), nullable=True, index=True
    )
    points_balance: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    total_spent: Mapped[float] = mapped_column(DECIMAL(12, 2), nullable=False, default=0)
    orders_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
    member_expires_at: Mapped[MYSQL_DATETIME | None] = mapped_column(MYSQL_DATETIME(fsp=3), nullable=True)

    # JSON 扩展字段
    addresses: Mapped[list | None] = mapped_column(JSON, nullable=True, comment="收货地址数组")
    tags: Mapped[dict | None] = mapped_column(JSON, nullable=True, comment="客户标签")
    extra_data: Mapped[dict | None] = mapped_column(JSON, nullable=True, comment="行业扩展属性")
    preferred_language: Mapped[str | None] = mapped_column(
        String(10), nullable=True, comment="客户偏好语言 zh | en，空时用租户默认"
    )

    # ── 关联 ─────────────────────────────────────────────────────
    tenant = relationship("Tenant", back_populates="customers", lazy="noload")
    orders = relationship("Order", back_populates="customer", lazy="noload")
    member_level = relationship("MemberLevel", back_populates="customers", lazy="noload")

    def get_attribute(self, key: str, default=None):
        if not self.extra_data:
            return default
        return self.extra_data.get(key, default)

    def set_attribute(self, key: str, value) -> None:
        if self.extra_data is None:
            self.extra_data = {}
        self.extra_data = {**self.extra_data, key: value}

    def __repr__(self) -> str:
        return f"<Customer id={self.id} email={self.email!r}>"
