"""
FastAPI routes for AI Act Compliance — AI System CRUD.

Endpoints:
- /ai/systems: List/Create AI systems
- /ai/systems/{id}: Get/Update/Delete AI system
- /ai/systems/{id}/assess: Run AI Act risk assessment
"""

import logging
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session

from classroom_engine.database import get_db

from ..db.models import AISystemDB, AIClassificationEnum, AISystemStatusEnum
from .schemas import (
    AISystemCreate, AISystemUpdate, AISystemResponse, AISystemListResponse,
)

logger = logging.getLogger(__name__)
router = APIRouter(tags=["compliance-ai"])


# ============================================================================
# AI System CRUD Endpoints (AI Act Compliance)
# ============================================================================

@router.get("/ai/systems", response_model=AISystemListResponse)
async def list_ai_systems(
    classification: Optional[str] = Query(None, description="Filter by classification"),
    status: Optional[str] = Query(None, description="Filter by status"),
    sector: Optional[str] = Query(None, description="Filter by sector"),
    db: Session = Depends(get_db),
):
    """List all registered AI systems."""
    query = db.query(AISystemDB)

    if classification:
        try:
            cls_enum = AIClassificationEnum(classification)
            query = query.filter(AISystemDB.classification == cls_enum)
        except ValueError:
            pass

    if status:
        try:
            status_enum = AISystemStatusEnum(status)
            query = query.filter(AISystemDB.status == status_enum)
        except ValueError:
            pass

    if sector:
        query = query.filter(AISystemDB.sector.ilike(f"%{sector}%"))

    systems = query.order_by(AISystemDB.created_at.desc()).all()

    results = [
        AISystemResponse(
            id=s.id,
            name=s.name,
            description=s.description,
            purpose=s.purpose,
            sector=s.sector,
            classification=s.classification.value if s.classification else "unclassified",
            status=s.status.value if s.status else "draft",
            obligations=s.obligations or [],
            assessment_date=s.assessment_date,
            assessment_result=s.assessment_result,
            risk_factors=s.risk_factors,
            recommendations=s.recommendations,
            created_at=s.created_at,
            updated_at=s.updated_at,
        )
        for s in systems
    ]

    return AISystemListResponse(systems=results, total=len(results))


@router.post("/ai/systems", response_model=AISystemResponse)
async def create_ai_system(
    data: AISystemCreate,
    db: Session = Depends(get_db),
):
    """Register a new AI system."""
    import uuid as _uuid

    try:
        cls_enum = AIClassificationEnum(data.classification) if data.classification else AIClassificationEnum.UNCLASSIFIED
    except ValueError:
        cls_enum = AIClassificationEnum.UNCLASSIFIED

    try:
        status_enum = AISystemStatusEnum(data.status) if data.status else AISystemStatusEnum.DRAFT
    except ValueError:
        status_enum = AISystemStatusEnum.DRAFT

    system = AISystemDB(
        id=str(_uuid.uuid4()),
        name=data.name,
        description=data.description,
        purpose=data.purpose,
        sector=data.sector,
        classification=cls_enum,
        status=status_enum,
        obligations=data.obligations or [],
    )
    db.add(system)
    db.commit()
    db.refresh(system)

    return AISystemResponse(
        id=system.id,
        name=system.name,
        description=system.description,
        purpose=system.purpose,
        sector=system.sector,
        classification=system.classification.value if system.classification else "unclassified",
        status=system.status.value if system.status else "draft",
        obligations=system.obligations or [],
        assessment_date=system.assessment_date,
        assessment_result=system.assessment_result,
        risk_factors=system.risk_factors,
        recommendations=system.recommendations,
        created_at=system.created_at,
        updated_at=system.updated_at,
    )


