from __future__ import annotations

from typing import TYPE_CHECKING, Any

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

if TYPE_CHECKING:
    from niannian.client import NianNian


class PinnSyncHandoffBody(BaseModel):
    control_plane: str = Field(min_length=1)
    bearer_token: str = Field(min_length=1)
    username: str = Field(min_length=1)
    role: str = Field(min_length=1)
    session_token: str | None = None


class PinnSyncSettingsPatch(BaseModel):
    smb_mount_path: str | None = None
    providers_local: str | None = None
    control_plane: str | None = None


def create_pinn_sync_client_router(_nn: NianNian) -> APIRouter:
    router = APIRouter(prefix="/v1/client/pinn-sync", tags=["client"])

    @router.get("/status")
    def get_pinn_sync_status() -> dict[str, Any]:
        from pinn_sync.auth import session_status

        return session_status()

    @router.get("/cloud-status")
    def get_cloud_status() -> dict[str, Any]:
        from pinn_sync.oauth import cloud_status

        return cloud_status()

    @router.get("/settings")
    def get_pinn_sync_settings() -> dict[str, Any]:
        from pinn_sync.settings_loader import load_settings

        cfg = load_settings()
        return cfg.to_dict()

    @router.patch("/settings")
    def patch_pinn_sync_settings(body: PinnSyncSettingsPatch) -> dict[str, Any]:
        from pinn_sync.run_cycle import update_settings_patch

        patch = body.model_dump(exclude_none=True)
        cfg = update_settings_patch(patch)
        return cfg.to_dict()

    @router.post("/handoff")
    def post_pinn_sync_handoff(body: PinnSyncHandoffBody) -> dict[str, Any]:
        from pinn_sync.auth import PinnSyncAuthError, handoff_session

        try:
            session = handoff_session(
                control_plane=body.control_plane,
                bearer_token=body.bearer_token,
                username=body.username,
                role=body.role,
                session_token=body.session_token,
            )
        except PinnSyncAuthError as exc:
            raise HTTPException(status_code=403, detail={"code": exc.code, "message": exc.message}) from exc
        return {"ok": True, "active": True, "updated_at": session.updated_at}

    @router.delete("/handoff")
    def delete_pinn_sync_handoff() -> dict[str, bool]:
        from pinn_sync.auth import logout_sync

        logout_sync()
        return {"ok": True}

    @router.post("/sync-now")
    def post_sync_now() -> dict[str, Any]:
        from pinn_sync.run_cycle import run_sync_cycle

        return run_sync_cycle()

    @router.post("/oauth/google")
    def post_google_oauth() -> dict[str, Any]:
        from pinn_sync.oauth import google_auth_url

        return google_auth_url()

    return router
