"""Backfill memberships collection from existing pm_client_ids and team.member_user_ids."""

from datetime import UTC, datetime

from app.migrations.migrator import Migration


class Migration(Migration):

    def __init__(self):
        super().__init__()
        self.version = "2026-04-28-000001"
        self.description = "Backfill memberships from pm_client_ids and team member lists"

    async def up(self) -> None:
        now = datetime.now(UTC)
        upserted = 0

        # 1. PROJECT_MANAGER users → MANAGER membership for each pm_client_id
        async for user in self.db.users.find(
            {"pm_client_ids": {"$exists": True, "$ne": []}}
        ):
            user_id = str(user["_id"])
            for org_id in user.get("pm_client_ids", []):
                result = await self.db.memberships.update_one(
                    {"user_id": user_id, "organization_id": org_id},
                    {
                        "$setOnInsert": {
                            "user_id": user_id,
                            "organization_id": org_id,
                            "role_in_org": "manager",
                            "created_at": now,
                            "created_by": None,
                        }
                    },
                    upsert=True,
                )
                if result.upserted_id:
                    upserted += 1

        print(f"✅ Backfilled {upserted} MANAGER memberships from pm_client_ids")

        # 2. Team member_user_ids → MEMBER membership for the team's client/org
        team_upserted = 0
        async for team in self.db.teams.find(
            {"member_user_ids": {"$exists": True, "$ne": []}}
        ):
            org_id = team.get("client_id", "")
            if not org_id:
                continue
            for user_id in team.get("member_user_ids", []):
                # Only create MEMBER if no existing higher role
                existing = await self.db.memberships.find_one(
                    {"user_id": user_id, "organization_id": org_id}
                )
                if existing:
                    continue
                result = await self.db.memberships.update_one(
                    {"user_id": user_id, "organization_id": org_id},
                    {
                        "$setOnInsert": {
                            "user_id": user_id,
                            "organization_id": org_id,
                            "role_in_org": "member",
                            "created_at": now,
                            "created_by": None,
                        }
                    },
                    upsert=True,
                )
                if result.upserted_id:
                    team_upserted += 1

        print(f"✅ Backfilled {team_upserted} MEMBER memberships from team.member_user_ids")

        # 3. Users with role=client → VIEWER membership for their team's org
        client_upserted = 0
        async for user in self.db.users.find({"role": "client"}):
            user_id = str(user["_id"])
            # Find which teams this user is in
            async for team in self.db.teams.find(
                {"member_user_ids": user_id}
            ):
                org_id = team.get("client_id", "")
                if not org_id:
                    continue
                existing = await self.db.memberships.find_one(
                    {"user_id": user_id, "organization_id": org_id}
                )
                if existing:
                    continue
                result = await self.db.memberships.update_one(
                    {"user_id": user_id, "organization_id": org_id},
                    {
                        "$setOnInsert": {
                            "user_id": user_id,
                            "organization_id": org_id,
                            "role_in_org": "viewer",
                            "created_at": now,
                            "created_by": None,
                        }
                    },
                    upsert=True,
                )
                if result.upserted_id:
                    client_upserted += 1

        print(f"✅ Backfilled {client_upserted} VIEWER memberships for client-role users")
        print(f"✅ Applied migration {self.version}: {self.description}")

    async def down(self) -> None:
        # Remove only the backfilled memberships (created_by is None)
        result = await self.db.memberships.delete_many({"created_by": None})
        print(f"⚠️  Rolled back migration {self.version}: removed {result.deleted_count} backfilled memberships")
