"""
FastAPI routes for Compliance module.

Endpoints:
- /regulations: Manage regulations
- /requirements: Manage requirements
- /controls: Manage controls
- /mappings: Requirement-Control mappings
- /evidence: Evidence management
- /risks: Risk management
- /dashboard: Dashboard statistics
- /export: Audit export
"""

import logging

logger = logging.getLogger(__name__)
import os
from datetime import datetime, timedelta
from typing import Optional, List

from pydantic import BaseModel
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Query, BackgroundTasks
from fastapi.responses import FileResponse
from sqlalchemy.orm import Session

from classroom_engine.database import get_db

from ..db import (
    RegulationRepository,
    RequirementRepository,
    ControlRepository,
    EvidenceRepository,
    RiskRepository,
    AuditExportRepository,
    ControlStatusEnum,
    ControlDomainEnum,
    RiskLevelEnum,
    EvidenceStatusEnum,
)
from ..db.models import EvidenceDB, ControlDB
from ..services.seeder import ComplianceSeeder
from ..services.export_generator import AuditExportGenerator
from ..services.auto_risk_updater import AutoRiskUpdater, ScanType
from .schemas import (
    RegulationCreate, RegulationResponse, RegulationListResponse,
    RequirementCreate, RequirementResponse, RequirementListResponse,
    ControlCreate, ControlUpdate, ControlResponse, ControlListResponse, ControlReviewRequest,
    MappingCreate, MappingResponse, MappingListResponse,
    ExportRequest, ExportResponse, ExportListResponse,
    SeedRequest, SeedResponse,
    # Pagination schemas
    PaginationMeta, PaginatedRequirementResponse, PaginatedControlResponse,
)

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/compliance", tags=["compliance"])


# ============================================================================
# Regulations
# ============================================================================

@router.get("/regulations", response_model=RegulationListResponse)
async def list_regulations(
    is_active: Optional[bool] = None,
    regulation_type: Optional[str] = None,
    db: Session = Depends(get_db),
):
    """List all regulations."""
    repo = RegulationRepository(db)
    if is_active is not None:
        regulations = repo.get_active() if is_active else repo.get_all()
    else:
        regulations = repo.get_all()

    if regulation_type:
        from ..db.models import RegulationTypeEnum
        try:
            reg_type = RegulationTypeEnum(regulation_type)
            regulations = [r for r in regulations if r.regulation_type == reg_type]
        except ValueError:
            pass

    # Add requirement counts
    req_repo = RequirementRepository(db)
    results = []
    for reg in regulations:
        reqs = req_repo.get_by_regulation(reg.id)
        reg_dict = {
            "id": reg.id,
            "code": reg.code,
            "name": reg.name,
            "full_name": reg.full_name,
            "regulation_type": reg.regulation_type.value if reg.regulation_type else None,
            "source_url": reg.source_url,
            "local_pdf_path": reg.local_pdf_path,
            "effective_date": reg.effective_date,
            "description": reg.description,
            "is_active": reg.is_active,
            "created_at": reg.created_at,
            "updated_at": reg.updated_at,
            "requirement_count": len(reqs),
        }
        results.append(RegulationResponse(**reg_dict))

    return RegulationListResponse(regulations=results, total=len(results))


@router.get("/regulations/{code}", response_model=RegulationResponse)
async def get_regulation(code: str, db: Session = Depends(get_db)):
    """Get a specific regulation by code."""
    repo = RegulationRepository(db)
    regulation = repo.get_by_code(code)
    if not regulation:
        raise HTTPException(status_code=404, detail=f"Regulation {code} not found")

    req_repo = RequirementRepository(db)
    reqs = req_repo.get_by_regulation(regulation.id)

    return RegulationResponse(
        id=regulation.id,
        code=regulation.code,
        name=regulation.name,
        full_name=regulation.full_name,
        regulation_type=regulation.regulation_type.value if regulation.regulation_type else None,
        source_url=regulation.source_url,
        local_pdf_path=regulation.local_pdf_path,
        effective_date=regulation.effective_date,
        description=regulation.description,
        is_active=regulation.is_active,
        created_at=regulation.created_at,
        updated_at=regulation.updated_at,
        requirement_count=len(reqs),
    )


