"""
FastAPI routes for Template Rules — Empfehlungs-Regeln + Versionierung +
Approval-Workflow + Tenant-Overrides + Recommend.

Mounted unter /api/v1/compliance/* (Tenant via X-Tenant-ID Header).
"""

import logging
from typing import Optional

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

from classroom_engine.database import get_db
from compliance.api._http_errors import translate_domain_errors
from compliance.schemas.template_rule import (
    ApprovalActionRequest,
    ApprovalHistoryEntry,
    OverrideCreate,
    OverrideResponse,
    RecommendationRequest,
    RecommendationResult,
    RejectActionRequest,
    RuleCreate,
    RuleResponse,
    RuleVersionCreate,
    RuleVersionResponse,
    RuleVersionUpdate,
    SubmitForReviewRequest,
)
from compliance.services.recommendation_service import RecommendationService
from compliance.services.template_rule_service import TemplateRuleService

logger = logging.getLogger(__name__)
router = APIRouter(prefix="", tags=["template-rules"])

DEFAULT_TENANT = "9282a473-5c95-4b3a-bf78-0ecc0ec71d3e"


def _get_tenant(
    x_tenant_id: Optional[str] = Header(None, alias="X-Tenant-ID"),
) -> str:
    return x_tenant_id or DEFAULT_TENANT


def _rule_svc(db: Session = Depends(get_db)) -> TemplateRuleService:
    return TemplateRuleService(db)


def _rec_svc(db: Session = Depends(get_db)) -> RecommendationService:
    return RecommendationService(db)


# ============================================================================
# Rules (Hülle)
# ============================================================================

@router.get("/template-rules", response_model=list[RuleResponse])
async def list_rules(
    document_type: Optional[str] = Query(None),
    svc: TemplateRuleService = Depends(_rule_svc),
) -> list[RuleResponse]:
    with translate_domain_errors():
        return svc.list_rules(document_type=document_type)


@router.post("/template-rules", response_model=RuleResponse, status_code=201)
async def create_rule(
    request: RuleCreate,
    svc: TemplateRuleService = Depends(_rule_svc),
) -> RuleResponse:
    with translate_domain_errors():
        return svc.create_rule(request)


@router.get("/template-rules/{rule_id}", response_model=RuleResponse)
async def get_rule(
    rule_id: str, svc: TemplateRuleService = Depends(_rule_svc),
) -> RuleResponse:
    with translate_domain_errors():
        return svc.get_rule(rule_id)


@router.delete("/template-rules/{rule_id}", status_code=204)
async def delete_rule(
    rule_id: str, svc: TemplateRuleService = Depends(_rule_svc),
) -> None:
    with translate_domain_errors():
        svc.delete_rule(rule_id)


# ============================================================================
# Versions
# ============================================================================

@router.get(
    "/template-rules/{rule_id}/versions",
    response_model=list[RuleVersionResponse],
)
async def list_versions(
    rule_id: str, svc: TemplateRuleService = Depends(_rule_svc),
) -> list[RuleVersionResponse]:
    with translate_domain_errors():
        return svc.list_versions_for(rule_id)


@router.post(
    "/template-rules/{rule_id}/versions",
    response_model=RuleVersionResponse,
    status_code=201,
)
async def create_version(
    rule_id: str,
    request: RuleVersionCreate,
    svc: TemplateRuleService = Depends(_rule_svc),
) -> RuleVersionResponse:
    request.rule_id = rule_id  # URL gewinnt
    with translate_domain_errors():
        return svc.create_version(request)


@router.get(
    "/template-rule-versions/{version_id}",
    response_model=RuleVersionResponse,
)
async def get_version(
    version_id: str, svc: TemplateRuleService = Depends(_rule_svc),
) -> RuleVersionResponse:
    with translate_domain_errors():
        return svc.get_version(version_id)


@router.patch(
    "/template-rule-versions/{version_id}",
    response_model=RuleVersionResponse,
)
async def update_version(
    version_id: str,
    request: RuleVersionUpdate,
    svc: TemplateRuleService = Depends(_rule_svc),
) -> RuleVersionResponse:
    with translate_domain_errors():
        return svc.update_version(version_id, request)


@router.post(
    "/template-rule-versions/{version_id}/submit-review",
    response_model=RuleVersionResponse,
)
async def submit_for_review(
    version_id: str,
    request: SubmitForReviewRequest,
    svc: TemplateRuleService = Depends(_rule_svc),
) -> RuleVersionResponse:
    with translate_domain_errors():
        return svc.submit_for_review(version_id, request)


@router.post(
    "/template-rule-versions/{version_id}/approve",
    response_model=RuleVersionResponse,
)
async def approve_version(
    version_id: str,
    request: ApprovalActionRequest,
    svc: TemplateRuleService = Depends(_rule_svc),
) -> RuleVersionResponse:
    with translate_domain_errors():
        return svc.approve(version_id, request)


@router.post(
    "/template-rule-versions/{version_id}/publish",
    response_model=RuleVersionResponse,
)
async def publish_version(
    version_id: str,
    request: ApprovalActionRequest,
    svc: TemplateRuleService = Depends(_rule_svc),
) -> RuleVersionResponse:
    with translate_domain_errors():
        return svc.publish(version_id, request)


@router.post(
    "/template-rule-versions/{version_id}/reject",
    response_model=RuleVersionResponse,
)
async def reject_version(
    version_id: str,
    request: RejectActionRequest,
    svc: TemplateRuleService = Depends(_rule_svc),
) -> RuleVersionResponse:
    with translate_domain_errors():
        return svc.reject(version_id, request)


@router.get(
    "/template-rule-versions/{version_id}/approval-history",
    response_model=list[ApprovalHistoryEntry],
)
async def approval_history(
    version_id: str, svc: TemplateRuleService = Depends(_rule_svc),
) -> list[ApprovalHistoryEntry]:
    with translate_domain_errors():
        return svc.approval_history(version_id)


# ============================================================================
# Tenant Overrides
# ============================================================================

@router.get(
    "/tenant-rule-overrides",
    response_model=list[OverrideResponse],
)
async def list_overrides(
    tenant_id: str = Depends(_get_tenant),
    svc: TemplateRuleService = Depends(_rule_svc),
) -> list[OverrideResponse]:
    with translate_domain_errors():
        return svc.list_overrides(tenant_id)


@router.post(
    "/tenant-rule-overrides",
    response_model=OverrideResponse,
    status_code=201,
)
async def upsert_override(
    request: OverrideCreate,
    tenant_id: str = Depends(_get_tenant),
    svc: TemplateRuleService = Depends(_rule_svc),
) -> OverrideResponse:
    with translate_domain_errors():
        return svc.upsert_override(tenant_id, request)


@router.delete(
    "/tenant-rule-overrides/{override_id}",
    status_code=204,
)
async def delete_override(
    override_id: str,
    tenant_id: str = Depends(_get_tenant),
    svc: TemplateRuleService = Depends(_rule_svc),
) -> None:
    with translate_domain_errors():
        svc.delete_override(tenant_id, override_id)


# ============================================================================
# Recommend
# ============================================================================

@router.post("/recommend", response_model=RecommendationResult)
async def recommend(
    request: RecommendationRequest,
    tenant_id: str = Depends(_get_tenant),
    svc: RecommendationService = Depends(_rec_svc),
) -> RecommendationResult:
    with translate_domain_errors():
        return svc.recommend(request, tenant_id=tenant_id)
