# app/modules/tenancy/models/merchant_domain.py
"""
Merchant Domain Model - Maps custom domains to merchants for merchant-level domain routing.

When a merchant subscribes to a platform (e.g., loyalty), they can register a domain
(e.g., myloyaltyprogram.lu) that serves as the default for all their stores.
Individual stores can optionally override this with their own custom StoreDomain.

Domain Resolution Priority:
1. Store-specific custom domain (StoreDomain) -> highest priority
2. Merchant domain (MerchantDomain) -> inherited default
3. Store subdomain ({store.subdomain}.rewardflow.lu) -> fallback
"""

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

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


class MerchantDomain(Base, TimestampMixin):
    """
    Maps custom domains to merchants for merchant-level domain routing.

    Examples:
    - myloyaltyprogram.lu -> Merchant "WizaCorp" (all stores inherit)
    - Store ORION overrides with StoreDomain -> mysuperloyaltyprogram.lu
    - Store WIZAGADGETS -> inherits myloyaltyprogram.lu
    """

    __tablename__ = "merchant_domains"

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

    # Domain configuration
    domain = Column(String(255), nullable=False, unique=True, index=True)
    is_primary = Column(Boolean, default=True, nullable=False)
    is_active = Column(Boolean, default=True, nullable=False)

    # SSL/TLS status (for monitoring)
    ssl_status = Column(
        String(50), default="pending"
    )  # pending, active, expired, error
    ssl_verified_at = Column(DateTime(timezone=True), nullable=True)

    # DNS verification (to confirm domain ownership)
    verification_token = Column(String(100), unique=True, nullable=True)
    is_verified = Column(Boolean, default=False, nullable=False)
    verified_at = Column(DateTime(timezone=True), nullable=True)

    # Platform association (for platform context resolution from custom domains)
    platform_id = Column(
        Integer,
        ForeignKey("platforms.id", ondelete="SET NULL"),
        nullable=True,
        index=True,
        comment="Platform this domain is associated with (for platform context resolution)",
    )

    # Relationships
    merchant = relationship("Merchant", back_populates="merchant_domains")
    platform = relationship("Platform")

    # Constraints
    __table_args__ = (
        UniqueConstraint("merchant_id", "platform_id", name="uq_merchant_domain_platform"),
        Index("idx_merchant_domain_active", "domain", "is_active"),
        Index("idx_merchant_domain_primary", "merchant_id", "is_primary"),
        Index("idx_merchant_domain_platform", "platform_id"),
    )

    def __repr__(self):
        return f"<MerchantDomain(domain='{self.domain}', merchant_id={self.merchant_id})>"

    @property
    def full_url(self):
        """Return full URL with https"""
        return f"https://{self.domain}"

    @classmethod
    def normalize_domain(cls, domain: str) -> str:
        """
        Normalize domain for consistent storage.

        Reuses the same logic as StoreDomain.normalize_domain().

        Examples:
        - https://example.com -> example.com
        - www.example.com -> example.com
        - EXAMPLE.COM -> example.com
        """
        # Remove protocol
        domain = domain.replace("https://", "").replace("http://", "")  # noqa: SEC034

        # Remove trailing slash
        domain = domain.rstrip("/")

        # Convert to lowercase
        domain = domain.lower()

        return domain


__all__ = ["MerchantDomain"]
