"""
FastAPI routes for Service Module Registry.

Endpoints:
- /modules: Module listing and management
- /modules/overview: Module compliance overview
- /modules/{module_id}: Module details
- /modules/seed: Seed modules from data
- /modules/{module_id}/regulations: Add regulation mapping
"""

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 RegulationRepository
from .schemas import (
    ServiceModuleResponse, ServiceModuleListResponse, ServiceModuleDetailResponse,
    ModuleRegulationMappingCreate, ModuleRegulationMappingResponse,
    ModuleSeedRequest, ModuleSeedResponse, ModuleComplianceOverview,
)

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


# ============================================================================
# Service Module Registry
# ============================================================================

@router.get("/modules", response_model=ServiceModuleListResponse)
async def list_modules(
    service_type: Optional[str] = None,
    criticality: Optional[str] = None,
    processes_pii: Optional[bool] = None,
    ai_components: Optional[bool] = None,
    db: Session = Depends(get_db),
):
    """List all service modules with optional filters."""
    from ..db.repository import ServiceModuleRepository

    repo = ServiceModuleRepository(db)
    modules = repo.get_all(
        service_type=service_type,
        criticality=criticality,
        processes_pii=processes_pii,
        ai_components=ai_components,
    )

    # Count regulations and risks for each module
    results = []
    for m in modules:
        reg_count = len(m.regulation_mappings) if m.regulation_mappings else 0
        risk_count = len(m.module_risks) if m.module_risks else 0

        results.append(ServiceModuleResponse(
            id=m.id,
            name=m.name,
            display_name=m.display_name,
            description=m.description,
            service_type=m.service_type.value if m.service_type else None,
            port=m.port,
            technology_stack=m.technology_stack or [],
            repository_path=m.repository_path,
            docker_image=m.docker_image,
            data_categories=m.data_categories or [],
            processes_pii=m.processes_pii,
            processes_health_data=m.processes_health_data,
            ai_components=m.ai_components,
            criticality=m.criticality,
            owner_team=m.owner_team,
            owner_contact=m.owner_contact,
            is_active=m.is_active,
            compliance_score=m.compliance_score,
            last_compliance_check=m.last_compliance_check,
            created_at=m.created_at,
            updated_at=m.updated_at,
            regulation_count=reg_count,
            risk_count=risk_count,
        ))

    return ServiceModuleListResponse(modules=results, total=len(results))


@router.get("/modules/overview", response_model=ModuleComplianceOverview)
async def get_modules_overview(db: Session = Depends(get_db)):
    """Get overview statistics for all modules."""
    from ..db.repository import ServiceModuleRepository

    repo = ServiceModuleRepository(db)
    overview = repo.get_overview()

    return ModuleComplianceOverview(**overview)


@router.get("/modules/{module_id}", response_model=ServiceModuleDetailResponse)
async def get_module(module_id: str, db: Session = Depends(get_db)):
    """Get a specific module with its regulations and risks."""
    from ..db.repository import ServiceModuleRepository

    repo = ServiceModuleRepository(db)
    module = repo.get_with_regulations(module_id)

    if not module:
        # Try by name
        module = repo.get_by_name(module_id)
        if module:
            module = repo.get_with_regulations(module.id)

    if not module:
        raise HTTPException(status_code=404, detail=f"Module {module_id} not found")

    # Build regulation list
    regulations = []
    for mapping in (module.regulation_mappings or []):
        reg = mapping.regulation
        if reg:
            regulations.append({
                "code": reg.code,
                "name": reg.name,
                "relevance_level": mapping.relevance_level.value if mapping.relevance_level else "medium",
                "notes": mapping.notes,
            })

    # Build risk list
    risks = []
    for mr in (module.module_risks or []):
        risk = mr.risk
        if risk:
            risks.append({
                "risk_id": risk.risk_id,
                "title": risk.title,
                "inherent_risk": risk.inherent_risk.value if risk.inherent_risk else None,
                "module_risk_level": mr.module_risk_level.value if mr.module_risk_level else None,
            })

    return ServiceModuleDetailResponse(
        id=module.id,
        name=module.name,
        display_name=module.display_name,
        description=module.description,
        service_type=module.service_type.value if module.service_type else None,
        port=module.port,
        technology_stack=module.technology_stack or [],
        repository_path=module.repository_path,
        docker_image=module.docker_image,
        data_categories=module.data_categories or [],
        processes_pii=module.processes_pii,
        processes_health_data=module.processes_health_data,
        ai_components=module.ai_components,
        criticality=module.criticality,
        owner_team=module.owner_team,
        owner_contact=module.owner_contact,
        is_active=module.is_active,
        compliance_score=module.compliance_score,
        last_compliance_check=module.last_compliance_check,
        created_at=module.created_at,
        updated_at=module.updated_at,
        regulation_count=len(regulations),
        risk_count=len(risks),
        regulations=regulations,
        risks=risks,
    )