@router.get("/ai/systems/{system_id}", response_model=AISystemResponse)
async def get_ai_system(system_id: str, db: Session = Depends(get_db)):
    """Get a specific AI system by ID."""
    system = db.query(AISystemDB).filter(AISystemDB.id == system_id).first()
    if not system:
        raise HTTPException(status_code=404, detail=f"AI System {system_id} not found")

    return AISystemResponse(
        id=system.id,
        name=system.name,
        description=system.description,
        purpose=system.purpose,
        sector=system.sector,
        classification=system.classification.value if system.classification else "unclassified",
        status=system.status.value if system.status else "draft",
        obligations=system.obligations or [],
        assessment_date=system.assessment_date,
        assessment_result=system.assessment_result,
        risk_factors=system.risk_factors,
        recommendations=system.recommendations,
        created_at=system.created_at,
        updated_at=system.updated_at,
    )


@router.put("/ai/systems/{system_id}", response_model=AISystemResponse)
async def update_ai_system(
    system_id: str,
    data: AISystemUpdate,
    db: Session = Depends(get_db),
):
    """Update an AI system."""
    from datetime import datetime, timezone

    system = db.query(AISystemDB).filter(AISystemDB.id == system_id).first()
    if not system:
        raise HTTPException(status_code=404, detail=f"AI System {system_id} not found")

    update_data = data.model_dump(exclude_unset=True)

    if "classification" in update_data:
        try:
            update_data["classification"] = AIClassificationEnum(update_data["classification"])
        except ValueError:
            raise HTTPException(status_code=400, detail=f"Invalid classification: {update_data['classification']}")

    if "status" in update_data:
        try:
            update_data["status"] = AISystemStatusEnum(update_data["status"])
        except ValueError:
            raise HTTPException(status_code=400, detail=f"Invalid status: {update_data['status']}")

    for key, value in update_data.items():
        if hasattr(system, key):
            setattr(system, key, value)

    system.updated_at = datetime.now(timezone.utc)
    db.commit()
    db.refresh(system)

    return AISystemResponse(
        id=system.id,
        name=system.name,
        description=system.description,
        purpose=system.purpose,
        sector=system.sector,
        classification=system.classification.value if system.classification else "unclassified",
        status=system.status.value if system.status else "draft",
        obligations=system.obligations or [],
        assessment_date=system.assessment_date,
        assessment_result=system.assessment_result,
        risk_factors=system.risk_factors,
        recommendations=system.recommendations,
        created_at=system.created_at,
        updated_at=system.updated_at,
    )


@router.delete("/ai/systems/{system_id}")
async def delete_ai_system(system_id: str, db: Session = Depends(get_db)):
    """Delete an AI system."""
    system = db.query(AISystemDB).filter(AISystemDB.id == system_id).first()
    if not system:
        raise HTTPException(status_code=404, detail=f"AI System {system_id} not found")

    db.delete(system)
    db.commit()
    return {"success": True, "message": "AI System deleted"}


@router.post("/ai/systems/{system_id}/assess", response_model=AISystemResponse)
async def assess_ai_system(
    system_id: str,
    db: Session = Depends(get_db),
):
    """Run AI Act risk assessment for an AI system."""
    from datetime import datetime, timezone

    system = db.query(AISystemDB).filter(AISystemDB.id == system_id).first()
    if not system:
        raise HTTPException(status_code=404, detail=f"AI System {system_id} not found")

    # Try AI-based assessment
    assessment_result = None
    try:
        from ..services.ai_compliance_assistant import get_ai_assistant
        assistant = get_ai_assistant()
        result = await assistant.assess_module_risk(
            module_name=system.name,
            service_type="ai_system",
            description=system.description or "",
            processes_pii=True,
            ai_components=True,
            criticality="high",
            data_categories=[],
            regulations=[{"code": "AI-ACT", "relevance": "high"}],
        )
        assessment_result = {
            "overall_risk": result.overall_risk,
            "risk_factors": result.risk_factors,
            "recommendations": result.recommendations,
            "compliance_gaps": result.compliance_gaps,
            "confidence_score": result.confidence_score,
        }
    except Exception as e:
        logger.warning(f"AI assessment failed for {system_id}, using rule-based: {e}")
        # Rule-based fallback
        assessment_result = _rule_based_assessment(system)

    # Update system with assessment results
    classification = _derive_classification(assessment_result)
    try:
        system.classification = AIClassificationEnum(classification)
    except ValueError:
        system.classification = AIClassificationEnum.UNCLASSIFIED

    system.assessment_date = datetime.now(timezone.utc)
    system.assessment_result = assessment_result
    system.obligations = _derive_obligations(classification)
    system.risk_factors = assessment_result.get("risk_factors", [])
    system.recommendations = assessment_result.get("recommendations", [])
    system.status = AISystemStatusEnum.CLASSIFIED

    db.commit()
    db.refresh(system)

    return AISystemResponse(
        id=system.id,
        name=system.name,
        description=system.description,
        purpose=system.purpose,
        sector=system.sector,
        classification=system.classification.value if system.classification else "unclassified",
        status=system.status.value if system.status else "draft",
        obligations=system.obligations or [],
        assessment_date=system.assessment_date,
        assessment_result=system.assessment_result,
        risk_factors=system.risk_factors,
        recommendations=system.recommendations,
        created_at=system.created_at,
        updated_at=system.updated_at,
    )


