from decimal import Decimal
from sqlalchemy import BigInteger, String, DECIMAL, JSON, Index, ForeignKey
from sqlalchemy.dialects.mysql import TINYINT
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.core.models.base import Base, TimestampMixin, TenantMixin


class ShippingSurcharge(Base, TenantMixin, TimestampMixin):
    """运费附加费（燃油费、偏远地区附加费、超尺寸附加费等）

    surcharge_type:
      - percentage  : 按运费基础费的百分比附加（value=百分比数值，如 5.5 = 5.5%）
      - fixed       : 固定金额附加

    condition_type:
      - always      : 始终收取
      - zone_match  : 仅指定区域（condition_zone_ids）收取
      - weight_over : 超过指定重量（condition_weight_kg）收取
    """

    __tablename__ = "shipping_surcharges"
    __table_args__ = (
        Index("ix_surcharge_tenant_active", "tenant_id", "is_active"),
        Index("ix_surcharge_method", "method_id"),
        {
            "mysql_engine": "InnoDB",
            "mysql_charset": "utf8mb4",
            "mysql_collate": "utf8mb4_unicode_ci",
        },
    )

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
    method_id: Mapped[int | None] = mapped_column(
        BigInteger, ForeignKey("shipping_methods.id", ondelete="CASCADE"),
        nullable=True, comment="NULL=应用到所有运费方案"
    )
    name: Mapped[str] = mapped_column(String(100), nullable=False, comment="附加费名称，如 燃油附加费")
    surcharge_type: Mapped[str] = mapped_column(
        String(20), nullable=False, default="fixed",
        comment="percentage=按比例 / fixed=固定金额"
    )
    value: Mapped[Decimal] = mapped_column(
        DECIMAL(10, 4), nullable=False, default=Decimal("0"),
        comment="百分比数值（5.5=5.5%）或固定金额"
    )
    condition_type: Mapped[str] = mapped_column(
        String(20), nullable=False, default="always",
        comment="always / zone_match / weight_over"
    )
    condition_zone_ids: Mapped[list | None] = mapped_column(
        JSON, nullable=True,
        comment="zone_match 时生效的区域 ID 列表"
    )
    condition_weight_kg: Mapped[Decimal | None] = mapped_column(
        DECIMAL(10, 3), nullable=True,
        comment="weight_over 时的重量门槛（kg）"
    )
    sort_order: Mapped[int] = mapped_column(BigInteger, nullable=False, default=0)
    is_active: Mapped[int] = mapped_column(TINYINT(1), nullable=False, default=1)

    method = relationship("ShippingMethod", back_populates="surcharges", lazy="noload")

    def __repr__(self) -> str:
        return f"<ShippingSurcharge id={self.id} name={self.name!r}>"