@router.get("/regulations/{code}/requirements", response_model=RequirementListResponse)
async def get_regulation_requirements(
    code: str,
    is_applicable: Optional[bool] = None,
    db: Session = Depends(get_db),
):
    """Get requirements for a specific regulation."""
    reg_repo = RegulationRepository(db)
    regulation = reg_repo.get_by_code(code)
    if not regulation:
        raise HTTPException(status_code=404, detail=f"Regulation {code} not found")

    req_repo = RequirementRepository(db)
    if is_applicable is not None:
        requirements = req_repo.get_applicable(regulation.id) if is_applicable else req_repo.get_by_regulation(regulation.id)
    else:
        requirements = req_repo.get_by_regulation(regulation.id)

    results = [
        RequirementResponse(
            id=r.id,
            regulation_id=r.regulation_id,
            regulation_code=code,
            article=r.article,
            paragraph=r.paragraph,
            title=r.title,
            description=r.description,
            requirement_text=r.requirement_text,
            breakpilot_interpretation=r.breakpilot_interpretation,
            is_applicable=r.is_applicable,
            applicability_reason=r.applicability_reason,
            priority=r.priority,
            created_at=r.created_at,
            updated_at=r.updated_at,
        )
        for r in requirements
    ]

    return RequirementListResponse(requirements=results, total=len(results))


@router.get("/requirements/{requirement_id}")
async def get_requirement(requirement_id: str, db: Session = Depends(get_db)):
    """Get a specific requirement by ID."""
    from ..db.models import RequirementDB, RegulationDB

    requirement = db.query(RequirementDB).filter(RequirementDB.id == requirement_id).first()
    if not requirement:
        raise HTTPException(status_code=404, detail=f"Requirement {requirement_id} not found")

    regulation = db.query(RegulationDB).filter(RegulationDB.id == requirement.regulation_id).first()

    return {
        "id": requirement.id,
        "regulation_id": requirement.regulation_id,
        "regulation_code": regulation.code if regulation else None,
        "article": requirement.article,
        "paragraph": requirement.paragraph,
        "title": requirement.title,
        "description": requirement.description,
        "requirement_text": requirement.requirement_text,
        "breakpilot_interpretation": requirement.breakpilot_interpretation,
        "implementation_status": requirement.implementation_status or "not_started",
        "implementation_details": requirement.implementation_details,
        "code_references": requirement.code_references,
        "documentation_links": requirement.documentation_links,
        "evidence_description": requirement.evidence_description,
        "evidence_artifacts": requirement.evidence_artifacts,
        "auditor_notes": requirement.auditor_notes,
        "audit_status": requirement.audit_status or "pending",
        "last_audit_date": requirement.last_audit_date,
        "last_auditor": requirement.last_auditor,
        "is_applicable": requirement.is_applicable,
        "applicability_reason": requirement.applicability_reason,
        "priority": requirement.priority,
        "source_page": requirement.source_page,
        "source_section": requirement.source_section,
    }


@router.get("/requirements", response_model=PaginatedRequirementResponse)
async def list_requirements_paginated(
    page: int = Query(1, ge=1, description="Page number"),
    page_size: int = Query(50, ge=1, le=500, description="Items per page"),
    regulation_code: Optional[str] = Query(None, description="Filter by regulation code"),
    status: Optional[str] = Query(None, description="Filter by implementation status"),
    is_applicable: Optional[bool] = Query(None, description="Filter by applicability"),
    search: Optional[str] = Query(None, description="Search in title/description"),
    db: Session = Depends(get_db),
):
    """
    List requirements with pagination and eager-loaded relationships.

    This endpoint is optimized for large datasets (1000+ requirements) with:
    - Eager loading to prevent N+1 queries
    - Server-side pagination
    - Full-text search support
    """
    req_repo = RequirementRepository(db)

    # Use the new paginated method with eager loading
    requirements, total = req_repo.get_paginated(
        page=page,
        page_size=page_size,
        regulation_code=regulation_code,
        status=status,
        is_applicable=is_applicable,
        search=search,
    )

    # Calculate pagination metadata
    total_pages = (total + page_size - 1) // page_size

    results = [
        RequirementResponse(
            id=r.id,
            regulation_id=r.regulation_id,
            regulation_code=r.regulation.code if r.regulation else None,
            article=r.article,
            paragraph=r.paragraph,
            title=r.title,
            description=r.description,
            requirement_text=r.requirement_text,
            breakpilot_interpretation=r.breakpilot_interpretation,
            is_applicable=r.is_applicable,
            applicability_reason=r.applicability_reason,
            priority=r.priority,
            implementation_status=r.implementation_status or "not_started",
            implementation_details=r.implementation_details,
            code_references=r.code_references,
            documentation_links=r.documentation_links,
            evidence_description=r.evidence_description,
            evidence_artifacts=r.evidence_artifacts,
            auditor_notes=r.auditor_notes,
            audit_status=r.audit_status or "pending",
            last_audit_date=r.last_audit_date,
            last_auditor=r.last_auditor,
            source_page=r.source_page,
            source_section=r.source_section,
            created_at=r.created_at,
            updated_at=r.updated_at,
        )
        for r in requirements
    ]

    return PaginatedRequirementResponse(
        data=results,
        pagination=PaginationMeta(
            page=page,
            page_size=page_size,
            total=total,
            total_pages=total_pages,
            has_next=page < total_pages,
            has_prev=page > 1,
        ),
    )


