"""tenancy: RBAC cleanup — consolidate user roles and drop legacy columns

Migrates users.role from old 3-value scheme (admin/store/user) to new
4-value scheme (super_admin/platform_admin/merchant_owner/store_member).
Drops the now-redundant users.is_super_admin and store_users.user_type columns.

Revision ID: tenancy_003
Revises: tenancy_002
Create Date: 2026-02-19
"""
import sqlalchemy as sa

from alembic import op

revision = "tenancy_003"
down_revision = "tenancy_002"
branch_labels = None
depends_on = None


def upgrade() -> None:
    # ------------------------------------------------------------------
    # Step 1: Data migration — remap role values using is_super_admin
    #         and merchant ownership to determine the new role.
    #
    # Order matters: the 'admin' rows must be split before we touch
    # 'store' or 'user' rows, and 'merchant_owner' for role='user'
    # (bug fix) must come before the catch-all 'store_member' update.
    # ------------------------------------------------------------------

    # admin + is_super_admin=true  ->  super_admin
    op.execute(
        "UPDATE users SET role = 'super_admin' "
        "WHERE role = 'admin' AND is_super_admin = true"
    )

    # admin + is_super_admin=false  ->  platform_admin
    op.execute(
        "UPDATE users SET role = 'platform_admin' "
        "WHERE role = 'admin' AND is_super_admin = false"
    )

    # store users who own a merchant  ->  merchant_owner
    op.execute(
        "UPDATE users SET role = 'merchant_owner' "
        "WHERE role = 'store' "
        "AND id IN (SELECT owner_user_id FROM merchants)"
    )

    # legacy 'user' role (bug — should have been 'store')  ->  merchant_owner
    op.execute(
        "UPDATE users SET role = 'merchant_owner' "
        "WHERE role = 'user'"
    )

    # remaining store users (not merchant owners)  ->  store_member
    op.execute(
        "UPDATE users SET role = 'store_member' "
        "WHERE role = 'store' "
        "AND id NOT IN (SELECT owner_user_id FROM merchants)"
    )

    # ------------------------------------------------------------------
    # Step 2: Drop legacy columns that are now redundant
    # ------------------------------------------------------------------

    # users.is_super_admin is replaced by role = 'super_admin'
    op.drop_column("users", "is_super_admin")

    # store_users.user_type is replaced by users.role (merchant_owner vs store_member)
    op.drop_column("store_users", "user_type")


def downgrade() -> None:
    # ------------------------------------------------------------------
    # Step 1: Re-add dropped columns
    # ------------------------------------------------------------------

    op.add_column(
        "users",
        sa.Column(
            "is_super_admin",
            sa.Boolean(),
            nullable=False,
            server_default="false",
        ),
    )

    op.add_column(
        "store_users",
        sa.Column(
            "user_type",
            sa.String(),
            nullable=False,
            server_default="member",
        ),
    )

    # ------------------------------------------------------------------
    # Step 2: Reverse data migration — map new roles back to old scheme
    # ------------------------------------------------------------------

    # Mark super admins
    op.execute(
        "UPDATE users SET is_super_admin = true "
        "WHERE role = 'super_admin'"
    )

    # super_admin + platform_admin  ->  admin
    op.execute(
        "UPDATE users SET role = 'admin' "
        "WHERE role IN ('super_admin', 'platform_admin')"
    )

    # merchant_owner + store_member  ->  store
    op.execute(
        "UPDATE users SET role = 'store' "
        "WHERE role IN ('merchant_owner', 'store_member')"
    )

    # ------------------------------------------------------------------
    # Step 3: Restore store_users.user_type based on merchant ownership
    #
    # If the user owns the merchant that owns the store, they are
    # an 'owner'; otherwise 'member'.
    # ------------------------------------------------------------------
    op.execute(
        "UPDATE store_users SET user_type = 'owner' "
        "WHERE user_id IN ("
        "  SELECT m.owner_user_id FROM merchants m"
        "  JOIN stores s ON s.merchant_id = m.id"
        "  WHERE s.id = store_users.store_id"
        ")"
    )
