"""Pydantic schemas for Detection Lifecycle endpoints."""

from pydantic import BaseModel, Field, ConfigDict
from typing import Optional
from uuid import UUID
from datetime import datetime
from app.models.detection_lifecycle import (
    DetectionConfidence, DetectionHealthStatus, InvalidationReason
)


class DetectionAssetCreate(BaseModel):
    name: str = Field(..., min_length=3, max_length=500)
    description: Optional[str] = None
    asset_type: str = Field(..., pattern=r'^(siem_rule|edr_rule|sigma_rule|yara_rule|spl_query|kql_query|custom_script)$')
    platform: Optional[str] = None
    rule_content: Optional[str] = None
    rule_language: Optional[str] = None
    rule_repository_url: Optional[str] = None
    rule_file_path: Optional[str] = None
    rule_version: Optional[str] = None
    log_source_name: Optional[str] = None
    log_source_version: Optional[str] = None
    log_source_config: Optional[dict] = Field(default_factory=dict)
    infrastructure_details: Optional[dict] = Field(default_factory=dict)
    expected_alert_frequency: Optional[str] = None
    tags: Optional[list[str]] = Field(default_factory=list)
    technique_ids: Optional[list[UUID]] = Field(default_factory=list)


class DetectionAssetUpdate(BaseModel):
    name: Optional[str] = None
    description: Optional[str] = None
    rule_content: Optional[str] = None
    rule_version: Optional[str] = None
    log_source_version: Optional[str] = None
    infrastructure_details: Optional[dict] = None
    expected_alert_frequency: Optional[str] = None
    health_status: Optional[DetectionHealthStatus] = None
    last_alert_at: Optional[datetime] = None
    alert_count_30d: Optional[int] = None
    false_positive_rate: Optional[float] = None
    owner_id: Optional[UUID] = None
    backup_owner_id: Optional[UUID] = None
    team: Optional[str] = None
    tags: Optional[list[str]] = None
    is_active: Optional[bool] = None


class DetectionAssetOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: UUID
    name: str
    description: Optional[str] = None
    asset_type: str
    platform: Optional[str] = None
    rule_language: Optional[str] = None
    rule_version: Optional[str] = None
    rule_hash: Optional[str] = None
    health_status: DetectionHealthStatus
    last_alert_at: Optional[datetime] = None
    alert_count_30d: int
    false_positive_rate: Optional[float] = None
    expected_alert_frequency: Optional[str] = None
    owner_id: Optional[UUID] = None
    team: Optional[str] = None
    is_active: bool
    tags: list = Field(default_factory=list)
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


class DetectionValidationCreate(BaseModel):
    detection_asset_id: UUID
    technique_id: Optional[UUID] = None
    test_id: Optional[UUID] = None
    validation_result: str = Field(..., pattern=r'^(detected|not_detected|partial|error)$')
    validation_method: str
    notes: Optional[str] = None
    evidence_ids: Optional[list[UUID]] = Field(default_factory=list)
    validity_days: int = Field(default=180, ge=30, le=730)


class DetectionValidationOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: UUID
    detection_asset_id: UUID
    technique_id: Optional[UUID] = None
    validated_at: Optional[datetime] = None
    expires_at: datetime
    is_valid: bool
    validation_result: Optional[str] = None
    validation_method: Optional[str] = None
    invalidated_at: Optional[datetime] = None
    invalidation_reason: Optional[InvalidationReason] = None
    validated_by: Optional[UUID] = None
    notes: Optional[str] = None


class TechniqueConfidenceOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    technique_id: UUID
    confidence_level: DetectionConfidence
    confidence_score: float
    detection_count: int
    valid_detection_count: int
    last_validated_at: Optional[datetime] = None
    next_validation_due: Optional[datetime] = None
    recency_factor: float
    coverage_factor: float
    health_factor: float
    diversity_factor: float
    risk_factors: list = Field(default_factory=list)


class InfrastructureChangeCreate(BaseModel):
    change_type: str
    description: str = Field(..., min_length=10)
    affected_platforms: list[str] = Field(default_factory=list)
    affected_log_sources: list[str] = Field(default_factory=list)
    change_date: Optional[datetime] = None
    auto_invalidate: bool = True


class InfrastructureChangeOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: UUID
    change_type: str
    description: str
    affected_platforms: list = Field(default_factory=list)
    affected_log_sources: list = Field(default_factory=list)
    change_date: Optional[datetime] = None
    auto_invalidate: bool
    invalidated_count: int
    reported_by: Optional[UUID] = None
    created_at: Optional[datetime] = None
