"""One-time backfill: set owner_user_id on existing saas-membership records.

saas-membership v1.1.0 enabled rls_enabled on app_subscription, but that does
not retroactively set owner_user_id on records created under v1.0.0 (before
RLS existed) -- their actual owner's own session would see nothing until this
runs. This is fully deterministic, not a guess: app_subscription already
carries the owning app_user_id in its own data (it was a required field even
at v1.0.0).

Default is dry-run.

Usage (P2HS-BE root, same .env as the API):

    python -m scripts.backfill_saas_membership_ownership --project-id <uuid>
    python -m scripts.backfill_saas_membership_ownership --project-id <uuid> --apply
"""
from __future__ import annotations

import argparse
import asyncio
import json
from uuid import UUID

from src.core.orm_import import import_all_orm_models

import_all_orm_models()


def _record_data(record: dict) -> dict:
    raw = record.get("data_json")
    if not raw:
        return {}
    try:
        parsed = json.loads(raw)
        return parsed if isinstance(parsed, dict) else {}
    except (TypeError, ValueError):
        return {}


async def _backfill(project_id: UUID, apply: bool) -> None:
    from src.core.database import async_session_factory
    from src.domain.projects.repository import ProjectRepository
    from src.integrations.cloud_control_client import get_cloud_client_for_workspace

    async with async_session_factory() as db:
        project = await ProjectRepository(db).get_by_id(project_id)
        if not project:
            print(f"[error] project {project_id} not found")
            return
        client = await get_cloud_client_for_workspace(project.workspace_id, db)

    pid = str(project_id)

    checked = fixed = skipped = 0
    cursor = None
    while True:
        page = await client.query_project_records(pid, "app_subscription", limit=100, cursor=cursor)
        for record in page.get("records", []):
            checked += 1
            record_id = record["id"]
            if record.get("owner_user_id"):
                skipped += 1
                continue
            app_user_id = _record_data(record).get("app_user_id")
            if not app_user_id:
                print(f"[warn] app_subscription {record_id} has no app_user_id -- cannot backfill, skipping")
                skipped += 1
                continue
            fixed += 1
            if apply:
                await client.set_record_owner(pid, "app_subscription", record_id, app_user_id)
        cursor = page.get("next_cursor")
        if not cursor:
            break

    mode = "APPLIED" if apply else "DRY-RUN"
    print(f"[{mode}] app_subscription: checked={checked} fixed={fixed} skipped={skipped}")
    if not apply and fixed:
        print("Re-run with --apply to write these changes.")


def main() -> None:
    parser = argparse.ArgumentParser(
        description="Backfill owner_user_id on saas-membership records after enabling RLS"
    )
    parser.add_argument("--project-id", required=True, help="Project UUID")
    parser.add_argument("--apply", action="store_true", help="Write changes (default: dry-run)")
    args = parser.parse_args()
    asyncio.run(_backfill(UUID(args.project_id), args.apply))


if __name__ == "__main__":
    main()
