"""Pattern template routes: CRUD for rectangle layout templates."""

from fastapi import APIRouter, HTTPException, Depends

from wled_controller.api.auth import AuthRequired
from wled_controller.api.dependencies import (
    fire_entity_event,
    get_pattern_template_store,
    get_output_target_store,
)
from wled_controller.api.schemas.pattern_templates import (
    PatternTemplateCreate,
    PatternTemplateListResponse,
    PatternTemplateResponse,
    PatternTemplateUpdate,
)
from wled_controller.api.schemas.output_targets import KeyColorRectangleSchema
from wled_controller.storage.key_colors_output_target import KeyColorRectangle
from wled_controller.storage.pattern_template_store import PatternTemplateStore
from wled_controller.storage.output_target_store import OutputTargetStore
from wled_controller.utils import get_logger
from wled_controller.storage.base_store import EntityNotFoundError

logger = get_logger(__name__)

router = APIRouter()


def _pat_template_to_response(t) -> PatternTemplateResponse:
    """Convert a PatternTemplate to its API response."""
    return PatternTemplateResponse(
        id=t.id,
        name=t.name,
        rectangles=[
            KeyColorRectangleSchema(name=r.name, x=r.x, y=r.y, width=r.width, height=r.height)
            for r in t.rectangles
        ],
        created_at=t.created_at,
        updated_at=t.updated_at,
        description=t.description,
        tags=t.tags,
    )


@router.get("/api/v1/pattern-templates", response_model=PatternTemplateListResponse, tags=["Pattern Templates"])
async def list_pattern_templates(
    _auth: AuthRequired,
    store: PatternTemplateStore = Depends(get_pattern_template_store),
):
    """List all pattern templates."""
    try:
        templates = store.get_all_templates()
        responses = [_pat_template_to_response(t) for t in templates]
        return PatternTemplateListResponse(templates=responses, count=len(responses))
    except Exception as e:
        logger.error("Failed to list pattern templates: %s", e, exc_info=True)
        raise HTTPException(status_code=500, detail="Internal server error")


@router.post("/api/v1/pattern-templates", response_model=PatternTemplateResponse, tags=["Pattern Templates"], status_code=201)
async def create_pattern_template(
    data: PatternTemplateCreate,
    _auth: AuthRequired,
    store: PatternTemplateStore = Depends(get_pattern_template_store),
):
    """Create a new pattern template."""
    try:
        rectangles = [
            KeyColorRectangle(name=r.name, x=r.x, y=r.y, width=r.width, height=r.height)
            for r in data.rectangles
        ]
        template = store.create_template(
            name=data.name,
            rectangles=rectangles,
            description=data.description,
            tags=data.tags,
        )
        fire_entity_event("pattern_template", "created", template.id)
        return _pat_template_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 pattern template: %s", e, exc_info=True)
        raise HTTPException(status_code=500, detail="Internal server error")


@router.get("/api/v1/pattern-templates/{template_id}", response_model=PatternTemplateResponse, tags=["Pattern Templates"])
async def get_pattern_template(
    template_id: str,
    _auth: AuthRequired,
    store: PatternTemplateStore = Depends(get_pattern_template_store),
):
    """Get pattern template by ID."""
    try:
        template = store.get_template(template_id)
        return _pat_template_to_response(template)
    except ValueError:
        raise HTTPException(status_code=404, detail=f"Pattern template {template_id} not found")


@router.put("/api/v1/pattern-templates/{template_id}", response_model=PatternTemplateResponse, tags=["Pattern Templates"])
async def update_pattern_template(
    template_id: str,
    data: PatternTemplateUpdate,
    _auth: AuthRequired,
    store: PatternTemplateStore = Depends(get_pattern_template_store),
):
    """Update a pattern template."""
    try:
        rectangles = None
        if data.rectangles is not None:
            rectangles = [
                KeyColorRectangle(name=r.name, x=r.x, y=r.y, width=r.width, height=r.height)
                for r in data.rectangles
            ]
        template = store.update_template(
            template_id=template_id,
            name=data.name,
            rectangles=rectangles,
            description=data.description,
            tags=data.tags,
        )
        fire_entity_event("pattern_template", "updated", template_id)
        return _pat_template_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 pattern template: %s", e, exc_info=True)
        raise HTTPException(status_code=500, detail="Internal server error")


@router.delete("/api/v1/pattern-templates/{template_id}", status_code=204, tags=["Pattern Templates"])
async def delete_pattern_template(
    template_id: str,
    _auth: AuthRequired,
    store: PatternTemplateStore = Depends(get_pattern_template_store),
    target_store: OutputTargetStore = Depends(get_output_target_store),
):
    """Delete a pattern template."""
    try:
        target_names = store.get_targets_referencing(template_id, target_store)
        if target_names:
            names = ", ".join(target_names)
            raise HTTPException(
                status_code=409,
                detail=f"Cannot delete pattern template: it is referenced by target(s): {names}. "
                       "Please reassign those targets before deleting.",
            )
        store.delete_template(template_id)
        fire_entity_event("pattern_template", "deleted", template_id)
    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 pattern template: %s", e, exc_info=True)
        raise HTTPException(status_code=500, detail="Internal server error")