@router.put("/requirements/{requirement_id}")
async def update_requirement(requirement_id: str, updates: dict, db: Session = Depends(get_db)):
    """Update a requirement with implementation/audit details."""
    from ..db.models import RequirementDB
    from datetime import datetime

    requirement = db.query(RequirementDB).filter(RequirementDB.id == requirement_id).first()
    if not requirement:
        raise HTTPException(status_code=404, detail=f"Requirement {requirement_id} not found")

    # Allowed fields to update
    allowed_fields = [
        'implementation_status', 'implementation_details', 'code_references',
        'documentation_links', 'evidence_description', 'evidence_artifacts',
        'auditor_notes', 'audit_status', 'is_applicable', 'applicability_reason',
        'breakpilot_interpretation'
    ]

    for field in allowed_fields:
        if field in updates:
            setattr(requirement, field, updates[field])

    # Track audit changes
    if 'audit_status' in updates:
        requirement.last_audit_date = datetime.utcnow()
        # TODO: Get auditor from auth
        requirement.last_auditor = updates.get('auditor_name', 'api_user')

    requirement.updated_at = datetime.utcnow()
    db.commit()
    db.refresh(requirement)

    return {"success": True, "message": "Requirement updated"}


# ============================================================================
# Controls
# ============================================================================

@router.get("/controls", response_model=ControlListResponse)
async def list_controls(
    domain: Optional[str] = None,
    status: Optional[str] = None,
    is_automated: Optional[bool] = None,
    search: Optional[str] = None,
    db: Session = Depends(get_db),
):
    """List all controls with optional filters."""
    repo = ControlRepository(db)

    if domain:
        try:
            domain_enum = ControlDomainEnum(domain)
            controls = repo.get_by_domain(domain_enum)
        except ValueError:
            raise HTTPException(status_code=400, detail=f"Invalid domain: {domain}")
    elif status:
        try:
            status_enum = ControlStatusEnum(status)
            controls = repo.get_by_status(status_enum)
        except ValueError:
            raise HTTPException(status_code=400, detail=f"Invalid status: {status}")
    else:
        controls = repo.get_all()

    # Apply additional filters
    if is_automated is not None:
        controls = [c for c in controls if c.is_automated == is_automated]

    if search:
        search_lower = search.lower()
        controls = [
            c for c in controls
            if search_lower in c.control_id.lower()
            or search_lower in c.title.lower()
            or (c.description and search_lower in c.description.lower())
        ]

    # Add counts
    evidence_repo = EvidenceRepository(db)
    results = []
    for ctrl in controls:
        evidence = evidence_repo.get_by_control(ctrl.id)
        results.append(ControlResponse(
            id=ctrl.id,
            control_id=ctrl.control_id,
            domain=ctrl.domain.value if ctrl.domain else None,
            control_type=ctrl.control_type.value if ctrl.control_type else None,
            title=ctrl.title,
            description=ctrl.description,
            pass_criteria=ctrl.pass_criteria,
            implementation_guidance=ctrl.implementation_guidance,
            code_reference=ctrl.code_reference,
            documentation_url=ctrl.documentation_url,
            is_automated=ctrl.is_automated,
            automation_tool=ctrl.automation_tool,
            automation_config=ctrl.automation_config,
            owner=ctrl.owner,
            review_frequency_days=ctrl.review_frequency_days,
            status=ctrl.status.value if ctrl.status else None,
            status_notes=ctrl.status_notes,
            last_reviewed_at=ctrl.last_reviewed_at,
            next_review_at=ctrl.next_review_at,
            created_at=ctrl.created_at,
            updated_at=ctrl.updated_at,
            evidence_count=len(evidence),
        ))

    return ControlListResponse(controls=results, total=len(results))


