from datetime import datetime, timezone

import httpx
from fastapi import HTTPException

from app.models.google_workspace import GoogleWorkspaceConnection
from app.services.google_workspace_client import (
    expires_at_from_seconds,
    is_google_workspace_configured,
    refresh_google_access_token,
    utc_now_isoformat,
)
from app.services.google_workspace_store import get_google_workspace_store
from app.services.tenant_store import SessionIdentity


def ensure_google_workspace_configured() -> None:
    if not is_google_workspace_configured():
        raise HTTPException(
            status_code=503,
            detail="Google Workspace non configurato. Imposta GOOGLE_WORKSPACE_CLIENT_ID e GOOGLE_WORKSPACE_CLIENT_SECRET.",
        )


def parse_google_workspace_datetime(value: str) -> datetime:
    return datetime.fromisoformat(value.replace("Z", "+00:00"))


def build_google_workspace_connection(
    token_payload: dict[str, object],
    *,
    refresh_token: str | None,
    account_email: str | None,
    connected_at: str | None = None,
) -> GoogleWorkspaceConnection:
    expires_in = token_payload.get("expires_in")
    if not isinstance(expires_in, (int, float)):
        raise HTTPException(status_code=502, detail="Risposta token Google priva di expires_in")

    access_token = token_payload.get("access_token")
    if not access_token:
        raise HTTPException(status_code=502, detail="Risposta token Google priva di access_token")

    return GoogleWorkspaceConnection(
        access_token=str(access_token),
        refresh_token=refresh_token,
        scope=str(token_payload.get("scope") or ""),
        token_type=str(token_payload.get("token_type") or "Bearer"),
        expires_at=expires_at_from_seconds(expires_in),
        account_email=account_email,
        connected_at=connected_at or utc_now_isoformat(),
        updated_at=utc_now_isoformat(),
    )


async def get_active_google_workspace_connection(session: SessionIdentity) -> GoogleWorkspaceConnection:
    store = get_google_workspace_store()
    connection = store.get_connection(session.tenant_id, adopt_legacy_if_needed=True)
    if connection is None:
        raise HTTPException(status_code=409, detail="Nessun account Google collegato")

    expires_at = parse_google_workspace_datetime(connection.expires_at)
    now = datetime.now(timezone.utc)
    if expires_at > now.replace(microsecond=0):
        return connection

    if not connection.refresh_token:
        raise HTTPException(status_code=409, detail="Refresh token Google non disponibile. Ricollega l'account.")

    try:
        token_payload = await refresh_google_access_token(connection.refresh_token)
    except httpx.HTTPError as exc:
        raise HTTPException(status_code=502, detail=f"Refresh token Google fallito: {exc}") from exc

    refreshed = build_google_workspace_connection(
        token_payload,
        refresh_token=str(token_payload.get("refresh_token") or connection.refresh_token),
        account_email=connection.account_email,
        connected_at=connection.connected_at,
    )
    if not refreshed.scope:
        refreshed.scope = connection.scope
    store.set_connection(session.tenant_id, refreshed)
    return refreshed
