"""
SiteTemplate admin router — PRD-010 Templates Management.

All endpoints require superuser authentication.

IMPORTANT: The /templates/variables route is registered BEFORE /templates/{id}
to prevent FastAPI from treating "variables" as an integer path parameter.
"""

from typing import Optional

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

from src.apps.auth.utils.auth import get_current_superuser
from src.apps.site_templates import crud as site_template_crud
from src.apps.site_templates import services as site_template_services
from src.apps.site_templates.schemas import (
    PaginatedTemplatesResponse,
    SiteTemplateListItemSchema,
    SiteTemplateSchema,
    SiteTemplateUpdateRequest,
    TemplatePreviewRequest,
    TemplatePreviewResponse,
    VariableRegistryResponse,
)
from src.core.database import get_session

router = APIRouter()


@router.get("/templates", response_model=PaginatedTemplatesResponse)
async def list_templates(
    channel: Optional[str] = Query(None, description="Filter by channel: email | sms | pdf"),
    template_type: Optional[str] = Query(None, description="Filter by type: auth | payment | user_invite"),
    is_active: Optional[bool] = Query(None, description="Filter by active status"),
    search: Optional[str] = Query(None, description="Search by template name or key"),
    page: int = Query(1, ge=1, description="Page number"),
    page_size: int = Query(20, ge=1, le=100, description="Items per page"),
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_session),
):
    """
    Paginated list of site templates with optional channel, type, status, and
    full-text search filters.
    """
    items, total = site_template_crud.list_templates(
        db,
        channel=channel,
        template_type=template_type,
        is_active=is_active,
        search=search,
        page=page,
        page_size=page_size,
    )
    return PaginatedTemplatesResponse(
        items=[SiteTemplateListItemSchema.model_validate(t) for t in items],
        total=total,
        page=page,
        page_size=page_size,
    )


# MUST be registered before /templates/{id} to avoid route conflict.
@router.get("/templates/variables", response_model=VariableRegistryResponse)
async def get_variable_registry(
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_session),
):
    """
    Return a mapping of {template_key: [variable_name, ...]} for every
    non-deleted template in the platform registry.
    """
    registry = site_template_crud.get_variable_registry(db)
    return VariableRegistryResponse(registry=registry)


@router.get("/templates/{id}", response_model=SiteTemplateSchema)
async def get_template(
    id: int,
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_session),
):
    """Fetch the full detail for a single template by primary key."""
    template = site_template_crud.get_template_by_id(db, id)
    if not template:
        raise HTTPException(status_code=404, detail="Template not found")
    return SiteTemplateSchema.model_validate(template)


@router.patch("/templates/{id}", response_model=SiteTemplateSchema)
async def update_template(
    id: int,
    body: SiteTemplateUpdateRequest,
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_session),
):
    """
    Partially update a template's editable fields: subject, body_html,
    body_text, branding colors, and is_active flag.
    """
    data = body.model_dump(exclude_none=True)
    if not data:
        raise HTTPException(status_code=400, detail="No update fields provided")

    template = site_template_crud.update_template(db, id, data)
    if not template:
        raise HTTPException(status_code=404, detail="Template not found")

    db.commit()
    db.refresh(template)
    return SiteTemplateSchema.model_validate(template)


@router.post("/templates/{id}/activate", response_model=SiteTemplateSchema)
async def activate_template(
    id: int,
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_session),
):
    """Activate a template so it is picked up by the notification dispatcher."""
    template = site_template_crud.set_active(db, id, is_active=True)
    if not template:
        raise HTTPException(status_code=404, detail="Template not found")

    db.commit()
    db.refresh(template)
    return SiteTemplateSchema.model_validate(template)


@router.post("/templates/{id}/deactivate", response_model=SiteTemplateSchema)
async def deactivate_template(
    id: int,
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_session),
):
    """Deactivate a template so it is skipped by the notification dispatcher."""
    template = site_template_crud.set_active(db, id, is_active=False)
    if not template:
        raise HTTPException(status_code=404, detail="Template not found")

    db.commit()
    db.refresh(template)
    return SiteTemplateSchema.model_validate(template)


@router.post("/templates/{id}/preview", response_model=TemplatePreviewResponse)
async def preview_template(
    id: int,
    body: TemplatePreviewRequest,
    current_user=Depends(get_current_superuser),
    db: Session = Depends(get_session),
):
    """
    Render a template with the supplied variables and return the rendered HTML,
    plain-text body, and a list of any variable names that were referenced in
    the template but not provided.
    """
    result = site_template_services.preview_template(db, id, body.variables)
    if result is None:
        raise HTTPException(status_code=404, detail="Template not found")

    return TemplatePreviewResponse(
        html=result["html"],
        text=result["text"],
        undefined_variables=result["undefined_variables"],
    )