@router.post("/modules/seed", response_model=ModuleSeedResponse)
async def seed_modules(
    request: ModuleSeedRequest,
    db: Session = Depends(get_db),
):
    """Seed service modules from predefined data."""
    from classroom_engine.database import engine
    from ..db.models import ServiceModuleDB, ModuleRegulationMappingDB, ModuleRiskDB
    from ..db.repository import ServiceModuleRepository
    from ..data.service_modules import BREAKPILOT_SERVICES

    try:
        # Ensure tables exist
        ServiceModuleDB.__table__.create(engine, checkfirst=True)
        ModuleRegulationMappingDB.__table__.create(engine, checkfirst=True)
        ModuleRiskDB.__table__.create(engine, checkfirst=True)

        repo = ServiceModuleRepository(db)
        result = repo.seed_from_data(BREAKPILOT_SERVICES, force=request.force)

        return ModuleSeedResponse(
            success=True,
            message=f"Seeded {result['modules_created']} modules with {result['mappings_created']} regulation mappings",
            modules_created=result["modules_created"],
            mappings_created=result["mappings_created"],
        )
    except Exception as e:
        logger.error(f"Module seeding failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/modules/{module_id}/regulations", response_model=ModuleRegulationMappingResponse)
async def add_module_regulation(
    module_id: str,
    mapping: ModuleRegulationMappingCreate,
    db: Session = Depends(get_db),
):
    """Add a regulation mapping to a module."""
    from ..db.repository import ServiceModuleRepository

    repo = ServiceModuleRepository(db)
    module = repo.get_by_id(module_id)

    if not module:
        module = repo.get_by_name(module_id)

    if not module:
        raise HTTPException(status_code=404, detail=f"Module {module_id} not found")

    # Verify regulation exists
    reg_repo = RegulationRepository(db)
    regulation = reg_repo.get_by_id(mapping.regulation_id)
    if not regulation:
        regulation = reg_repo.get_by_code(mapping.regulation_id)
    if not regulation:
        raise HTTPException(status_code=404, detail=f"Regulation {mapping.regulation_id} not found")

    try:
        new_mapping = repo.add_regulation_mapping(
            module_id=module.id,
            regulation_id=regulation.id,
            relevance_level=mapping.relevance_level,
            notes=mapping.notes,
            applicable_articles=mapping.applicable_articles,
        )

        return ModuleRegulationMappingResponse(
            id=new_mapping.id,
            module_id=new_mapping.module_id,
            regulation_id=new_mapping.regulation_id,
            relevance_level=new_mapping.relevance_level.value if new_mapping.relevance_level else "medium",
            notes=new_mapping.notes,
            applicable_articles=new_mapping.applicable_articles,
            module_name=module.name,
            regulation_code=regulation.code,
            regulation_name=regulation.name,
            created_at=new_mapping.created_at,
        )
    except Exception as e:
        logger.error(f"Failed to add regulation mapping: {e}")
        raise HTTPException(status_code=500, detail=str(e))
