"""Dashboard widget configuration endpoints."""
import logging
import uuid
from typing import Any

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

from app.database import get_db
from app.domains.admin.dashboard_service import (
    get_user_dashboard_config,
    upsert_user_dashboard_config,
    upsert_tenant_default,
)
from app.utils.auth import get_current_user, require_admin
from app.models.user import User

logger = logging.getLogger(__name__)

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


# ---------------------------------------------------------------------------
# Schemas
# ---------------------------------------------------------------------------

class WidgetPosition(BaseModel):
    col: int
    row: int
    w: int
    h: int


class WidgetConfig(BaseModel):
    widget_type: str
    position: WidgetPosition
    config: dict[str, Any] | None = None


class DashboardConfigPayload(BaseModel):
    widgets: list[WidgetConfig]


class DashboardConfigResponse(BaseModel):
    widgets: list[WidgetConfig]


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def _to_response(widgets: list[dict]) -> DashboardConfigResponse:
    parsed = []
    for w in widgets:
        pos = w.get("position", {})
        parsed.append(
            WidgetConfig(
                widget_type=w.get("widget_type", ""),
                position=WidgetPosition(
                    col=pos.get("col", 0),
                    row=pos.get("row", 0),
                    w=pos.get("w", 1),
                    h=pos.get("h", 1),
                ),
                config=w.get("config"),
            )
        )
    return DashboardConfigResponse(widgets=parsed)


# ---------------------------------------------------------------------------
# Endpoints
# ---------------------------------------------------------------------------

@router.get("/config", response_model=DashboardConfigResponse)
async def get_config(
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> DashboardConfigResponse:
    """Load the current user's dashboard widget config (with fallback cascade)."""
    widgets = await get_user_dashboard_config(
        db=db,
        user_id=current_user.id,
        tenant_id=current_user.tenant_id,
        role=current_user.role.value,
    )
    return _to_response(widgets)


@router.put("/config", response_model=DashboardConfigResponse)
async def update_config(
    payload: DashboardConfigPayload,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> DashboardConfigResponse:
    """Save or update the current user's dashboard widget config."""
    widgets_raw = [w.model_dump() for w in payload.widgets]
    config = await upsert_user_dashboard_config(
        db=db,
        user_id=current_user.id,
        tenant_id=current_user.tenant_id,
        widgets=widgets_raw,
    )
    return _to_response(list(config.widgets))


@router.get("/tenant-default", response_model=DashboardConfigResponse)
async def get_tenant_default(
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
) -> DashboardConfigResponse:
    """Load the tenant-default dashboard widget config (admin only)."""
    from sqlalchemy import select
    from app.domains.admin.models import DashboardConfig

    if current_user.tenant_id is None:
        return DashboardConfigResponse(widgets=[])

    result = await db.execute(
        select(DashboardConfig).where(
            DashboardConfig.tenant_id == current_user.tenant_id,
            DashboardConfig.is_tenant_default.is_(True),
        )
    )
    config = result.scalar_one_or_none()
    if config is None:
        return DashboardConfigResponse(widgets=[])
    return _to_response(list(config.widgets))


@router.put("/tenant-default", response_model=DashboardConfigResponse)
async def update_tenant_default(
    payload: DashboardConfigPayload,
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
) -> DashboardConfigResponse:
    """Set the tenant-default widget config (admin only)."""
    if current_user.tenant_id is None:
        from fastapi import HTTPException, status
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Admin user has no tenant_id assigned.",
        )

    widgets_raw = [w.model_dump() for w in payload.widgets]
    config = await upsert_tenant_default(
        db=db,
        tenant_id=current_user.tenant_id,
        widgets=widgets_raw,
    )
    return _to_response(list(config.widgets))
