"""Display brightness, power, contrast, input-source, color-preset and picture-mode API."""

import asyncio
import logging

from fastapi import APIRouter, Depends
from pydantic import BaseModel, Field

from ..auth import verify_token
from ..services.display_service import (
    list_monitors,
    set_brightness,
    set_color_preset,
    set_contrast,
    set_input_source,
    set_picture_mode,
    set_power,
)

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/display", tags=["display"])


class BrightnessRequest(BaseModel):
    brightness: int = Field(ge=0, le=100)


class PowerRequest(BaseModel):
    on: bool


class ContrastRequest(BaseModel):
    contrast: int = Field(ge=0, le=100)


class InputSourceRequest(BaseModel):
    source: str


class ColorPresetRequest(BaseModel):
    preset: str


class PictureModeRequest(BaseModel):
    code: int = Field(ge=0, le=255)


# DDC/CI hardware writes open a per-monitor handle and can take seconds —
# every public endpoint dispatches into a worker thread so the event loop
# stays responsive.


@router.get("/monitors")
async def get_monitors(
    refresh: bool = False,
    rediscover: bool = False,
    _: str = Depends(verify_token),
) -> list[dict]:
    """List all connected monitors with their reported DDC/CI capabilities."""
    monitors = await asyncio.to_thread(
        list_monitors, force_refresh=refresh, rediscover=rediscover
    )
    logger.debug("Found %d monitors", len(monitors))
    return [m.to_dict() for m in monitors]


@router.post("/brightness/{monitor_id}")
async def set_monitor_brightness(
    monitor_id: int, request: BrightnessRequest, _: str = Depends(verify_token)
) -> dict:
    """Set brightness for a specific monitor."""
    success = await asyncio.to_thread(set_brightness, monitor_id, request.brightness)
    if success:
        logger.info("Set monitor %d brightness to %d", monitor_id, request.brightness)
    return {"success": success}


@router.post("/power/{monitor_id}")
async def set_monitor_power(
    monitor_id: int, request: PowerRequest, _: str = Depends(verify_token)
) -> dict:
    """Turn a monitor on or off."""
    action = "on" if request.on else "off"
    success = await asyncio.to_thread(set_power, monitor_id, request.on)
    if success:
        logger.info("Set monitor %d power %s", monitor_id, action)
    return {"success": success}


@router.post("/contrast/{monitor_id}")
async def set_monitor_contrast(
    monitor_id: int, request: ContrastRequest, _: str = Depends(verify_token)
) -> dict:
    """Set DDC/CI contrast for a specific monitor."""
    success = await asyncio.to_thread(set_contrast, monitor_id, request.contrast)
    if success:
        logger.info("Set monitor %d contrast to %d", monitor_id, request.contrast)
    return {"success": success}


@router.post("/input_source/{monitor_id}")
async def set_monitor_input_source(
    monitor_id: int, request: InputSourceRequest, _: str = Depends(verify_token)
) -> dict:
    """Switch a monitor's DDC/CI input source (e.g. HDMI1, DP1)."""
    success = await asyncio.to_thread(set_input_source, monitor_id, request.source)
    if success:
        logger.info("Set monitor %d input source to %s", monitor_id, request.source)
    return {"success": success}


@router.post("/color_preset/{monitor_id}")
async def set_monitor_color_preset(
    monitor_id: int, request: ColorPresetRequest, _: str = Depends(verify_token)
) -> dict:
    """Apply a DDC/CI color preset (color temperature) to the monitor."""
    success = await asyncio.to_thread(set_color_preset, monitor_id, request.preset)
    if success:
        logger.info("Set monitor %d color preset to %s", monitor_id, request.preset)
    return {"success": success}


@router.post("/picture_mode/{monitor_id}")
async def set_monitor_picture_mode(
    monitor_id: int, request: PictureModeRequest, _: str = Depends(verify_token)
) -> dict:
    """Apply a DDC/CI picture/scene mode (VCP 0xDC) by raw code."""
    success = await asyncio.to_thread(set_picture_mode, monitor_id, request.code)
    if success:
        logger.info("Set monitor %d picture mode to code %d", monitor_id, request.code)
    return {"success": success}