def _rule_based_assessment(system: AISystemDB) -> dict:
    """Simple rule-based AI Act classification when AI service is unavailable."""
    desc = (system.description or "").lower() + " " + (system.purpose or "").lower()
    sector = (system.sector or "").lower()

    risk_factors = []
    risk_score = 0

    # Check for prohibited use cases
    prohibited_keywords = ["social scoring", "biometric surveillance", "emotion recognition", "subliminal manipulation"]
    for kw in prohibited_keywords:
        if kw in desc:
            risk_factors.append({"factor": f"Prohibited use case: {kw}", "severity": "critical", "likelihood": "high"})
            risk_score += 10

    # Check for high-risk indicators
    high_risk_keywords = ["education", "employment", "credit scoring", "law enforcement", "migration", "critical infrastructure", "medical", "bildung", "gesundheit"]
    for kw in high_risk_keywords:
        if kw in desc or kw in sector:
            risk_factors.append({"factor": f"High-risk sector: {kw}", "severity": "high", "likelihood": "medium"})
            risk_score += 5

    # Check for limited-risk indicators
    limited_keywords = ["chatbot", "deepfake", "emotion", "biometric"]
    for kw in limited_keywords:
        if kw in desc:
            risk_factors.append({"factor": f"Transparency requirement: {kw}", "severity": "medium", "likelihood": "high"})
            risk_score += 3

    return {
        "overall_risk": "critical" if risk_score >= 10 else "high" if risk_score >= 5 else "medium" if risk_score >= 3 else "low",
        "risk_factors": risk_factors,
        "recommendations": [
            "Dokumentation des AI-Systems vervollstaendigen",
            "Risikomanagement-Framework implementieren",
            "Transparenzpflichten pruefen",
        ],
        "compliance_gaps": [],
        "confidence_score": 0.6,
        "risk_score": risk_score,
    }


def _derive_classification(assessment: dict) -> str:
    """Derive AI Act classification from assessment result."""
    risk = assessment.get("overall_risk", "medium")
    score = assessment.get("risk_score", 0)

    if score >= 10:
        return "prohibited"
    elif risk in ("critical", "high") or score >= 5:
        return "high-risk"
    elif risk == "medium" or score >= 3:
        return "limited-risk"
    else:
        return "minimal-risk"


def _derive_obligations(classification: str) -> list:
    """Derive AI Act obligations based on classification."""
    obligations_map = {
        "prohibited": ["Einsatz verboten (Art. 5 AI Act)"],
        "high-risk": [
            "Risikomanagementsystem (Art. 9)",
            "Daten-Governance (Art. 10)",
            "Technische Dokumentation (Art. 11)",
            "Aufzeichnungspflicht (Art. 12)",
            "Transparenz (Art. 13)",
            "Menschliche Aufsicht (Art. 14)",
            "Genauigkeit & Robustheit (Art. 15)",
            "Konformitaetsbewertung (Art. 43)",
        ],
        "limited-risk": [
            "Transparenzpflicht (Art. 52)",
            "Kennzeichnung als KI-System",
        ],
        "minimal-risk": [
            "Freiwillige Verhaltenskodizes (Art. 69)",
        ],
    }
    return obligations_map.get(classification, [])