@router.get("/controls/paginated", response_model=PaginatedControlResponse)
async def list_controls_paginated(
    page: int = Query(1, ge=1, description="Page number"),
    page_size: int = Query(50, ge=1, le=500, description="Items per page"),
    domain: Optional[str] = Query(None, description="Filter by domain"),
    status: Optional[str] = Query(None, description="Filter by status"),
    is_automated: Optional[bool] = Query(None, description="Filter by automation"),
    search: Optional[str] = Query(None, description="Search in title/description"),
    db: Session = Depends(get_db),
):
    """
    List controls with pagination and eager-loaded relationships.

    This endpoint is optimized for large datasets with:
    - Eager loading to prevent N+1 queries
    - Server-side pagination
    - Full-text search support
    """
    repo = ControlRepository(db)

    # Convert domain/status to enums if provided
    domain_enum = None
    status_enum = None
    if domain:
        try:
            domain_enum = ControlDomainEnum(domain)
        except ValueError:
            raise HTTPException(status_code=400, detail=f"Invalid domain: {domain}")
    if status:
        try:
            status_enum = ControlStatusEnum(status)
        except ValueError:
            raise HTTPException(status_code=400, detail=f"Invalid status: {status}")

    controls, total = repo.get_paginated(
        page=page,
        page_size=page_size,
        domain=domain_enum,
        status=status_enum,
        is_automated=is_automated,
        search=search,
    )

    total_pages = (total + page_size - 1) // page_size

    results = [
        ControlResponse(
            id=c.id,
            control_id=c.control_id,
            domain=c.domain.value if c.domain else None,
            control_type=c.control_type.value if c.control_type else None,
            title=c.title,
            description=c.description,
            pass_criteria=c.pass_criteria,
            implementation_guidance=c.implementation_guidance,
            code_reference=c.code_reference,
            documentation_url=c.documentation_url,
            is_automated=c.is_automated,
            automation_tool=c.automation_tool,
            automation_config=c.automation_config,
            owner=c.owner,
            review_frequency_days=c.review_frequency_days,
            status=c.status.value if c.status else None,
            status_notes=c.status_notes,
            last_reviewed_at=c.last_reviewed_at,
            next_review_at=c.next_review_at,
            created_at=c.created_at,
            updated_at=c.updated_at,
            evidence_count=len(c.evidence) if c.evidence else 0,
        )
        for c in controls
    ]

    return PaginatedControlResponse(
        data=results,
        pagination=PaginationMeta(
            page=page,
            page_size=page_size,
            total=total,
            total_pages=total_pages,
            has_next=page < total_pages,
            has_prev=page > 1,
        ),
    )


@router.get("/controls/{control_id}", response_model=ControlResponse)
async def get_control(control_id: str, db: Session = Depends(get_db)):
    """Get a specific control by control_id."""
    repo = ControlRepository(db)
    control = repo.get_by_control_id(control_id)
    if not control:
        raise HTTPException(status_code=404, detail=f"Control {control_id} not found")

    evidence_repo = EvidenceRepository(db)
    evidence = evidence_repo.get_by_control(control.id)

    return ControlResponse(
        id=control.id,
        control_id=control.control_id,
        domain=control.domain.value if control.domain else None,
        control_type=control.control_type.value if control.control_type else None,
        title=control.title,
        description=control.description,
        pass_criteria=control.pass_criteria,
        implementation_guidance=control.implementation_guidance,
        code_reference=control.code_reference,
        documentation_url=control.documentation_url,
        is_automated=control.is_automated,
        automation_tool=control.automation_tool,
        automation_config=control.automation_config,
        owner=control.owner,
        review_frequency_days=control.review_frequency_days,
        status=control.status.value if control.status else None,
        status_notes=control.status_notes,
        last_reviewed_at=control.last_reviewed_at,
        next_review_at=control.next_review_at,
        created_at=control.created_at,
        updated_at=control.updated_at,
        evidence_count=len(evidence),
    )


