"""
Domain Listing models for "Pounce For Sale" feature.

This implements the "Micro-Marktplatz" strategy from analysis_3.md:
- Users can create professional landing pages for domains they want to sell
- Buyers can contact sellers through Pounce
- DNS verification ensures only real owners can list domains

DATABASE TABLES TO CREATE:
1. domain_listings - Main listing table
2. listing_inquiries - Contact requests from potential buyers
3. listing_views - Track views for analytics

Run migrations: alembic upgrade head
"""
from datetime import datetime
from typing import Optional, List
from sqlalchemy import String, DateTime, Float, Integer, Text, ForeignKey, Boolean, Enum as SQLEnum
from sqlalchemy.orm import Mapped, mapped_column, relationship
import enum

from app.database import Base


class ListingStatus(str, enum.Enum):
    """Status of a domain listing."""
    DRAFT = "draft"           # Not yet published
    PENDING_VERIFICATION = "pending_verification"  # Awaiting DNS verification
    ACTIVE = "active"         # Live and visible
    SOLD = "sold"             # Marked as sold
    EXPIRED = "expired"       # Listing expired
    SUSPENDED = "suspended"   # Suspended by admin


class VerificationStatus(str, enum.Enum):
    """DNS verification status."""
    NOT_STARTED = "not_started"
    PENDING = "pending"
    VERIFIED = "verified"
    FAILED = "failed"


class DomainListing(Base):
    """
    Domain listing for the Pounce marketplace.
    
    Users can list their domains for sale with a professional landing page.
    URL: pounce.ch/buy/{slug}
    
    Features:
    - DNS verification for ownership proof
    - Professional landing page with valuation
    - Contact form for buyers
    - Analytics (views, inquiries)
    
    From analysis_3.md:
    "Ein User (Trader/Tycoon) kann für seine Domains mit einem Klick 
    eine schicke Verkaufsseite erstellen."
    """
    
    __tablename__ = "domain_listings"
    
    id: Mapped[int] = mapped_column(primary_key=True, index=True)
    user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), index=True, nullable=False)
    
    # Domain info
    domain: Mapped[str] = mapped_column(String(255), unique=True, nullable=False, index=True)
    slug: Mapped[str] = mapped_column(String(300), unique=True, nullable=False, index=True)
    
    # Listing details
    title: Mapped[Optional[str]] = mapped_column(String(200), nullable=True)  # Custom headline
    description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
    
    # Pricing
    asking_price: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
    min_offer: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
    currency: Mapped[str] = mapped_column(String(3), default="USD")
    price_type: Mapped[str] = mapped_column(String(20), default="fixed")  # fixed, negotiable, make_offer
    
    # Pounce valuation (calculated)
    pounce_score: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)  # 0-100
    estimated_value: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
    
    # Verification (from analysis_3.md - Säule 2: Asset Verification)
    verification_status: Mapped[str] = mapped_column(
        String(20), 
        default=VerificationStatus.NOT_STARTED.value
    )
    verification_code: Mapped[Optional[str]] = mapped_column(String(64), nullable=True)
    verified_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    
    # Status
    status: Mapped[str] = mapped_column(String(30), default=ListingStatus.DRAFT.value, index=True)
    sold_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    sold_reason: Mapped[Optional[str]] = mapped_column(String(200), nullable=True)
    sold_price: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
    sold_currency: Mapped[Optional[str]] = mapped_column(String(3), nullable=True)
    
    # Features
    show_valuation: Mapped[bool] = mapped_column(Boolean, default=True)
    allow_offers: Mapped[bool] = mapped_column(Boolean, default=True)
    featured: Mapped[bool] = mapped_column(Boolean, default=False)  # Premium placement
    
    # Analytics
    view_count: Mapped[int] = mapped_column(Integer, default=0)
    inquiry_count: Mapped[int] = mapped_column(Integer, default=0)
    
    # Expiry
    expires_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    
    # Timestamps
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
    updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    published_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    
    # Relationships
    user: Mapped["User"] = relationship("User", back_populates="listings")
    inquiries: Mapped[List["ListingInquiry"]] = relationship(
        "ListingInquiry", back_populates="listing", cascade="all, delete-orphan"
    )
    
    def __repr__(self) -> str:
        return f"<DomainListing {self.domain} ({self.status})>"
    
    @property
    def is_verified(self) -> bool:
        return self.verification_status == VerificationStatus.VERIFIED.value
    
    @property
    def is_active(self) -> bool:
        return self.status == ListingStatus.ACTIVE.value
    
    @property
    def public_url(self) -> str:
        return f"/buy/{self.slug}"


