"""
{{ TableNamePascal }} API Router

This module defines the FastAPI routes for {{ TableNamePascal }}.
"""
from datetime import datetime, date, time, timedelta
from decimal import Decimal
from typing import List, Optional
from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException, Query, status
from fastapi.responses import JSONResponse

from api.v1.dependencies{{ GroupNamespace }}.{{ TableNameSnake }}_deps import get_{{ TableNameSnake }}_service_read, get_{{ TableNameSnake }}_service_write
from api.schemas{{ GroupNamespace }}.{{ TableNameSnake }}_schema import (
    {{ TableNamePascal }}Response,
    Create{{ TableNamePascal }}Request,
    Update{{ TableNamePascal }}Request,
    {{ TableNamePascal }}ListResponse
)
from application.services{{ GroupNamespace }}.{{ TableNameSnake }}_service import {{ TableNamePascal }}Service
from common.pagination import PaginatedResponse


router = APIRouter(
    prefix="/{{ TableNameSnake }}s",
    tags=["{{ TableNamePascal }}"],
    responses={
        404: {"description": "Not found"},
        400: {"description": "Bad request"},
        500: {"description": "Internal server error"}
    }
)


@router.get(
    "/{id}",
    response_model={{ TableNamePascal }}Response,
    summary="Get {{ TableNamePascal }} by ID",
    description="Retrieve a specific {{ TableNamePascal }} by its ID"
)
async def get_{{ TableNameSnake }}(
    id: {{ PrimaryKey.PythonType }},
    service: {{ TableNamePascal }}Service = Depends(get_{{ TableNameSnake }}_service_read)
) -> {{ TableNamePascal }}Response:
    """Get a {{ TableNamePascal }} by ID."""
    result = await service.get_by_id(id)
    
    if result.is_failure:
        if result.error.type == "NOT_FOUND":
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=result.error.message
            )
        elif result.error.type == "VALIDATION":
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=result.error.message
            )
        else:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=result.error.message
            )
    
    return {{ TableNamePascal }}Response.from_entity(result.value)


@router.get(
    "/",
    response_model={{ TableNamePascal }}ListResponse,
    summary="List all {{ TableNamePascal }}s",
    description="Retrieve a list of all {{ TableNamePascal }} entities"
)
async def get_{{ TableNameSnake }}s(
    skip: int = Query(0, ge=0, description="Number of records to skip"),
    limit: int = Query(10, ge=1, le=100, description="Maximum number of records to return"),
    service: {{ TableNamePascal }}Service = Depends(get_{{ TableNameSnake }}_service_read)
) -> {{ TableNamePascal }}ListResponse:
    """Get all {{ TableNamePascal }} entities."""
    result = await service.get_all(skip, limit)
    
    if result.is_failure:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=result.error.message
        )
    
    items = [{{ TableNamePascal }}Response.from_entity(entity) for entity in result.value]
    return {{ TableNamePascal }}ListResponse(items=items, total=len(items))


