import jwt
import pytest
from fastapi import FastAPI, HTTPException
from fastapi.testclient import TestClient

from modules.auth.supabase_bearer import verify_supabase_token_dep
from routers.tlsync_token import TLSYNC_TOKEN_AUDIENCE, create_tlsync_token, router


def test_create_tlsync_token_is_short_lived_and_signed(monkeypatch):
    monkeypatch.setenv("TLSYNC_SECRET", "test-tlsync-secret-with-at-least-32-bytes")
    monkeypatch.setenv("TLSYNC_TOKEN_TTL_SECONDS", "120")

    response = create_tlsync_token({"sub": "user-123"})

    assert response["token_type"] == "Bearer"
    assert response["expires_in"] == 120
    assert response["token"]

    payload = jwt.decode(
        response["token"],
        "test-tlsync-secret-with-at-least-32-bytes",
        algorithms=["HS256"],
        audience=TLSYNC_TOKEN_AUDIENCE,
    )
    assert payload["sub"] == "user-123"
    assert payload["exp"] == response["expires_at"]
    assert payload["exp"] - payload["iat"] == 120
    assert payload["jti"]


def test_create_tlsync_token_requires_tlsync_secret(monkeypatch):
    monkeypatch.delenv("TLSYNC_SECRET", raising=False)

    with pytest.raises(HTTPException) as excinfo:
        create_tlsync_token({"sub": "user-123"})

    assert excinfo.value.status_code == 503


def test_create_tlsync_token_requires_authenticated_subject(monkeypatch):
    monkeypatch.setenv("TLSYNC_SECRET", "test-tlsync-secret-with-at-least-32-bytes")

    with pytest.raises(HTTPException) as excinfo:
        create_tlsync_token({})

    assert excinfo.value.status_code == 401


def test_tlsync_token_route_uses_authenticated_user_claims(monkeypatch):
    monkeypatch.setenv("TLSYNC_SECRET", "test-tlsync-secret-with-at-least-32-bytes")
    monkeypatch.setenv("TLSYNC_TOKEN_TTL_SECONDS", "60")

    app = FastAPI()
    app.include_router(router, prefix="/api/tlsync")
    app.dependency_overrides[verify_supabase_token_dep] = lambda: {"sub": "route-user-123"}

    response = TestClient(app).get("/api/tlsync/token", headers={"Authorization": "Bearer supabase-jwt"})

    assert response.status_code == 200
    body = response.json()
    payload = jwt.decode(
        body["token"],
        "test-tlsync-secret-with-at-least-32-bytes",
        algorithms=["HS256"],
        audience=TLSYNC_TOKEN_AUDIENCE,
    )
    assert payload["sub"] == "route-user-123"
    assert body["expires_in"] == 60
