"""Services API endpoints."""

from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, Field
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.dependencies import get_db, verify_api_key
from app.models.models import Service

router = APIRouter()


class ServiceCreate(BaseModel):
    name: str = Field(..., max_length=100)
    slug: str = Field(..., max_length=50, pattern=r"^[a-z0-9-]+$")
    description: str | None = None
    group_name: str | None = Field(None, max_length=50)
    position: int = 0
    is_visible: bool = True


class ServiceUpdate(BaseModel):
    name: str | None = None
    slug: str | None = Field(None, max_length=50, pattern=r"^[a-z0-9-]+$")
    description: str | None = None
    group_name: str | None = None
    position: int | None = None
    is_visible: bool | None = None


def serialize_service(s: Service) -> dict:
    return {
        "id": s.id,
        "name": s.name,
        "slug": s.slug,
        "description": s.description,
        "group_name": s.group_name,
        "position": s.position,
        "is_visible": s.is_visible,
        "created_at": s.created_at.isoformat() if s.created_at else None,
        "updated_at": s.updated_at.isoformat() if s.updated_at else None,
    }


@router.get("/")
async def list_services(db: AsyncSession = Depends(get_db)):
    """List all services."""
    result = await db.execute(select(Service).order_by(Service.position, Service.name))
    services = result.scalars().all()
    return [serialize_service(s) for s in services]


@router.post("/", status_code=status.HTTP_201_CREATED)
async def create_service(
    data: ServiceCreate,
    db: AsyncSession = Depends(get_db),
    api_key: str = Depends(verify_api_key),
):
    """Create a new service."""
    service = Service(
        name=data.name,
        slug=data.slug,
        description=data.description,
        group_name=data.group_name,
        position=data.position,
        is_visible=data.is_visible,
    )
    db.add(service)
    await db.flush()
    await db.refresh(service)
    return serialize_service(service)


@router.get("/{service_id}")
async def get_service(service_id: UUID, db: AsyncSession = Depends(get_db)):
    """Get a service by ID."""
    result = await db.execute(select(Service).where(Service.id == str(service_id)))
    service = result.scalar_one_or_none()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")
    return serialize_service(service)


@router.patch("/{service_id}")
async def update_service(
    service_id: UUID,
    data: ServiceUpdate,
    db: AsyncSession = Depends(get_db),
    api_key: str = Depends(verify_api_key),
):
    """Update a service."""
    result = await db.execute(select(Service).where(Service.id == str(service_id)))
    service = result.scalar_one_or_none()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")

    update_data = data.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(service, field, value)

    await db.flush()
    await db.refresh(service)
    return serialize_service(service)


@router.delete("/{service_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_service(
    service_id: UUID,
    db: AsyncSession = Depends(get_db),
    api_key: str = Depends(verify_api_key),
):
    """Delete a service."""
    result = await db.execute(select(Service).where(Service.id == str(service_id)))
    service = result.scalar_one_or_none()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")
    await db.delete(service)