"""
FastAPI routes for Risk management.

Endpoints:
- /risks: Risk listing and CRUD
- /risks/matrix: Risk matrix visualization
"""

import logging
from typing import Optional

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

from classroom_engine.database import get_db

from ..db import RiskRepository, RiskLevelEnum
from .schemas import (
    RiskCreate, RiskUpdate, RiskResponse, RiskListResponse, RiskMatrixResponse,
)

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


# ============================================================================
# Risks
# ============================================================================

@router.get("/risks", response_model=RiskListResponse)
async def list_risks(
    category: Optional[str] = None,
    status: Optional[str] = None,
    risk_level: Optional[str] = None,
    db: Session = Depends(get_db),
):
    """List risks with optional filters."""
    repo = RiskRepository(db)
    risks = repo.get_all()

    if category:
        risks = [r for r in risks if r.category == category]

    if status:
        risks = [r for r in risks if r.status == status]

    if risk_level:
        try:
            level = RiskLevelEnum(risk_level)
            risks = [r for r in risks if r.inherent_risk == level]
        except ValueError:
            pass

    results = [
        RiskResponse(
            id=r.id,
            risk_id=r.risk_id,
            title=r.title,
            description=r.description,
            category=r.category,
            likelihood=r.likelihood,
            impact=r.impact,
            inherent_risk=r.inherent_risk.value if r.inherent_risk else None,
            mitigating_controls=r.mitigating_controls,
            residual_likelihood=r.residual_likelihood,
            residual_impact=r.residual_impact,
            residual_risk=r.residual_risk.value if r.residual_risk else None,
            owner=r.owner,
            status=r.status,
            treatment_plan=r.treatment_plan,
            identified_date=r.identified_date,
            review_date=r.review_date,
            last_assessed_at=r.last_assessed_at,
            created_at=r.created_at,
            updated_at=r.updated_at,
        )
        for r in risks
    ]

    return RiskListResponse(risks=results, total=len(results))


@router.post("/risks", response_model=RiskResponse)
async def create_risk(
    risk_data: RiskCreate,
    db: Session = Depends(get_db),
):
    """Create a new risk."""
    repo = RiskRepository(db)
    risk = repo.create(
        risk_id=risk_data.risk_id,
        title=risk_data.title,
        description=risk_data.description,
        category=risk_data.category,
        likelihood=risk_data.likelihood,
        impact=risk_data.impact,
        mitigating_controls=risk_data.mitigating_controls,
        owner=risk_data.owner,
        treatment_plan=risk_data.treatment_plan,
    )
    db.commit()

    return RiskResponse(
        id=risk.id,
        risk_id=risk.risk_id,
        title=risk.title,
        description=risk.description,
        category=risk.category,
        likelihood=risk.likelihood,
        impact=risk.impact,
        inherent_risk=risk.inherent_risk.value if risk.inherent_risk else None,
        mitigating_controls=risk.mitigating_controls,
        residual_likelihood=risk.residual_likelihood,
        residual_impact=risk.residual_impact,
        residual_risk=risk.residual_risk.value if risk.residual_risk else None,
        owner=risk.owner,
        status=risk.status,
        treatment_plan=risk.treatment_plan,
        identified_date=risk.identified_date,
        review_date=risk.review_date,
        last_assessed_at=risk.last_assessed_at,
        created_at=risk.created_at,
        updated_at=risk.updated_at,
    )


@router.put("/risks/{risk_id}", response_model=RiskResponse)
async def update_risk(
    risk_id: str,
    update: RiskUpdate,
    db: Session = Depends(get_db),
):
    """Update a risk."""
    repo = RiskRepository(db)
    risk = repo.get_by_risk_id(risk_id)
    if not risk:
        raise HTTPException(status_code=404, detail=f"Risk {risk_id} not found")

    update_data = update.model_dump(exclude_unset=True)
    updated = repo.update(risk.id, **update_data)
    db.commit()

    return RiskResponse(
        id=updated.id,
        risk_id=updated.risk_id,
        title=updated.title,
        description=updated.description,
        category=updated.category,
        likelihood=updated.likelihood,
        impact=updated.impact,
        inherent_risk=updated.inherent_risk.value if updated.inherent_risk else None,
        mitigating_controls=updated.mitigating_controls,
        residual_likelihood=updated.residual_likelihood,
        residual_impact=updated.residual_impact,
        residual_risk=updated.residual_risk.value if updated.residual_risk else None,
        owner=updated.owner,
        status=updated.status,
        treatment_plan=updated.treatment_plan,
        identified_date=updated.identified_date,
        review_date=updated.review_date,
        last_assessed_at=updated.last_assessed_at,
        created_at=updated.created_at,
        updated_at=updated.updated_at,
    )


@router.delete("/risks/{risk_id}")
async def delete_risk(
    risk_id: str,
    db: Session = Depends(get_db),
):
    """Delete a risk."""
    repo = RiskRepository(db)
    risk = repo.get_by_risk_id(risk_id)
    if not risk:
        raise HTTPException(status_code=404, detail=f"Risk {risk_id} not found")

    db.delete(risk)
    db.commit()

    logger.info(f"Risk {risk_id} deleted")
    return {"success": True, "message": f"Risk {risk_id} deleted"}


@router.get("/risks/matrix", response_model=RiskMatrixResponse)
async def get_risk_matrix(db: Session = Depends(get_db)):
    """Get risk matrix data for visualization."""
    repo = RiskRepository(db)
    matrix_data = repo.get_risk_matrix()
    risks = repo.get_all()

    risk_responses = [
        RiskResponse(
            id=r.id,
            risk_id=r.risk_id,
            title=r.title,
            description=r.description,
            category=r.category,
            likelihood=r.likelihood,
            impact=r.impact,
            inherent_risk=r.inherent_risk.value if r.inherent_risk else None,
            mitigating_controls=r.mitigating_controls,
            residual_likelihood=r.residual_likelihood,
            residual_impact=r.residual_impact,
            residual_risk=r.residual_risk.value if r.residual_risk else None,
            owner=r.owner,
            status=r.status,
            treatment_plan=r.treatment_plan,
            identified_date=r.identified_date,
            review_date=r.review_date,
            last_assessed_at=r.last_assessed_at,
            created_at=r.created_at,
            updated_at=r.updated_at,
        )
        for r in risks
    ]

    return RiskMatrixResponse(matrix=matrix_data, risks=risk_responses)
