from __future__ import annotations

from datetime import datetime, timezone

from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, Text, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.core.db.common import CommonBase


class DomainMapping(CommonBase):
    """Maps an incoming domain/host to marketplace, tenant, branch, or consultant context.

    Phase 7T.1 only stores and manages the mappings. Runtime domain resolution is added
    in Phase 7T.2, so this table is intentionally safe and independent.
    """

    __tablename__ = "domain_mappings"
    __table_args__ = (
        UniqueConstraint("domain_name", name="uq_domain_mappings_domain_name"),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    domain_name: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
    domain_type: Mapped[str] = mapped_column(String(60), nullable=False, index=True)

    tenant_id: Mapped[int | None] = mapped_column(ForeignKey("tenants.id", ondelete="SET NULL"), nullable=True, index=True)
    branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
    consultant_id: Mapped[int | None] = mapped_column(ForeignKey("consultant_profiles.id", ondelete="SET NULL"), nullable=True, index=True)
    parent_tenant_id: Mapped[int | None] = mapped_column(ForeignKey("tenants.id", ondelete="SET NULL"), nullable=True, index=True)

    is_primary: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
    is_verified: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
    status: Mapped[str] = mapped_column(String(30), nullable=False, default="draft", index=True)

    verification_token: Mapped[str | None] = mapped_column(String(120), nullable=True, index=True)
    dns_txt_name: Mapped[str | None] = mapped_column(String(255), nullable=True)
    dns_txt_value: Mapped[str | None] = mapped_column(String(255), nullable=True)
    ssl_mode: Mapped[str] = mapped_column(String(30), nullable=False, default="manual")
    ssl_status: Mapped[str] = mapped_column(String(30), nullable=False, default="not_checked", index=True)
    ssl_provider: Mapped[str | None] = mapped_column(String(60), nullable=True)
    ssl_last_checked_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
    ssl_not_after_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
    ssl_issuer: Mapped[str | None] = mapped_column(String(255), nullable=True)
    ssl_subject: Mapped[str | None] = mapped_column(String(255), nullable=True)
    ssl_last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
    notes: Mapped[str | None] = mapped_column(Text, nullable=True)

    created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
    updated_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
    created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
    updated_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), nullable=False)

    tenant = relationship("Tenant", foreign_keys=[tenant_id])
    branch = relationship("Branch", foreign_keys=[branch_id])
    consultant = relationship("ConsultantProfile", foreign_keys=[consultant_id])
    parent_tenant = relationship("Tenant", foreign_keys=[parent_tenant_id])
