from __future__ import annotations

from typing import Any

from fastapi import HTTPException

from backend.auth.dependencies import default_tenant_id

_AUTH_USER_DIRECTORY_SCHEMA_CACHE_KEY = "_auth_user_directory_schema_ready"


def _sql_text_literal(value: str) -> str:
    return "'" + value.replace("'", "''") + "'"


async def ensure_user_directory_schema(app: Any) -> None:
    if getattr(app.state, _AUTH_USER_DIRECTORY_SCHEMA_CACHE_KEY, False):
        return

    pool = getattr(app.state, "db_pool", None)
    if pool is None:
        raise HTTPException(status_code=503, detail="Database unavailable.")

    tenant_fallback = default_tenant_id()
    tenant_default_literal = _sql_text_literal(tenant_fallback)

    async with pool.acquire() as conn:
        await conn.execute("ALTER TABLE users_and_roles ADD COLUMN IF NOT EXISTS tenant_id TEXT")
        await conn.execute(
            """
            UPDATE users_and_roles
            SET tenant_id = $1
            WHERE tenant_id IS NULL OR tenant_id = ''
            """,
            tenant_fallback,
        )
        await conn.execute(
            f"ALTER TABLE users_and_roles ALTER COLUMN tenant_id SET DEFAULT {tenant_default_literal}"
        )
        await conn.execute("ALTER TABLE users_and_roles ALTER COLUMN tenant_id SET NOT NULL")
        await conn.execute(
            "CREATE INDEX IF NOT EXISTS idx_users_tenant_active ON users_and_roles (tenant_id, is_active)"
        )

    setattr(app.state, _AUTH_USER_DIRECTORY_SCHEMA_CACHE_KEY, True)
