"""Audio processing template routes."""

from fastapi import APIRouter, Depends, HTTPException

from wled_controller.api.auth import AuthRequired
from wled_controller.api.dependencies import (
    fire_entity_event,
    get_audio_processing_template_store,
    get_processor_manager,
)
from wled_controller.api.schemas.audio_processing import (
    AudioProcessingTemplateCreate,
    AudioProcessingTemplateListResponse,
    AudioProcessingTemplateResponse,
    AudioProcessingTemplateUpdate,
)
from wled_controller.api.schemas.filters import FilterInstanceSchema
from wled_controller.core.filters.filter_instance import FilterInstance
from wled_controller.storage.audio_processing_template_store import AudioProcessingTemplateStore
from wled_controller.storage.base_store import EntityNotFoundError
from wled_controller.utils import get_logger

logger = get_logger(__name__)

router = APIRouter()


def _apt_to_response(t) -> AudioProcessingTemplateResponse:
    """Convert an AudioProcessingTemplate to its API response."""
    return AudioProcessingTemplateResponse(
        id=t.id,
        name=t.name,
        filters=[FilterInstanceSchema(filter_id=f.filter_id, options=f.options) for f in t.filters],
        created_at=t.created_at,
        updated_at=t.updated_at,
        description=t.description,
        tags=t.tags,
    )


@router.get(
    "/api/v1/audio-processing-templates",
    response_model=AudioProcessingTemplateListResponse,
    tags=["Audio Processing Templates"],
)
async def list_audio_processing_templates(
    _auth: AuthRequired,
    store: AudioProcessingTemplateStore = Depends(get_audio_processing_template_store),
):
    """List all audio processing templates."""
    templates = store.get_all_templates()
    responses = [_apt_to_response(t) for t in templates]
    return AudioProcessingTemplateListResponse(templates=responses, count=len(responses))


@router.post(
    "/api/v1/audio-processing-templates",
    response_model=AudioProcessingTemplateResponse,
    tags=["Audio Processing Templates"],
    status_code=201,
)
async def create_audio_processing_template(
    data: AudioProcessingTemplateCreate,
    _auth: AuthRequired,
    store: AudioProcessingTemplateStore = Depends(get_audio_processing_template_store),
):
    """Create a new audio processing template."""
    try:
        filters = [FilterInstance(f.filter_id, f.options) for f in data.filters]
        template = store.create_template(
            name=data.name,
            filters=filters,
            description=data.description,
            tags=data.tags,
        )
        fire_entity_event("audio_processing_template", "created", template.id)
        return _apt_to_response(template)
    except EntityNotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error("Failed to create audio processing template: %s", e, exc_info=True)
        raise HTTPException(status_code=500, detail="Internal server error")


@router.get(
    "/api/v1/audio-processing-templates/{template_id}",
    response_model=AudioProcessingTemplateResponse,
    tags=["Audio Processing Templates"],
)
async def get_audio_processing_template(
    template_id: str,
    _auth: AuthRequired,
    store: AudioProcessingTemplateStore = Depends(get_audio_processing_template_store),
):
    """Get audio processing template by ID."""
    try:
        template = store.get_template(template_id)
        return _apt_to_response(template)
    except ValueError:
        raise HTTPException(
            status_code=404, detail=f"Audio processing template {template_id} not found"
        )


@router.put(
    "/api/v1/audio-processing-templates/{template_id}",
    response_model=AudioProcessingTemplateResponse,
    tags=["Audio Processing Templates"],
)
async def update_audio_processing_template(
    template_id: str,
    data: AudioProcessingTemplateUpdate,
    _auth: AuthRequired,
    store: AudioProcessingTemplateStore = Depends(get_audio_processing_template_store),
):
    """Update an audio processing template."""
    try:
        filters = (
            [FilterInstance(f.filter_id, f.options) for f in data.filters]
            if data.filters is not None
            else None
        )
        template = store.update_template(
            template_id=template_id,
            name=data.name,
            filters=filters,
            description=data.description,
            tags=data.tags,
        )
        fire_entity_event("audio_processing_template", "updated", template_id)
        # Hot-update: rebuild filter pipelines for running streams using this template
        try:
            pm = get_processor_manager()
            pm.refresh_audio_filter_pipelines(template_id)
        except Exception:
            pass  # Non-critical: streams will pick up changes on next restart
        return _apt_to_response(template)
    except EntityNotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error("Failed to update audio processing template: %s", e, exc_info=True)
        raise HTTPException(status_code=500, detail="Internal server error")


@router.delete(
    "/api/v1/audio-processing-templates/{template_id}",
    status_code=204,
    tags=["Audio Processing Templates"],
)
async def delete_audio_processing_template(
    template_id: str,
    _auth: AuthRequired,
    store: AudioProcessingTemplateStore = Depends(get_audio_processing_template_store),
):
    """Delete an audio processing template."""
    try:
        # TODO: Phase 3 will add reference checks against ProcessedAudioSource
        store.delete_template(template_id)
        fire_entity_event("audio_processing_template", "deleted", template_id)
        # Hot-update: rebuild filter pipelines for running streams that used this template
        try:
            pm = get_processor_manager()
            pm.refresh_audio_filter_pipelines(template_id)
        except Exception:
            pass  # Non-critical
    except HTTPException:
        raise
    except EntityNotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error("Failed to delete audio processing template: %s", e, exc_info=True)
        raise HTTPException(status_code=500, detail="Internal server error")
