"""
FastAPI routes for Document Generation from Stammdaten.

Endpoints:
  GET  /generation/preview/{doc_type}   — Markdown preview from Stammdaten
  POST /generation/apply/{doc_type}     — Generate drafts → create Change-Requests
"""

import json
import logging
from typing import Optional

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

from classroom_engine.database import get_db
from .tenant_utils import get_tenant_id
from .document_templates import (
    generate_dsfa_draft,
    generate_vvt_drafts,
    generate_loeschfristen_drafts,
    generate_tom_drafts,
    generate_obligation_drafts,
)

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

VALID_DOC_TYPES = {"dsfa", "vvt", "tom", "loeschfristen", "obligation"}


def _get_template_context(db, tid: str) -> dict:
    """Fetch company profile and build template context."""
    from .company_profile_routes import _BASE_COLUMNS, row_to_response
    from database import SessionLocal

    # Use a fresh session for company_profile (different DB import pattern)
    cp_db = SessionLocal()
    try:
        result = cp_db.execute(
            text(f"SELECT {_BASE_COLUMNS} FROM compliance_company_profiles WHERE tenant_id = :tid"),
            {"tid": tid},
        )
        row = result.fetchone()
        if not row:
            return None
        resp = row_to_response(row)
        # Build flat context
        return {
            "company_name": f"{resp.company_name} {resp.legal_form}".strip() if resp.legal_form else resp.company_name,
            "company_name_short": resp.company_name,
            "legal_form": resp.legal_form,
            "industry": resp.industry,
            "business_model": resp.business_model,
            "company_size": resp.company_size,
            "employee_count": resp.employee_count,
            "headquarters_country": resp.headquarters_country,
            "headquarters_city": resp.headquarters_city,
            "primary_jurisdiction": resp.primary_jurisdiction,
            "is_data_controller": resp.is_data_controller,
            "is_data_processor": resp.is_data_processor,
            "uses_ai": resp.uses_ai,
            "dpo_name": resp.dpo_name or "",
            "dpo_email": resp.dpo_email or "",
            "supervisory_authority": resp.supervisory_authority or "",
            "review_cycle_months": resp.review_cycle_months,
            "subject_to_nis2": resp.subject_to_nis2,
            "subject_to_ai_act": resp.subject_to_ai_act,
            "subject_to_iso27001": resp.subject_to_iso27001,
            "offerings": resp.offerings,
            "target_markets": resp.target_markets,
            "ai_use_cases": resp.ai_use_cases,
            "repos": resp.repos,
            "document_sources": resp.document_sources,
            "processing_systems": resp.processing_systems,
            "ai_systems": resp.ai_systems,
            "technical_contacts": resp.technical_contacts,
            "has_ai_systems": len(resp.ai_systems) > 0,
            "processing_system_count": len(resp.processing_systems),
            "ai_system_count": len(resp.ai_systems),
            "is_complete": resp.is_complete,
        }
    finally:
        cp_db.close()


def _generate_for_type(doc_type: str, ctx: dict):
    """Call the appropriate template generator."""
    if doc_type == "dsfa":
        return [generate_dsfa_draft(ctx)]
    elif doc_type == "vvt":
        return generate_vvt_drafts(ctx)
    elif doc_type == "tom":
        return generate_tom_drafts(ctx)
    elif doc_type == "loeschfristen":
        return generate_loeschfristen_drafts(ctx)
    elif doc_type == "obligation":
        return generate_obligation_drafts(ctx)
    else:
        raise ValueError(f"Unknown doc_type: {doc_type}")


@router.get("/preview/{doc_type}")
async def preview_generation(
    doc_type: str,
    tid: str = Depends(get_tenant_id),
    db: Session = Depends(get_db),
):
    """Preview what documents would be generated (no DB writes)."""
    if doc_type not in VALID_DOC_TYPES:
        raise HTTPException(status_code=400, detail=f"Invalid doc_type: {doc_type}. Valid: {VALID_DOC_TYPES}")

    ctx = _get_template_context(db, tid)
    if not ctx:
        raise HTTPException(status_code=404, detail="Company profile not found — fill Stammdaten first")

    drafts = _generate_for_type(doc_type, ctx)

    return {
        "doc_type": doc_type,
        "count": len(drafts),
        "drafts": drafts,
        "company_name": ctx.get("company_name"),
        "is_preview": True,
    }


@router.post("/apply/{doc_type}")
async def apply_generation(
    doc_type: str,
    tid: str = Depends(get_tenant_id),
    db: Session = Depends(get_db),
    x_user_id: Optional[str] = Header(None, alias="X-User-ID"),
):
    """Generate drafts and create Change-Requests for each.

    Does NOT create documents directly — all go through the CR inbox.
    """
    if doc_type not in VALID_DOC_TYPES:
        raise HTTPException(status_code=400, detail=f"Invalid doc_type: {doc_type}. Valid: {VALID_DOC_TYPES}")

    ctx = _get_template_context(db, tid)
    if not ctx:
        raise HTTPException(status_code=404, detail="Company profile not found — fill Stammdaten first")

    drafts = _generate_for_type(doc_type, ctx)
    user = x_user_id or "system"

    cr_ids = []
    for draft in drafts:
        title = draft.get("title") or draft.get("name") or draft.get("data_category") or f"Neues {doc_type}-Dokument"
        try:
            result = db.execute(
                text("""
                    INSERT INTO compliance_change_requests
                        (tenant_id, trigger_type, target_document_type,
                         proposal_title, proposal_body, proposed_changes,
                         priority, created_by)
                    VALUES (:tid, 'generation', :doc_type,
                            :title, :body, CAST(:changes AS jsonb),
                            'normal', :user)
                    RETURNING id
                """),
                {
                    "tid": tid,
                    "doc_type": doc_type,
                    "title": f"[Generiert] {title}",
                    "body": f"Automatisch aus Stammdaten generiert für {ctx.get('company_name', '')}",
                    "changes": json.dumps(draft),
                    "user": user,
                },
            )
            row = result.fetchone()
            if row:
                cr_ids.append(str(row[0]))
        except Exception as e:
            logger.error(f"Failed to create CR for draft: {e}")

    db.commit()

    return {
        "doc_type": doc_type,
        "drafts_generated": len(drafts),
        "change_requests_created": len(cr_ids),
        "change_request_ids": cr_ids,
    }