@router.get(
    "/paginated",
    response_model=PaginatedResponse[{{ TableNamePascal }}Response],
    summary="Get paginated {{ TableNamePascal }}s",
    description="Retrieve paginated {{ TableNamePascal }} entities with filtering and sorting"
)
async def get_{{ TableNameSnake }}s_paginated(
    page: int = Query(1, ge=1, description="Page number"),
    size: int = Query(10, ge=1, le=100, description="Page size"),
    search: Optional[str] = Query(None, description="Search term"),
    sort_by: Optional[str] = Query(None, description="Field to sort by"),
    sort_desc: bool = Query(False, description="Sort in descending order"),
    {% for col in Columns %}
    {% if not col.IsPrimaryKey and col.NameSnake not in ['created_at', 'updated_at'] %}
    {% set base_type = col.PythonType.replace('Optional[', '').replace(']', '') %}
    {% if base_type in ['str', 'int', 'bool', 'float'] %}
    filter_{{ col.NameSnake }}: Optional[{{ base_type }}] = Query(None, description="Filter by {{ col.NameSnake }}"),
    {% elif base_type == 'UUID' %}
    filter_{{ col.NameSnake }}: Optional[str] = Query(None, description="Filter by {{ col.NameSnake }} (UUID as string)"),
    {% else %}
    # Skip complex types that don't work well with Query parameters
    {% endif %}
    {% endif %}
    {% endfor %}
    service: {{ TableNamePascal }}Service = Depends(get_{{ TableNameSnake }}_service_read)
) -> PaginatedResponse[{{ TableNamePascal }}Response]:
    """Get paginated {{ TableNamePascal }} entities."""
    # Build filters
    filters = {}
    {% for col in Columns %}
    {% if not col.IsPrimaryKey and col.NameSnake not in ['created_at', 'updated_at'] %}
    {% set base_type = col.PythonType.replace('Optional[', '').replace(']', '') %}
    {% if base_type in ['str', 'int', 'bool', 'float'] %}
    if filter_{{ col.NameSnake }} is not None:
        filters["{{ col.NameSnake }}"] = filter_{{ col.NameSnake }}
    {% elif base_type == 'UUID' %}
    if filter_{{ col.NameSnake }} is not None:
        try:
            filters["{{ col.NameSnake }}"] = UUID(filter_{{ col.NameSnake }})
        except ValueError:
            raise HTTPException(status_code=400, detail=f"Invalid UUID format for {{ col.NameSnake }}")
    {% endif %}
    {% endif %}
    {% endfor %}
    
    result = await service.get_paginated(
        page=page,
        size=size,
        search_term=search,
        filters=filters if filters else None,
        sort_by=sort_by,
        sort_descending=sort_desc
    )
    
    if result.is_failure:
        if result.error.type == "VALIDATION":
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=result.error.message
            )
        else:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=result.error.message
            )
    
    entities, total_count = result.value
    items = [{{ TableNamePascal }}Response.from_entity(entity) for entity in entities]
    
    return PaginatedResponse(
        items=items,
        total=total_count,
        page=page,
        size=size,
        pages=(total_count + size - 1) // size
    )


@router.post(
    "/",
    response_model={{ TableNamePascal }}Response,
    status_code=status.HTTP_201_CREATED,
    summary="Create {{ TableNamePascal }}",
    description="Create a new {{ TableNamePascal }} entity"
)
async def create_{{ TableNameSnake }}(
    request: Create{{ TableNamePascal }}Request,
    service: {{ TableNamePascal }}Service = Depends(get_{{ TableNameSnake }}_service_write)
) -> {{ TableNamePascal }}Response:
    """Create a new {{ TableNamePascal }}."""
    dto = request.to_dto()
    result = await service.create(dto)
    
    if result.is_failure:
        if result.error.type == "VALIDATION":
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=result.error.message
            )
        elif result.error.type == "CONFLICT":
            raise HTTPException(
                status_code=status.HTTP_409_CONFLICT,
                detail=result.error.message
            )
        else:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=result.error.message
            )
    
    return {{ TableNamePascal }}Response.from_entity(result.value)


@router.put(
    "/{id}",
    response_model={{ TableNamePascal }}Response,
    summary="Update {{ TableNamePascal }}",
    description="Update an existing {{ TableNamePascal }} entity"
)
async def update_{{ TableNameSnake }}(
    id: {{ PrimaryKey.PythonType }},
    request: Update{{ TableNamePascal }}Request,
    service: {{ TableNamePascal }}Service = Depends(get_{{ TableNameSnake }}_service_write)
) -> {{ TableNamePascal }}Response:
    """Update an existing {{ TableNamePascal }}."""
    dto = request.to_dto()
    result = await service.update(id, dto)
    
    if result.is_failure:
        if result.error.type == "NOT_FOUND":
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=result.error.message
            )
        elif result.error.type == "VALIDATION":
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=result.error.message
            )
        elif result.error.type == "CONFLICT":
            raise HTTPException(
                status_code=status.HTTP_409_CONFLICT,
                detail=result.error.message
            )
        else:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=result.error.message
            )
    
    return {{ TableNamePascal }}Response.from_entity(result.value)


@router.delete(
    "/{id}",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="Delete {{ TableNamePascal }}",
    description="Delete a {{ TableNamePascal }} entity"
)
async def delete_{{ TableNameSnake }}(
    id: {{ PrimaryKey.PythonType }},
    service: {{ TableNamePascal }}Service = Depends(get_{{ TableNameSnake }}_service_write)
) -> None:
    """Delete a {{ TableNamePascal }}."""
    result = await service.delete(id)
    
    if result.is_failure:
        if result.error.type == "NOT_FOUND":
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=result.error.message
            )
        elif result.error.type == "CONFLICT":
            raise HTTPException(
                status_code=status.HTTP_409_CONFLICT,
                detail=result.error.message
            )
        else:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=result.error.message
            )
    
    return None