# src/fmatch/saas/models/survey_models.py
"""
Survey result storage and finding models.
Production-ready with proper indexing and relationships.
"""

from typing import Optional, Dict, Any, List
from sqlalchemy import (
    Column,
    String,
    JSON,
    Float,
    Integer,
    DateTime,
    Index,
    ForeignKey,
)
from sqlalchemy.orm import relationship
from datetime import datetime
from ..db import Base
import uuid


class SurveyResult(Base):
    """Stores complete survey results with findings."""

    __tablename__ = "survey_results"
    __allow_unmapped__ = (
        True  # Silence SQLAlchemy 2.0 warnings until migration to Mapped[]
    )

    id: str = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    account_id: str = Column(String, ForeignKey("accounts.id"), nullable=False)
    integration_id: str = Column(String, ForeignKey("integrations.id"), nullable=False)

    # Survey metadata
    started_at: datetime = Column(DateTime, default=datetime.utcnow)
    completed_at: Optional[datetime] = Column(DateTime)
    duration_seconds: Optional[float] = Column(Float)
    status: str = Column(String, default="running")  # running, complete, error, partial

    # Results
    records_analyzed: Optional[int] = Column(Integer)
    duplicates_found: Optional[int] = Column(Integer)
    enrichment_opportunities: Optional[int] = Column(Integer)
    data_quality_score: Optional[float] = Column(Float)
    grade: Optional[str] = Column(String)

    # Raw data (JSONB for fast queries)
    raw_results: Optional[Dict[str, Any]] = Column(JSON)  # Full survey output
    field_stats: Optional[Dict[str, Any]] = Column(JSON)  # Per-field statistics
    proposed_policies: Optional[Dict[str, Any]] = Column(
        JSON
    )  # Auto-generated policies
    insights: Optional[List[Dict[str, Any]]] = Column(
        JSON
    )  # Actionable recommendations

    # Relationships
    findings: List[Any] = relationship(
        "SurveyFinding", back_populates="survey", cascade="all, delete-orphan"
    )
    account: Optional[Any] = relationship("Account", back_populates="survey_results")
    integration: Optional[Any] = relationship("Integration")

    # Indexes for performance
    __table_args__ = (
        Index("idx_survey_account_status", "account_id", "status"),
        Index("idx_survey_completed", "completed_at"),
        {"extend_existing": True},
    )


class SurveyFinding(Base):
    """Individual duplicate/enrichment finding from survey."""

    __tablename__ = "survey_findings"
    __allow_unmapped__ = (
        True  # Silence SQLAlchemy 2.0 warnings until migration to Mapped[]
    )

    id: str = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    survey_id: str = Column(String, ForeignKey("survey_results.id"), nullable=False)

    # Finding details
    object_type: Optional[str] = Column(String)  # Account, Lead, Contact
    finding_type: Optional[str] = Column(String)  # duplicate, enrichment, quality_issue

    # For duplicates
    record_ids: Optional[List[str]] = Column(JSON)  # List of SF record IDs
    confidence_score: Optional[float] = Column(Float)
    confidence_tier: Optional[str] = Column(String)  # CERTAIN, LIKELY, POSSIBLE, REVIEW
    match_reasons: Optional[Dict[str, Any]] = Column(JSON)  # Field contributions
    explanation: Optional[str] = Column(String)  # Human-readable explanation

    # For enrichment opportunities
    field_name: Optional[str] = Column(String)
    issue_type: Optional[str] = Column(
        String
    )  # missing, invalid, stale, personal_email
    suggested_value: Optional[str] = Column(String)
    suggested_provider: Optional[str] = Column(String)

    # Action tracking
    status: str = Column(
        String, default="pending"
    )  # pending, accepted, rejected, merged
    actioned_at: Optional[datetime] = Column(DateTime)
    actioned_by: Optional[str] = Column(String)
    action_notes: Optional[str] = Column(String)

    # Relationships
    survey: Optional[Any] = relationship("SurveyResult", back_populates="findings")

    # Indexes
    __table_args__ = (
        Index("idx_finding_survey_type", "survey_id", "finding_type"),
        Index("idx_finding_status", "status"),
        Index("idx_finding_confidence", "confidence_score"),
        {"extend_existing": True},
    )


class SurveyProgress(Base):
    """Tracks survey progress for resumability."""

    __tablename__ = "survey_progress"
    __allow_unmapped__ = (
        True  # Silence SQLAlchemy 2.0 warnings until migration to Mapped[]
    )

    id: str = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    survey_id: str = Column(String, ForeignKey("survey_results.id"), unique=True)

    # Progress tracking
    current_phase: Optional[str] = Column(
        String
    )  # sampling, analyzing, finding_duplicates, complete
    current_object: Optional[str] = Column(String)  # Account, Lead, Contact
    records_processed: int = Column(Integer, default=0)
    total_records: Optional[int] = Column(Integer)

    # Checkpoint data for resume
    checkpoint_data: Optional[Dict[str, Any]] = Column(JSON)  # State to resume from
    last_updated: datetime = Column(
        DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
    )

    # Error tracking
    error_count: int = Column(Integer, default=0)
    last_error: Optional[str] = Column(String)

    __table_args__ = (
        Index("idx_progress_updated", "last_updated"),
        {"extend_existing": True},
    )
