from fastapi.testclient import TestClient

from zbt.core.config import Settings
from zbt.core.passwords import PasswordService
from zbt.domains.identity.models import AdminUser
from zbt.domains.identity.repository import InMemoryIdentityRepository
from zbt.main import create_app


def test_admin_login_returns_roles_permissions_and_data_scope() -> None:
    settings = Settings(
        app_env="test",
        jwt_access_secret="a" * 32,
        jwt_refresh_secret="b" * 32,
        field_encryption_key="c" * 32,
    )
    repository = InMemoryIdentityRepository()
    repository.save_admin_user(
        AdminUser(
            id="01ADMIN0000000000000000001",
            username="admin",
            password_hash=PasswordService().hash("zaq1XSW@"),
            display_name="系统管理员",
            status="ACTIVE",
            roles=("super_admin",),
            permissions=("role:read", "role:write", "product:read"),
            data_scope="ALL",
        )
    )
    app = create_app(settings=settings, identity_repository=repository)

    with TestClient(app) as client:
        login = client.post(
            "/api/v1/admin/auth/login",
            json={"username": "admin", "password": "zaq1XSW@"},
        )
        assert login.status_code == 200
        token = login.json()["data"]["tokens"]["access_token"]

        profile = client.get(
            "/api/v1/admin/me",
            headers={"Authorization": f"Bearer {token}"},
        )
        assert profile.status_code == 200
        assert profile.json()["data"]["roles"] == ["super_admin"]
        assert profile.json()["data"]["permissions"] == [
            "product:read",
            "role:read",
            "role:write",
        ]
        assert profile.json()["data"]["data_scope"] == "ALL"


def test_admin_refresh_cookie_restores_and_logout_revokes_session() -> None:
    settings = Settings(
        app_env="test",
        jwt_access_secret="a" * 32,
        jwt_refresh_secret="b" * 32,
        field_encryption_key="c" * 32,
    )
    repository = InMemoryIdentityRepository()
    repository.save_admin_user(
        AdminUser(
            id="01ADMIN0000000000000000001",
            username="admin",
            password_hash=PasswordService().hash("zaq1XSW@"),
            display_name="系统管理员",
            status="ACTIVE",
            roles=("SUPER_ADMIN",),
            permissions=("*",),
            data_scope="ALL",
        )
    )
    app = create_app(settings=settings, identity_repository=repository)

    with TestClient(app) as client:
        login = client.post(
            "/api/v1/admin/auth/login",
            json={"username": "admin", "password": "zaq1XSW@"},
        )
        assert "zbt_admin_refresh=" in login.headers["set-cookie"]
        assert "HttpOnly" in login.headers["set-cookie"]

        refreshed = client.post("/api/v1/admin/auth/refresh")
        assert refreshed.status_code == 200
        access_token = refreshed.json()["data"]["tokens"]["access_token"]

        logout = client.post(
            "/api/v1/admin/auth/logout",
            headers={"Authorization": f"Bearer {access_token}"},
        )
        assert logout.status_code == 200
        profile = client.get(
            "/api/v1/admin/me",
            headers={"Authorization": f"Bearer {access_token}"},
        )
        assert profile.status_code == 401
