"""
Team Dashboard Models - Component-Centric Architecture

Following expert recommendation: Component is the central entity,
with team-specific views as relationships.

Expert insight: "Teams are *views*; Components are the *truth*."
"""

from pydantic import BaseModel, Field
from typing import Optional, List, Dict, Any
from datetime import datetime
from enum import Enum


class TeamRole(str, Enum):
    """Team roles for dashboard views"""
    QA = "qa"
    UI = "ui"
    UX = "ux"
    ADMIN = "admin"


class TokenSource(str, Enum):
    """Source of design tokens"""
    FIGMA = "figma"
    CSS = "css"
    SCSS = "scss"
    TAILWIND = "tailwind"
    JSON = "json"
    CODE = "code"


class ComplianceStatus(str, Enum):
    """Compliance check status"""
    PASS = "pass"
    FAIL = "fail"
    WARNING = "warning"
    MISSING = "missing"


class Severity(str, Enum):
    """Issue severity levels"""
    CRITICAL = "critical"
    HIGH = "high"
    MEDIUM = "medium"
    LOW = "low"
    INFO = "info"


# ============================================================================
# Component-Centric Core Models
# ============================================================================

class ComponentToken(BaseModel):
    """
    Tracks which design tokens a component uses (UX Team View)

    Enables queries like:
    - "Which components use the old 'blue-500' token?"
    - "Show me all components using color tokens from Figma"
    """
    id: Optional[int] = None
    component_id: int
    token_name: str = Field(..., description="e.g., 'color-primary-500'")
    token_value: str = Field(..., description="Resolved value, e.g., '#3B82F6'")
    source: TokenSource = Field(..., description="Where this token came from")
    source_file: Optional[str] = Field(None, description="File path if from code")
    source_line: Optional[int] = Field(None, description="Line number if from code")
    figma_node_id: Optional[str] = Field(None, description="Figma node ID if from Figma")
    last_synced: Optional[datetime] = None
    metadata: Dict[str, Any] = Field(default_factory=dict)


class CodeMetric(BaseModel):
    """
    Tracks implementation details (UI Team View)

    Enables queries like:
    - "Which components have high complexity but low test coverage?"
    - "Show me components with the most props"
    """
    id: Optional[int] = None
    component_id: int
    file_path: str
    sloc: int = Field(..., description="Source lines of code")
    complexity_score: float = Field(..., description="Cyclomatic complexity")
    prop_count: int = Field(0, description="Number of props/parameters")
    has_tests: bool = Field(False)
    test_coverage: float = Field(0.0, description="Test coverage percentage")
    dependencies_count: int = Field(0, description="Number of dependencies")
    last_analyzed: datetime
    metadata: Dict[str, Any] = Field(default_factory=dict)


class TestResult(BaseModel):
    """
    Tracks compliance and regression tests (QA Team View)

    Enables queries like:
    - "Which components failed the last ESRE check?"
    - "Show me components with regressions"
    """
    id: Optional[int] = None
    component_id: int
    test_type: str = Field(..., description="'esre', 'regression', 'visual', 'unit'")
    passed: bool
    score: Optional[float] = Field(None, description="0.0-1.0 score if applicable")
    failures: List[str] = Field(default_factory=list, description="List of failures")
    diff_summary: Optional[Dict[str, Any]] = None
    snapshot_id: Optional[int] = Field(None, description="Reference to snapshot")
    run_at: datetime
    run_by: str = Field("system", description="User or system that ran test")
    metadata: Dict[str, Any] = Field(default_factory=dict)


# ============================================================================
# Supporting Models for Team Dashboards
# ============================================================================

class FigmaFile(BaseModel):
    """
    Figma file tracking (UX Dashboard)

    Supports multiple Figma files per project
    """
    id: Optional[int] = None
    project_id: int
    figma_url: str
    file_name: str
    file_key: str
    file_type: str = Field("design", description="'design' or 'dev'")
    last_synced: Optional[datetime] = None
    sync_status: str = Field("pending", description="'pending', 'syncing', 'success', 'error'")
    error_message: Optional[str] = None
    metadata: Dict[str, Any] = Field(default_factory=dict)


class ImplementationSnapshot(BaseModel):
    """
    Implementation snapshot for regression testing (UI Dashboard)

    "Golden Master" approach for comparison
    """
    id: Optional[int] = None
    project_id: int
    snapshot_name: str
    description: Optional[str] = None
    tokens_json: Dict[str, Any] = Field(..., description="W3C DTCG format tokens")
    files_hash: str = Field(..., description="Hash of all files for quick comparison")
    component_count: int = Field(0)
    token_count: int = Field(0)
    created_at: datetime
    created_by: str
    is_baseline: bool = Field(False, description="Is this the baseline 'Golden Master'?")
    metadata: Dict[str, Any] = Field(default_factory=dict)


class ESREDefinition(BaseModel):
    """
    ESRE (Expected System Response Evaluation) Definition (QA Dashboard)

    Natural language requirements that should be validated
    """
    id: Optional[int] = None
    project_id: int
    name: str = Field(..., description="Requirement name, e.g., 'Primary Button Color'")
    definition_text: str = Field(..., description="Natural language definition")
    expected_value: Optional[str] = Field(None, description="Expected value if parseable")
    token_type: Optional[str] = Field(None, description="Detected token type")
    component_name: Optional[str] = Field(None, description="Associated component")
    created_at: datetime
    created_by: str
    validated: bool = Field(False)
    last_check: Optional[datetime] = None
    metadata: Dict[str, Any] = Field(default_factory=dict)


class TokenDrift(BaseModel):
    """
    Token drift detection result (UI Dashboard)

    Tracks when code uses values that differ from design tokens
    """
    id: Optional[int] = None
    component_id: int
    property_name: str = Field(..., description="CSS property or prop name")
    hardcoded_value: str = Field(..., description="The hardcoded value found")
    suggested_token: Optional[str] = Field(None, description="Suggested token to use")
    confidence: float = Field(..., description="0.0-1.0 confidence in suggestion")
    severity: Severity
    file_path: str
    line_number: int
    detected_at: datetime
    resolved: bool = Field(False)
    metadata: Dict[str, Any] = Field(default_factory=dict)


# ============================================================================
# Dashboard View Models (API Responses)
# ============================================================================

class DashboardSummary(BaseModel):
    """
    Summary for dashboard overview

    This is the "thin slice" endpoint response
    """
    project_id: int
    project_name: str
    total_components: int

    # UX metrics
    figma_files_count: int
    figma_sync_status: str
    total_tokens: int

    # UI metrics
    token_drift_count: int
    high_complexity_components: int
    low_coverage_components: int

    # QA metrics
    esre_definitions_count: int
    failed_tests_count: int
    regression_issues_count: int

    last_updated: datetime
    metadata: Dict[str, Any] = Field(default_factory=dict)


class QADashboardView(BaseModel):
    """QA Dashboard data"""
    esre_definitions: List[ESREDefinition]
    failed_tests: List[TestResult]
    compliance_rate: float
    recent_checks: List[TestResult]


class UIDashboardView(BaseModel):
    """UI Dashboard data"""
    token_drifts: List[TokenDrift]
    high_complexity_components: List[Dict[str, Any]]
    recent_snapshots: List[ImplementationSnapshot]
    metrics_summary: Dict[str, Any]


class UXDashboardView(BaseModel):
    """UX Dashboard data"""
    figma_files: List[FigmaFile]
    component_tokens: List[ComponentToken]
    recent_syncs: List[Dict[str, Any]]
    sync_status: Dict[str, Any]
