# app/modules/billing/models/tier_feature_limit.py
"""
Feature limit models for tier-based and merchant-level access control.

Provides:
- TierFeatureLimit: Per-tier, per-feature limits (replaces hardcoded limit columns)
- MerchantFeatureOverride: Per-merchant overrides for admin-set exceptions
"""

from sqlalchemy import (
    Boolean,
    Column,
    ForeignKey,
    Index,
    Integer,
    String,
    UniqueConstraint,
)
from sqlalchemy.orm import relationship

from app.core.database import Base
from models.database.base import TimestampMixin


class TierFeatureLimit(Base, TimestampMixin):
    """
    Per-tier, per-feature limit definition.

    Replaces hardcoded limit columns on SubscriptionTier (orders_per_month,
    products_limit, etc.) and the features JSON array.

    For BINARY features: presence in this table = feature enabled for tier.
    For QUANTITATIVE features: limit_value is the cap (NULL = unlimited).

    Example:
        TierFeatureLimit(tier_id=1, feature_code="products_limit", limit_value=200)
        TierFeatureLimit(tier_id=1, feature_code="analytics_dashboard", limit_value=None)
    """

    __tablename__ = "tier_feature_limits"

    id = Column(Integer, primary_key=True, index=True)

    tier_id = Column(
        Integer,
        ForeignKey("subscription_tiers.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )

    feature_code = Column(String(80), nullable=False, index=True)

    # For QUANTITATIVE: cap value (NULL = unlimited)
    # For BINARY: ignored (presence means enabled)
    limit_value = Column(Integer, nullable=True)

    # Relationships
    tier = relationship(
        "SubscriptionTier",
        back_populates="feature_limits",
        foreign_keys=[tier_id],
    )

    __table_args__ = (
        UniqueConstraint(
            "tier_id", "feature_code",
            name="uq_tier_feature_code",
        ),
        Index("idx_tier_feature_lookup", "tier_id", "feature_code"),
    )

    def __repr__(self):
        limit = f", limit={self.limit_value}" if self.limit_value is not None else ""
        return f"<TierFeatureLimit(tier_id={self.tier_id}, code='{self.feature_code}'{limit})>"


class MerchantFeatureOverride(Base, TimestampMixin):
    """
    Per-merchant, per-platform feature override.

    Allows admins to override tier limits for specific merchants.
    For example, giving a merchant 500 products instead of tier's 200.

    Example:
        MerchantFeatureOverride(
            merchant_id=1,
            platform_id=1,
            feature_code="products_limit",
            limit_value=500,
            reason="Enterprise deal - custom product limit",
        )
    """

    __tablename__ = "merchant_feature_overrides"

    id = Column(Integer, primary_key=True, index=True)

    merchant_id = Column(
        Integer,
        ForeignKey("merchants.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )

    platform_id = Column(
        Integer,
        ForeignKey("platforms.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )

    feature_code = Column(String(80), nullable=False, index=True)

    # Override limit (NULL = unlimited)
    limit_value = Column(Integer, nullable=True)

    # Force enable/disable (overrides tier assignment)
    is_enabled = Column(Boolean, default=True, nullable=False)

    # Admin note explaining the override
    reason = Column(String(255), nullable=True)

    # Relationships
    merchant = relationship("Merchant", foreign_keys=[merchant_id])
    platform = relationship("Platform", foreign_keys=[platform_id])

    __table_args__ = (
        UniqueConstraint(
            "merchant_id", "platform_id", "feature_code",
            name="uq_merchant_platform_feature",
        ),
        Index("idx_merchant_override_lookup", "merchant_id", "platform_id", "feature_code"),
    )

    def __repr__(self):
        return (
            f"<MerchantFeatureOverride("
            f"merchant_id={self.merchant_id}, "
            f"platform_id={self.platform_id}, "
            f"code='{self.feature_code}'"
            f")>"
        )


__all__ = ["TierFeatureLimit", "MerchantFeatureOverride"]