@router.put("/controls/{control_id}", response_model=ControlResponse)
async def update_control(
    control_id: str,
    update: ControlUpdate,
    db: Session = Depends(get_db),
):
    """Update a control."""
    repo = ControlRepository(db)
    control = repo.get_by_control_id(control_id)
    if not control:
        raise HTTPException(status_code=404, detail=f"Control {control_id} not found")

    update_data = update.model_dump(exclude_unset=True)

    # Convert status string to enum
    if "status" in update_data:
        try:
            update_data["status"] = ControlStatusEnum(update_data["status"])
        except ValueError:
            raise HTTPException(status_code=400, detail=f"Invalid status: {update_data['status']}")

    updated = repo.update(control.id, **update_data)
    db.commit()

    return ControlResponse(
        id=updated.id,
        control_id=updated.control_id,
        domain=updated.domain.value if updated.domain else None,
        control_type=updated.control_type.value if updated.control_type else None,
        title=updated.title,
        description=updated.description,
        pass_criteria=updated.pass_criteria,
        implementation_guidance=updated.implementation_guidance,
        code_reference=updated.code_reference,
        documentation_url=updated.documentation_url,
        is_automated=updated.is_automated,
        automation_tool=updated.automation_tool,
        automation_config=updated.automation_config,
        owner=updated.owner,
        review_frequency_days=updated.review_frequency_days,
        status=updated.status.value if updated.status else None,
        status_notes=updated.status_notes,
        last_reviewed_at=updated.last_reviewed_at,
        next_review_at=updated.next_review_at,
        created_at=updated.created_at,
        updated_at=updated.updated_at,
    )


@router.put("/controls/{control_id}/review", response_model=ControlResponse)
async def review_control(
    control_id: str,
    review: ControlReviewRequest,
    db: Session = Depends(get_db),
):
    """Mark a control as reviewed with new status."""
    repo = ControlRepository(db)
    control = repo.get_by_control_id(control_id)
    if not control:
        raise HTTPException(status_code=404, detail=f"Control {control_id} not found")

    try:
        status_enum = ControlStatusEnum(review.status)
    except ValueError:
        raise HTTPException(status_code=400, detail=f"Invalid status: {review.status}")

    updated = repo.mark_reviewed(control.id, status_enum, review.status_notes)
    db.commit()

    return ControlResponse(
        id=updated.id,
        control_id=updated.control_id,
        domain=updated.domain.value if updated.domain else None,
        control_type=updated.control_type.value if updated.control_type else None,
        title=updated.title,
        description=updated.description,
        pass_criteria=updated.pass_criteria,
        implementation_guidance=updated.implementation_guidance,
        code_reference=updated.code_reference,
        documentation_url=updated.documentation_url,
        is_automated=updated.is_automated,
        automation_tool=updated.automation_tool,
        automation_config=updated.automation_config,
        owner=updated.owner,
        review_frequency_days=updated.review_frequency_days,
        status=updated.status.value if updated.status else None,
        status_notes=updated.status_notes,
        last_reviewed_at=updated.last_reviewed_at,
        next_review_at=updated.next_review_at,
        created_at=updated.created_at,
        updated_at=updated.updated_at,
    )


@router.get("/controls/by-domain/{domain}", response_model=ControlListResponse)
async def get_controls_by_domain(domain: str, db: Session = Depends(get_db)):
    """Get controls by domain."""
    try:
        domain_enum = ControlDomainEnum(domain)
    except ValueError:
        raise HTTPException(status_code=400, detail=f"Invalid domain: {domain}")

    repo = ControlRepository(db)
    controls = repo.get_by_domain(domain_enum)

    results = [
        ControlResponse(
            id=c.id,
            control_id=c.control_id,
            domain=c.domain.value if c.domain else None,
            control_type=c.control_type.value if c.control_type else None,
            title=c.title,
            description=c.description,
            pass_criteria=c.pass_criteria,
            implementation_guidance=c.implementation_guidance,
            code_reference=c.code_reference,
            documentation_url=c.documentation_url,
            is_automated=c.is_automated,
            automation_tool=c.automation_tool,
            automation_config=c.automation_config,
            owner=c.owner,
            review_frequency_days=c.review_frequency_days,
            status=c.status.value if c.status else None,
            status_notes=c.status_notes,
            last_reviewed_at=c.last_reviewed_at,
            next_review_at=c.next_review_at,
            created_at=c.created_at,
            updated_at=c.updated_at,
        )
        for c in controls
    ]

    return ControlListResponse(controls=results, total=len(results))


