"""
SEO Data models for the "SEO Juice Detector" feature.

This implements "Strategie 3: SEO-Daten & Backlinks" from analysis_3.md:
"SEO-Agenturen suchen Domains nicht wegen dem Namen, sondern wegen der Power (Backlinks).
Wenn eine Domain droppt, prüfst du nicht nur den Namen, sondern ob Backlinks existieren."

This is a TYCOON-ONLY feature ($29/month).

DATABASE TABLE TO CREATE:
- domain_seo_data - Cached SEO metrics for domains

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

from app.database import Base


class DomainSEOData(Base):
    """
    Cached SEO data for domains.
    
    Stores backlink data, domain authority, and other SEO metrics
    from Moz API or alternative sources.
    
    From analysis_3.md:
    "Domain `alte-bäckerei-münchen.de` ist frei. 
    Hat Links von `sueddeutsche.de` und `wikipedia.org`."
    """
    
    __tablename__ = "domain_seo_data"
    
    id: Mapped[int] = mapped_column(primary_key=True, index=True)
    domain: Mapped[str] = mapped_column(String(255), unique=True, nullable=False, index=True)
    
    # Moz metrics
    domain_authority: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)  # 0-100
    page_authority: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)  # 0-100
    spam_score: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)  # 0-100
    
    # Backlink data
    total_backlinks: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    referring_domains: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    
    # Top backlinks (JSON array of {domain, authority, type})
    top_backlinks: Mapped[Optional[dict]] = mapped_column(JSON, nullable=True)
    
    # Notable backlinks (high-authority sites)
    notable_backlinks: Mapped[Optional[str]] = mapped_column(Text, nullable=True)  # Comma-separated
    has_wikipedia_link: Mapped[bool] = mapped_column(Boolean, default=False)
    has_gov_link: Mapped[bool] = mapped_column(Boolean, default=False)
    has_edu_link: Mapped[bool] = mapped_column(Boolean, default=False)
    has_news_link: Mapped[bool] = mapped_column(Boolean, default=False)
    
    # Estimated value based on SEO
    seo_value_estimate: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
    
    # Data source
    data_source: Mapped[str] = mapped_column(String(50), default="moz")  # moz, ahrefs, majestic, estimated
    
    # Cache management
    last_updated: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
    expires_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    
    # Request tracking
    fetch_count: Mapped[int] = mapped_column(Integer, default=0)
    
    def __repr__(self) -> str:
        return f"<DomainSEOData {self.domain} DA:{self.domain_authority}>"
    
    @property
    def is_expired(self) -> bool:
        if not self.expires_at:
            return True
        return datetime.utcnow() > self.expires_at
    
    @property
    def seo_score(self) -> int:
        """Calculate overall SEO score (0-100)."""
        if not self.domain_authority:
            return 0
        
        score = self.domain_authority
        
        # Boost for notable links
        if self.has_wikipedia_link:
            score = min(100, score + 10)
        if self.has_gov_link:
            score = min(100, score + 5)
        if self.has_edu_link:
            score = min(100, score + 5)
        if self.has_news_link:
            score = min(100, score + 3)
        
        # Penalty for spam
        if self.spam_score and self.spam_score > 30:
            score = max(0, score - (self.spam_score // 5))
        
        return score
    
    @property
    def value_category(self) -> str:
        """Categorize SEO value for display."""
        score = self.seo_score
        if score >= 60:
            return "High Value"
        elif score >= 40:
            return "Medium Value"
        elif score >= 20:
            return "Low Value"
        return "Minimal"

