"""
KDS settings endpoints served by the kitchen backend.

The kitchen Settings page configures KDS (timers, GraphQL URL, course order, etc.)
via /kitchen/api/kds/settings. All KDS config lives in kitchen_settings — so these
endpoints belong here, not in the KDS backend.
"""
from datetime import datetime
from typing import Optional

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

from auth import get_current_user, require_cap
from database import get_db
from models.settings import KitchenSettings
from models.user import User

router = APIRouter()


class KDSSettingsResponse(BaseModel):
    kds_enabled: bool = False
    kds_graphql_url: Optional[str] = None
    kds_graphql_username: Optional[str] = None
    kds_graphql_password_set: bool = False
    kds_graphql_client_id: Optional[str] = None
    kds_poll_interval_seconds: int = 6000
    kds_timer_green_seconds: int = 300
    kds_timer_amber_seconds: int = 600
    kds_timer_red_seconds: int = 900
    kds_away_timer_green_seconds: int = 600
    kds_away_timer_amber_seconds: int = 900
    kds_away_timer_red_seconds: int = 1200
    kds_course_order: list = ["Starters", "Mains", "Desserts"]
    kds_show_completed_for_seconds: int = 30
    kds_bookings_refresh_seconds: int = 60

    class Config:
        from_attributes = True


class KDSSettingsUpdate(BaseModel):
    kds_enabled: Optional[bool] = None
    kds_graphql_url: Optional[str] = None
    kds_graphql_username: Optional[str] = None
    kds_graphql_password: Optional[str] = None
    kds_graphql_client_id: Optional[str] = None
    kds_poll_interval_seconds: Optional[int] = None
    kds_timer_green_seconds: Optional[int] = None
    kds_timer_amber_seconds: Optional[int] = None
    kds_timer_red_seconds: Optional[int] = None
    kds_away_timer_green_seconds: Optional[int] = None
    kds_away_timer_amber_seconds: Optional[int] = None
    kds_away_timer_red_seconds: Optional[int] = None
    kds_course_order: Optional[list] = None
    kds_show_completed_for_seconds: Optional[int] = None
    kds_bookings_refresh_seconds: Optional[int] = None


def _normalize_course_config(course_order: list, s: KitchenSettings) -> list:
    result = []
    for entry in course_order:
        if isinstance(entry, str):
            result.append({
                "name": entry,
                "prep_green": s.kds_timer_green_seconds or 300,
                "prep_amber": s.kds_timer_amber_seconds or 600,
                "prep_red": s.kds_timer_red_seconds or 900,
                "away_green": s.kds_away_timer_green_seconds or 600,
                "away_amber": s.kds_away_timer_amber_seconds or 900,
                "away_red": s.kds_away_timer_red_seconds or 1200,
            })
        elif isinstance(entry, dict) and "name" in entry:
            result.append(entry)
    return result


async def _get_settings(db: AsyncSession, kitchen_id: int):
    result = await db.execute(
        select(KitchenSettings).where(KitchenSettings.kitchen_id == kitchen_id)
    )
    return result.scalar_one_or_none()


def _to_response(s: KitchenSettings) -> KDSSettingsResponse:
    raw = s.kds_course_order or ["Starters", "Mains", "Desserts"]
    return KDSSettingsResponse(
        kds_enabled=s.kds_enabled or False,
        kds_graphql_url=s.kds_graphql_url,
        kds_graphql_username=s.kds_graphql_username,
        kds_graphql_password_set=bool(s.kds_graphql_password),
        kds_graphql_client_id=s.kds_graphql_client_id,
        kds_poll_interval_seconds=s.kds_poll_interval_seconds or 6000,
        kds_timer_green_seconds=s.kds_timer_green_seconds or 300,
        kds_timer_amber_seconds=s.kds_timer_amber_seconds or 600,
        kds_timer_red_seconds=s.kds_timer_red_seconds or 900,
        kds_away_timer_green_seconds=s.kds_away_timer_green_seconds or 600,
        kds_away_timer_amber_seconds=s.kds_away_timer_amber_seconds or 900,
        kds_away_timer_red_seconds=s.kds_away_timer_red_seconds or 1200,
        kds_course_order=_normalize_course_config(raw, s),
        kds_show_completed_for_seconds=s.kds_show_completed_for_seconds or 30,
        kds_bookings_refresh_seconds=s.kds_bookings_refresh_seconds or 60,
    )


@router.get("/settings", response_model=KDSSettingsResponse)
async def get_kds_settings(
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    s = await _get_settings(db, current_user.kitchen_id)
    if not s:
        return KDSSettingsResponse()
    return _to_response(s)


@router.patch("/settings", response_model=KDSSettingsResponse)
async def update_kds_settings(
    update: KDSSettingsUpdate,
    current_user: User = Depends(require_cap("settings")),
    db: AsyncSession = Depends(get_db),
):
    s = await _get_settings(db, current_user.kitchen_id)
    if not s:
        raise HTTPException(status_code=404, detail="Kitchen settings not found")

    for field, value in update.model_dump(exclude_unset=True).items():
        if hasattr(s, field):
            setattr(s, field, value)

    s.updated_at = datetime.utcnow()
    await db.commit()
    await db.refresh(s)
    return _to_response(s)