@router.post("/export", response_model=ExportResponse)
async def create_export(
    request: ExportRequest,
    background_tasks: BackgroundTasks,
    db: Session = Depends(get_db),
):
    """Create a new audit export."""
    generator = AuditExportGenerator(db)
    export = generator.create_export(
        requested_by="api_user",  # TODO: Get from auth
        export_type=request.export_type,
        included_regulations=request.included_regulations,
        included_domains=request.included_domains,
        date_range_start=request.date_range_start,
        date_range_end=request.date_range_end,
    )

    return ExportResponse(
        id=export.id,
        export_type=export.export_type,
        export_name=export.export_name,
        status=export.status.value if export.status else None,
        requested_by=export.requested_by,
        requested_at=export.requested_at,
        completed_at=export.completed_at,
        file_path=export.file_path,
        file_hash=export.file_hash,
        file_size_bytes=export.file_size_bytes,
        total_controls=export.total_controls,
        total_evidence=export.total_evidence,
        compliance_score=export.compliance_score,
        error_message=export.error_message,
    )


@router.get("/export/{export_id}", response_model=ExportResponse)
async def get_export(export_id: str, db: Session = Depends(get_db)):
    """Get export status."""
    generator = AuditExportGenerator(db)
    export = generator.get_export_status(export_id)
    if not export:
        raise HTTPException(status_code=404, detail=f"Export {export_id} not found")

    return ExportResponse(
        id=export.id,
        export_type=export.export_type,
        export_name=export.export_name,
        status=export.status.value if export.status else None,
        requested_by=export.requested_by,
        requested_at=export.requested_at,
        completed_at=export.completed_at,
        file_path=export.file_path,
        file_hash=export.file_hash,
        file_size_bytes=export.file_size_bytes,
        total_controls=export.total_controls,
        total_evidence=export.total_evidence,
        compliance_score=export.compliance_score,
        error_message=export.error_message,
    )


@router.get("/export/{export_id}/download")
async def download_export(export_id: str, db: Session = Depends(get_db)):
    """Download export file."""
    generator = AuditExportGenerator(db)
    export = generator.get_export_status(export_id)
    if not export:
        raise HTTPException(status_code=404, detail=f"Export {export_id} not found")

    if export.status.value != "completed":
        raise HTTPException(status_code=400, detail="Export not completed")

    if not export.file_path or not os.path.exists(export.file_path):
        raise HTTPException(status_code=404, detail="Export file not found")

    return FileResponse(
        export.file_path,
        media_type="application/zip",
        filename=os.path.basename(export.file_path),
    )


@router.get("/exports", response_model=ExportListResponse)
async def list_exports(
    limit: int = 20,
    offset: int = 0,
    db: Session = Depends(get_db),
):
    """List recent exports."""
    generator = AuditExportGenerator(db)
    exports = generator.list_exports(limit, offset)

    results = [
        ExportResponse(
            id=e.id,
            export_type=e.export_type,
            export_name=e.export_name,
            status=e.status.value if e.status else None,
            requested_by=e.requested_by,
            requested_at=e.requested_at,
            completed_at=e.completed_at,
            file_path=e.file_path,
            file_hash=e.file_hash,
            file_size_bytes=e.file_size_bytes,
            total_controls=e.total_controls,
            total_evidence=e.total_evidence,
            compliance_score=e.compliance_score,
            error_message=e.error_message,
        )
        for e in exports
    ]

    return ExportListResponse(exports=results, total=len(results))


# ============================================================================
# Seeding
# ============================================================================

