"""
Autonomous Agent Types

Type definitions for the autonomous data factory agent system.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime, timezone
from enum import Enum
from typing import Any


class AgentPriority(str, Enum):
    """Agent execution priority"""
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    CRITICAL = "critical"


class HealthStatus(str, Enum):
    """Health status levels"""
    HEALTHY = "healthy"
    DEGRADED = "degraded"
    STALE = "stale"
    CRITICAL = "critical"
    UNKNOWN = "unknown"


class ApprovalStatus(str, Enum):
    """Human approval status"""
    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"
    EXPIRED = "expired"
    AUTO_APPROVED = "auto_approved"


class TriggerType(str, Enum):
    """Types of triggers for agent execution"""
    SCHEDULED = "scheduled"      # Cron-based trigger
    EVENT = "event"              # Event-driven trigger
    MANUAL = "manual"            # Human-initiated
    ALERT = "alert"              # Alert-triggered
    HEALTH_CHECK = "health_check"  # Health check triggered


@dataclass
class PipelineHealth:
    """Health status of a single pipeline"""
    module: str
    last_data_date: str | None
    hours_since_run: float | None
    status: HealthStatus
    records_count: int = 0
    quality_score: float = 1.0
    last_error: str | None = None
    checked_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))


@dataclass
class LayerHealth:
    """Health status of a data warehouse layer"""
    layer: str  # ods, dwd, dws, ads
    tables_count: int
    total_rows: int
    freshness_hours: float | None
    status: HealthStatus
    issues: list[str] = field(default_factory=list)
    checked_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))


@dataclass
class SystemHealth:
    """Overall system health report"""
    pipelines: list[PipelineHealth]
    layers: list[LayerHealth]
    overall_status: HealthStatus
    healthy_count: int
    degraded_count: int
    critical_count: int
    recommendations: list[str] = field(default_factory=list)
    generated_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary for JSON serialization"""
        return {
            "pipelines": [
                {
                    "module": p.module,
                    "last_data_date": p.last_data_date,
                    "hours_since_run": p.hours_since_run,
                    "status": p.status.value,
                    "records_count": p.records_count,
                    "quality_score": p.quality_score,
                    "last_error": p.last_error,
                }
                for p in self.pipelines
            ],
            "layers": [
                {
                    "layer": l.layer,
                    "tables_count": l.tables_count,
                    "total_rows": l.total_rows,
                    "freshness_hours": l.freshness_hours,
                    "status": l.status.value,
                    "issues": l.issues,
                }
                for l in self.layers
            ],
            "overall_status": self.overall_status.value,
            "healthy_count": self.healthy_count,
            "degraded_count": self.degraded_count,
            "critical_count": self.critical_count,
            "recommendations": self.recommendations,
            "generated_at": self.generated_at.isoformat(),
        }


@dataclass
class AgentDecision:
    """Decision made by the autonomous agent"""
    action: str
    reason: str
    priority: AgentPriority
    requires_approval: bool
    parameters: dict[str, Any] = field(default_factory=dict)
    estimated_impact: str = ""
    created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))


@dataclass
class ApprovalRequest:
    """Request for human approval"""
    request_id: str
    decision: AgentDecision
    status: ApprovalStatus = ApprovalStatus.PENDING
    requester: str = "MasterOrchestratorAgent"
    approver: str | None = None
    expires_at: datetime | None = None
    created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
    resolved_at: datetime | None = None
    notes: str = ""


@dataclass
class AgentExecutionResult:
    """Result of an agent execution"""
    success: bool
    action: str
    trigger_type: TriggerType
    decision: AgentDecision | None = None
    approval: ApprovalRequest | None = None
    result_data: dict[str, Any] = field(default_factory=dict)
    duration_ms: float = 0.0
    tokens_used: int = 0
    errors: list[str] = field(default_factory=list)
    executed_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))


@dataclass
class ScheduledTask:
    """A scheduled task for the agent"""
    task_id: str
    cron_expression: str
    action: str
    parameters: dict[str, Any] = field(default_factory=dict)
    enabled: bool = True
    last_run: datetime | None = None
    next_run: datetime | None = None
    run_count: int = 0
    failure_count: int = 0


# Safety red lines - operations requiring human approval
HUMAN_APPROVAL_REQUIRED = [
    "DELETE",           # Any delete operation
    "TRUNCATE",         # Table truncation
    "DROP",             # Drop table/schema
    "rollback_24h",     # Rollback > 24 hours
    "new_data_source",  # New data source integration
    "modify_sla",       # SLA threshold changes
    "impact_downstream_3", # Impact > 3 downstream systems
    "cost_exceed_150",  # Cost > 150% of budget
    "consecutive_fail_5", # > 5 consecutive failures
]

# Freshness thresholds (hours)
FRESHNESS_THRESHOLDS = {
    "healthy": 24,      # < 24h = healthy
    "stale": 48,        # 24-48h = stale
    "critical": 72,     # > 48h = critical
}

# Quality thresholds
QUALITY_THRESHOLDS = {
    "healthy": 0.95,    # >= 95% = healthy
    "degraded": 0.90,   # 90-95% = degraded
    "critical": 0.85,   # < 85% = critical
}
