"""Device types API endpoints."""
from typing import Annotated
from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy import select, or_
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.database import get_db
from app.api.deps import get_current_active_user
from app.models.user import User
from app.models.device_type import DeviceType
from app.schemas.device_type import (
    DeviceTypeCreate,
    DeviceTypeUpdate,
    DeviceTypeResponse,
)
from app.core.service_account import PLATFORM_ACCOUNT_ID

router = APIRouter(prefix="/device-types", tags=["device-types"])


@router.get("/", response_model=list[DeviceTypeResponse])
async def list_device_types(
    db: Annotated[AsyncSession, Depends(get_db)],
    current_user: Annotated[User, Depends(get_current_active_user)],
) -> list[DeviceTypeResponse]:
    stmt = (
        select(DeviceType)
        .where(
            or_(
                DeviceType.account_id == PLATFORM_ACCOUNT_ID,
                DeviceType.account_id == current_user.account_id,
            )
        )
        .order_by(DeviceType.category, DeviceType.sort_order, DeviceType.label)
    )
    result = await db.execute(stmt)
    rows = result.scalars().all()
    return [DeviceTypeResponse.model_validate(r) for r in rows]


@router.post("/", response_model=DeviceTypeResponse, status_code=201)
async def create_device_type(
    data: DeviceTypeCreate,
    db: Annotated[AsyncSession, Depends(get_db)],
    current_user: Annotated[User, Depends(get_current_active_user)],
) -> DeviceTypeResponse:
    existing = await db.execute(
        select(DeviceType).where(
            DeviceType.slug == data.slug,
            DeviceType.account_id == current_user.account_id,
        )
    )
    if existing.scalar_one_or_none():
        raise HTTPException(status_code=409, detail=f"Device type '{data.slug}' already exists for your account")

    system_existing = await db.execute(
        select(DeviceType).where(
            DeviceType.slug == data.slug,
            DeviceType.account_id == PLATFORM_ACCOUNT_ID,
        )
    )
    if system_existing.scalar_one_or_none():
        raise HTTPException(status_code=409, detail=f"Device type '{data.slug}' conflicts with a system type")

    device_type = DeviceType(
        slug=data.slug,
        label=data.label,
        category=data.category,
        is_system=False,
        account_id=current_user.account_id,
        sort_order=data.sort_order,
    )
    db.add(device_type)
    await db.commit()
    await db.refresh(device_type)
    return DeviceTypeResponse.model_validate(device_type)


@router.put("/{device_type_id}", response_model=DeviceTypeResponse)
async def update_device_type(
    device_type_id: UUID,
    data: DeviceTypeUpdate,
    db: Annotated[AsyncSession, Depends(get_db)],
    current_user: Annotated[User, Depends(get_current_active_user)],
) -> DeviceTypeResponse:
    device_type = await db.get(DeviceType, device_type_id)
    if not device_type:
        raise HTTPException(status_code=404, detail="Device type not found")
    if device_type.is_system:
        raise HTTPException(status_code=403, detail="Cannot modify system device types")
    if device_type.account_id != current_user.account_id:
        raise HTTPException(status_code=404, detail="Device type not found")

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

    await db.commit()
    await db.refresh(device_type)
    return DeviceTypeResponse.model_validate(device_type)


@router.delete("/{device_type_id}", status_code=204)
async def delete_device_type(
    device_type_id: UUID,
    db: Annotated[AsyncSession, Depends(get_db)],
    current_user: Annotated[User, Depends(get_current_active_user)],
) -> None:
    device_type = await db.get(DeviceType, device_type_id)
    if not device_type:
        raise HTTPException(status_code=404, detail="Device type not found")
    if device_type.is_system:
        raise HTTPException(status_code=403, detail="Cannot delete system device types")
    if device_type.account_id != current_user.account_id:
        raise HTTPException(status_code=404, detail="Device type not found")

    await db.delete(device_type)
    await db.commit()
