"""Embedded browser UI preferences API."""

from __future__ import annotations

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

from server.api.auth_jwt import get_current_admin
from server.api.dependencies import get_db
from server.domain.models import Admin
from server.infrastructure.database.admin_ui_preference_repo import AdminUiPreferenceRepositoryImpl
from server.utils.browser_ui_state import (
    BROWSER_UI_CONTEXT,
    merge_browser_state,
    parse_browser_state,
    record_visit,
)

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


class BrowserVisitRecord(BaseModel):
    url: str
    title: str | None = None


class BrowserTabState(BaseModel):
    id: str
    url: str
    title: str | None = None
    stack: list[str] | None = None
    stack_index: int | None = None


class BrowserPanelRect(BaseModel):
    x: float
    y: float
    w: float
    h: float


class BrowserStateUpdate(BaseModel):
    url_history: list[str] | None = None
    visits: list[dict] | None = None
    tabs: list[BrowserTabState] | None = None
    active_tab_id: str | None = None
    minimized: bool | None = None
    rect: BrowserPanelRect | None = None
    minimized_rect: BrowserPanelRect | None = None
    record_url: str | None = Field(default=None, description="Append one visit + history entry")
    record_title: str | None = None


@router.get("/state")
async def get_browser_state(
    admin: Admin = Depends(get_current_admin),
    db: AsyncSession = Depends(get_db),
):
    repo = AdminUiPreferenceRepositoryImpl(db)
    raw = await repo.get(admin.id, BROWSER_UI_CONTEXT)
    return parse_browser_state(raw)


@router.put("/state")
async def put_browser_state(
    payload: BrowserStateUpdate,
    admin: Admin = Depends(get_current_admin),
    db: AsyncSession = Depends(get_db),
):
    repo = AdminUiPreferenceRepositoryImpl(db)
    current = parse_browser_state(await repo.get(admin.id, BROWSER_UI_CONTEXT))

    incoming = payload.model_dump(exclude_none=True)
    if payload.tabs is not None:
        incoming["tabs"] = [t.model_dump(exclude_none=True) for t in payload.tabs]
    if payload.rect is not None:
        incoming["rect"] = payload.rect.model_dump()
    if payload.minimized_rect is not None:
        incoming["minimized_rect"] = payload.minimized_rect.model_dump()

    merged = merge_browser_state(current, incoming)
    if payload.record_url:
        merged = record_visit(merged, payload.record_url, payload.record_title)

    await repo.upsert(admin.id, BROWSER_UI_CONTEXT, merged)
    return merged
