"""Mint a short-lived Cloud app JWT for live legacy exports.

Core never has the generated app's SESSION_SECRET, so it cannot forge the
homemade `p2hs_session` cookie. It can sign the same RS256 app JWT Cloud
already verifies for `/auth/me` and platform BFF adapters.
"""
from __future__ import annotations

import time
from uuid import UUID

from jose import jwt

EXPORT_TOKEN_TTL_SECONDS = 600


def sign_project_app_jwt(
    *,
    private_pem: str,
    key_id: str,
    project_id: str,
    workspace_id: str,
    user_id: str,
    email: str,
    role: str,
    ttl_seconds: int = EXPORT_TOKEN_TTL_SECONDS,
) -> str:
    now = int(time.time())
    return jwt.encode(
        {
            "sub": user_id,
            "project_id": project_id,
            "workspace_id": workspace_id,
            "email": email,
            "role": role,
            "app_metadata": {"source": "legacy_export"},
            "user_metadata": {},
            "iat": now,
            "exp": now + max(60, min(int(ttl_seconds), EXPORT_TOKEN_TTL_SECONDS)),
        },
        private_pem,
        algorithm="RS256",
        headers={"kid": key_id, "typ": "JWT"},
    )


async def mint_workspace_owner_export_token(db, project_id: str) -> str:
    """Ensure Cloud auth, then sign a staff JWT for the workspace owner."""
    from src.core.security.encryption import decrypt_value
    from src.domain.codegen.legacy_cloud_cutover import ensure_cloud_auth_for_project
    from src.domain.project_auth.repository import (
        ProjectAuthConfigRepository,
        ProjectAuthKeyRepository,
    )
    from src.domain.project_auth.staff_directory import identities_for_workspace
    from src.domain.projects.repository import ProjectRepository
    from src.domain.workspaces.models import Workspace
    from src.integrations.cloud_control_client import get_cloud_client_for_workspace

    project = await ProjectRepository(db).get_by_id(UUID(project_id))
    if not project:
        raise ValueError("Project not found")
    await ensure_cloud_auth_for_project(db, project.id)
    workspace = await db.get(Workspace, project.workspace_id)
    owner = next(
        (
            item
            for item in await identities_for_workspace(
                db, project.workspace_id, getattr(workspace, "owner_id", None)
            )
            if item.is_owner
        ),
        None,
    )
    if not owner:
        raise ValueError("Workspace owner email is missing; cannot mint an export token")
    cloud = await get_cloud_client_for_workspace(project.workspace_id, db)
    match = next(
        (
            user
            for user in await cloud.list_app_users(str(project.id))
            if str(user.get("email") or "").strip().lower() == owner.email
        ),
        None,
    )
    if not match or not match.get("id"):
        raise ValueError(
            "Workspace owner is not a Cloud app user yet; Cloud auth must be provisioned first"
        )
    if match.get("role") not in {"admin", "super_admin"}:
        raise ValueError("Workspace owner is not a staff Cloud identity")
    key = await ProjectAuthKeyRepository(db).get_active_for_project(project.id)
    if not key:
        raise ValueError("Project auth signing key is missing")
    config = await ProjectAuthConfigRepository(db).get_by_project(project.id)
    ttl = int(getattr(config, "access_token_ttl_seconds", None) or EXPORT_TOKEN_TTL_SECONDS)
    return sign_project_app_jwt(
        private_pem=decrypt_value(key.private_key_enc),
        key_id=key.key_id,
        project_id=str(project.id),
        workspace_id=str(project.workspace_id),
        user_id=str(match["id"]),
        email=owner.email,
        role=str(match["role"]),
        ttl_seconds=ttl,
    )