@router.post("/init-tables")
async def init_tables(db: Session = Depends(get_db)):
    """Create compliance tables if they don't exist."""
    from classroom_engine.database import engine
    from ..db.models import (
        RegulationDB, RequirementDB, ControlDB, ControlMappingDB,
        EvidenceDB, RiskDB, AuditExportDB
    )

    try:
        # Create all tables
        RegulationDB.__table__.create(engine, checkfirst=True)
        RequirementDB.__table__.create(engine, checkfirst=True)
        ControlDB.__table__.create(engine, checkfirst=True)
        ControlMappingDB.__table__.create(engine, checkfirst=True)
        EvidenceDB.__table__.create(engine, checkfirst=True)
        RiskDB.__table__.create(engine, checkfirst=True)
        AuditExportDB.__table__.create(engine, checkfirst=True)

        return {"success": True, "message": "Tables created successfully"}
    except Exception as e:
        logger.error(f"Table creation failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/create-indexes")
async def create_performance_indexes(db: Session = Depends(get_db)):
    """
    Create additional performance indexes for large datasets.

    These indexes are optimized for:
    - Pagination queries (1000+ requirements)
    - Full-text search
    - Filtering by status/priority
    """
    from sqlalchemy import text

    indexes = [
        # Priority index for sorting (descending, as we want high priority first)
        ("ix_req_priority_desc", "CREATE INDEX IF NOT EXISTS ix_req_priority_desc ON compliance_requirements (priority DESC)"),

        # Compound index for common filtering patterns
        ("ix_req_applicable_status", "CREATE INDEX IF NOT EXISTS ix_req_applicable_status ON compliance_requirements (is_applicable, implementation_status)"),

        # Control status index
        ("ix_ctrl_status", "CREATE INDEX IF NOT EXISTS ix_ctrl_status ON compliance_controls (status)"),

        # Evidence collected_at for timeline queries
        ("ix_evidence_collected", "CREATE INDEX IF NOT EXISTS ix_evidence_collected ON compliance_evidence (collected_at DESC)"),

        # Risk inherent risk level
        ("ix_risk_level", "CREATE INDEX IF NOT EXISTS ix_risk_level ON compliance_risks (inherent_risk)"),
    ]

    created = []
    errors = []

    for idx_name, idx_sql in indexes:
        try:
            db.execute(text(idx_sql))
            db.commit()
            created.append(idx_name)
        except Exception as e:
            errors.append({"index": idx_name, "error": str(e)})
            logger.warning(f"Index creation failed for {idx_name}: {e}")

    return {
        "success": len(errors) == 0,
        "created": created,
        "errors": errors,
        "message": f"Created {len(created)} indexes" + (f", {len(errors)} failed" if errors else ""),
    }


@router.post("/seed-risks")
async def seed_risks_only(db: Session = Depends(get_db)):
    """Seed only risks (incremental update for existing databases)."""
    from classroom_engine.database import engine
    from ..db.models import RiskDB

    try:
        # Ensure table exists
        RiskDB.__table__.create(engine, checkfirst=True)

        seeder = ComplianceSeeder(db)
        count = seeder.seed_risks_only()

        return {
            "success": True,
            "message": f"Successfully seeded {count} risks",
            "risks_seeded": count,
        }
    except Exception as e:
        logger.error(f"Risk seeding failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/seed", response_model=SeedResponse)
async def seed_database(
    request: SeedRequest,
    db: Session = Depends(get_db),
):
    """Seed the compliance database with initial data."""
    from classroom_engine.database import engine
    from ..db.models import (
        RegulationDB, RequirementDB, ControlDB, ControlMappingDB,
        EvidenceDB, RiskDB, AuditExportDB
    )

    try:
        # Ensure tables exist first
        RegulationDB.__table__.create(engine, checkfirst=True)
        RequirementDB.__table__.create(engine, checkfirst=True)
        ControlDB.__table__.create(engine, checkfirst=True)
        ControlMappingDB.__table__.create(engine, checkfirst=True)
        EvidenceDB.__table__.create(engine, checkfirst=True)
        RiskDB.__table__.create(engine, checkfirst=True)
        AuditExportDB.__table__.create(engine, checkfirst=True)

        seeder = ComplianceSeeder(db)
        counts = seeder.seed_all(force=request.force)
        return SeedResponse(
            success=True,
            message="Database seeded successfully",
            counts=counts,
        )
    except Exception as e:
        logger.error(f"Seeding failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