class ListingInquiry(Base):
    """
    Contact request from a potential buyer.
    
    From analysis_3.md:
    "Ein einfaches Kontaktformular, das die Anfrage direkt an den User leitet."
    
    Security (from analysis_3.md - Säule 3):
    - Keyword blocking for phishing prevention
    - Rate limiting per IP/user
    """
    
    __tablename__ = "listing_inquiries"
    
    id: Mapped[int] = mapped_column(primary_key=True, index=True)
    listing_id: Mapped[int] = mapped_column(ForeignKey("domain_listings.id"), index=True, nullable=False)
    buyer_user_id: Mapped[Optional[int]] = mapped_column(ForeignKey("users.id"), index=True, nullable=True)
    
    # Inquirer info
    name: Mapped[str] = mapped_column(String(100), nullable=False)
    email: Mapped[str] = mapped_column(String(255), nullable=False)
    phone: Mapped[Optional[str]] = mapped_column(String(50), nullable=True)
    company: Mapped[Optional[str]] = mapped_column(String(200), nullable=True)
    
    # Message
    message: Mapped[str] = mapped_column(Text, nullable=False)
    offer_amount: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
    
    # Status
    status: Mapped[str] = mapped_column(String(20), default="new")  # new, read, replied, closed, spam
    closed_reason: Mapped[Optional[str]] = mapped_column(String(200), nullable=True)
    
    # Tracking
    ip_address: Mapped[Optional[str]] = mapped_column(String(45), nullable=True)
    user_agent: Mapped[Optional[str]] = mapped_column(String(500), nullable=True)
    
    # Timestamps
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
    read_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    replied_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    closed_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    
    # Relationships
    listing: Mapped["DomainListing"] = relationship("DomainListing", back_populates="inquiries")
    messages: Mapped[List["ListingInquiryMessage"]] = relationship(
        "ListingInquiryMessage", back_populates="inquiry", cascade="all, delete-orphan"
    )
    events: Mapped[List["ListingInquiryEvent"]] = relationship(
        "ListingInquiryEvent", back_populates="inquiry", cascade="all, delete-orphan"
    )
    
    def __repr__(self) -> str:
        return f"<ListingInquiry from {self.email} for listing #{self.listing_id}>"


class ListingInquiryEvent(Base):
    """
    Audit trail for inquiry status changes.

    This is the minimal “deal system” log:
    - who changed what status
    - when it happened
    - optional reason (close/spam)
    """

    __tablename__ = "listing_inquiry_events"

    id: Mapped[int] = mapped_column(primary_key=True, index=True)
    inquiry_id: Mapped[int] = mapped_column(ForeignKey("listing_inquiries.id"), index=True, nullable=False)
    listing_id: Mapped[int] = mapped_column(ForeignKey("domain_listings.id"), index=True, nullable=False)
    actor_user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), index=True, nullable=False)

    old_status: Mapped[Optional[str]] = mapped_column(String(20), nullable=True)
    new_status: Mapped[str] = mapped_column(String(20), nullable=False)
    reason: Mapped[Optional[str]] = mapped_column(String(200), nullable=True)

    ip_address: Mapped[Optional[str]] = mapped_column(String(45), nullable=True)
    user_agent: Mapped[Optional[str]] = mapped_column(String(500), nullable=True)

    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, index=True)

    inquiry: Mapped["ListingInquiry"] = relationship("ListingInquiry", back_populates="events")


class ListingInquiryMessage(Base):
    """
    Thread messages for listing inquiries (in-product negotiation).

    - Buyer sends messages from their account
    - Seller replies from Terminal
    """

    __tablename__ = "listing_inquiry_messages"

    id: Mapped[int] = mapped_column(primary_key=True, index=True)
    inquiry_id: Mapped[int] = mapped_column(ForeignKey("listing_inquiries.id"), index=True, nullable=False)
    listing_id: Mapped[int] = mapped_column(ForeignKey("domain_listings.id"), index=True, nullable=False)

    sender_user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), index=True, nullable=False)
    body: Mapped[str] = mapped_column(Text, nullable=False)

    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, index=True)

    inquiry: Mapped["ListingInquiry"] = relationship("ListingInquiry", back_populates="messages")


class ListingView(Base):
    """
    Track listing page views for analytics.
    """
    
    __tablename__ = "listing_views"
    
    id: Mapped[int] = mapped_column(primary_key=True, index=True)
    listing_id: Mapped[int] = mapped_column(ForeignKey("domain_listings.id"), index=True, nullable=False)
    
    # Visitor info
    ip_address: Mapped[Optional[str]] = mapped_column(String(45), nullable=True)
    user_agent: Mapped[Optional[str]] = mapped_column(String(500), nullable=True)
    referrer: Mapped[Optional[str]] = mapped_column(String(500), nullable=True)
    
    # User (if logged in)
    user_id: Mapped[Optional[int]] = mapped_column(ForeignKey("users.id"), nullable=True)
    
    # Timestamp
    viewed_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
    
    def __repr__(self) -> str:
        return f"<ListingView #{self.listing_id} at {self.viewed_at}>"

