"""Scope-aware client services using the existing registrations module."""

from alembic import op
import sqlalchemy as sa

revision = "20260805_scope_aware_services"
down_revision = "20260805_client_service_plan_master"
branch_labels = None
depends_on = None


def upgrade():
    op.create_table(
        "client_business_units",
        sa.Column("id", sa.Integer(), primary_key=True, autoincrement=True),
        sa.Column("tenant_id", sa.Integer(), sa.ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False),
        sa.Column("client_id", sa.Integer(), sa.ForeignKey("clients.id", ondelete="CASCADE"), nullable=False),
        sa.Column("business_code", sa.String(50), nullable=False),
        sa.Column("business_name", sa.String(200), nullable=False),
        sa.Column("trade_name", sa.String(200), nullable=True),
        sa.Column("nature_of_business", sa.String(200), nullable=True),
        sa.Column("is_primary", sa.Boolean(), nullable=False, server_default=sa.false()),
        sa.Column("is_active", sa.Boolean(), nullable=False, server_default=sa.true()),
        sa.Column("created_by_user_id", sa.Integer(), sa.ForeignKey("users.id"), nullable=True),
        sa.Column("updated_by_user_id", sa.Integer(), sa.ForeignKey("users.id"), nullable=True),
        sa.Column("created_at_utc", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
        sa.Column("updated_at_utc", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
        sa.UniqueConstraint("tenant_id", "client_id", "business_code", name="uq_cbu_tenant_client_code"),
    )
    op.create_index("ix_client_business_units_tenant_id", "client_business_units", ["tenant_id"])
    op.create_index("ix_client_business_units_client_id", "client_business_units", ["client_id"])

    op.create_table(
        "client_branches",
        sa.Column("id", sa.Integer(), primary_key=True, autoincrement=True),
        sa.Column("tenant_id", sa.Integer(), sa.ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False),
        sa.Column("client_id", sa.Integer(), sa.ForeignKey("clients.id", ondelete="CASCADE"), nullable=False),
        sa.Column("business_unit_id", sa.Integer(), sa.ForeignKey("client_business_units.id", ondelete="CASCADE"), nullable=False),
        sa.Column("branch_code", sa.String(50), nullable=False),
        sa.Column("branch_name", sa.String(200), nullable=False),
        sa.Column("branch_type", sa.String(40), nullable=False, server_default="branch"),
        sa.Column("address_line_1", sa.String(255), nullable=True),
        sa.Column("address_line_2", sa.String(255), nullable=True),
        sa.Column("city", sa.String(100), nullable=True),
        sa.Column("state", sa.String(100), nullable=True),
        sa.Column("pincode", sa.String(20), nullable=True),
        sa.Column("is_primary", sa.Boolean(), nullable=False, server_default=sa.false()),
        sa.Column("is_active", sa.Boolean(), nullable=False, server_default=sa.true()),
        sa.Column("created_by_user_id", sa.Integer(), sa.ForeignKey("users.id"), nullable=True),
        sa.Column("updated_by_user_id", sa.Integer(), sa.ForeignKey("users.id"), nullable=True),
        sa.Column("created_at_utc", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
        sa.Column("updated_at_utc", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
        sa.UniqueConstraint("tenant_id", "business_unit_id", "branch_code", name="uq_cbranch_tenant_business_code"),
    )
    op.create_index("ix_client_branches_tenant_id", "client_branches", ["tenant_id"])
    op.create_index("ix_client_branches_client_id", "client_branches", ["client_id"])
    op.create_index("ix_client_branches_business_unit_id", "client_branches", ["business_unit_id"])

    # Reuse and extend the production client_registrations table introduced in Phase 4.
    with op.batch_alter_table("client_registrations") as batch:
        batch.add_column(sa.Column("business_unit_id", sa.Integer(), nullable=True))
        batch.add_column(sa.Column("client_branch_id", sa.Integer(), nullable=True))
        batch.add_column(sa.Column("legal_name", sa.String(200), nullable=True))
        batch.add_column(sa.Column("trade_name", sa.String(200), nullable=True))
        batch.add_column(sa.Column("state", sa.String(100), nullable=True))
        batch.create_foreign_key(
            "fk_client_registrations_business_unit",
            "client_business_units", ["business_unit_id"], ["id"], ondelete="SET NULL"
        )
        batch.create_foreign_key(
            "fk_client_registrations_client_branch",
            "client_branches", ["client_branch_id"], ["id"], ondelete="SET NULL"
        )
        batch.create_index("ix_client_registrations_business_unit_id", ["business_unit_id"])
        batch.create_index("ix_client_registrations_client_branch_id", ["client_branch_id"])

    with op.batch_alter_table("service_catalogues") as batch:
        batch.add_column(sa.Column("service_scope_type", sa.String(30), nullable=False, server_default="client"))
        batch.add_column(sa.Column("required_registration_type", sa.String(40), nullable=True))
        batch.create_index("ix_service_catalogues_service_scope_type", ["service_scope_type"])
        batch.create_index("ix_service_catalogues_required_registration_type", ["required_registration_type"])

    for table in ("client_service_plans", "client_service_subscriptions"):
        with op.batch_alter_table(table) as batch:
            batch.add_column(sa.Column("scope_type", sa.String(30), nullable=False, server_default="client"))
            batch.add_column(sa.Column("scope_key", sa.String(80), nullable=False, server_default=""))
            batch.add_column(sa.Column("business_unit_id", sa.Integer(), nullable=True))
            batch.add_column(sa.Column("client_branch_id", sa.Integer(), nullable=True))
            batch.add_column(sa.Column("registration_id", sa.Integer(), nullable=True))
            batch.create_foreign_key(f"fk_{table}_business_unit", "client_business_units", ["business_unit_id"], ["id"], ondelete="SET NULL")
            batch.create_foreign_key(f"fk_{table}_client_branch", "client_branches", ["client_branch_id"], ["id"], ondelete="SET NULL")
            batch.create_foreign_key(f"fk_{table}_registration", "client_registrations", ["registration_id"], ["id"], ondelete="SET NULL")
            batch.create_index(f"ix_{table}_scope_type", ["scope_type"])
            batch.create_index(f"ix_{table}_scope_key", ["scope_key"])
            batch.create_index(f"ix_{table}_business_unit_id", ["business_unit_id"])
            batch.create_index(f"ix_{table}_client_branch_id", ["client_branch_id"])
            batch.create_index(f"ix_{table}_registration_id", ["registration_id"])

    op.execute("UPDATE client_service_plans SET scope_key = 'CLIENT:' || client_id WHERE scope_key = ''")
    op.execute("UPDATE client_service_subscriptions SET scope_key = 'CLIENT:' || client_id WHERE scope_key = ''")

    with op.batch_alter_table("client_service_plans") as batch:
        batch.drop_constraint("uq_csp_tenant_client_service", type_="unique")
        batch.create_unique_constraint("uq_csp_tenant_service_scope", ["tenant_id", "service_catalogue_id", "scope_key"])

    with op.batch_alter_table("client_service_subscriptions") as batch:
        batch.drop_constraint("uq_css_tenant_client_service_fy_period", type_="unique")
        batch.create_unique_constraint(
            "uq_css_tenant_service_scope_fy_period",
            ["tenant_id", "service_catalogue_id", "scope_key", "financial_year", "period_label"],
        )


def downgrade():
    with op.batch_alter_table("client_service_subscriptions") as batch:
        batch.drop_constraint("uq_css_tenant_service_scope_fy_period", type_="unique")
        batch.create_unique_constraint(
            "uq_css_tenant_client_service_fy_period",
            ["tenant_id", "client_id", "service_catalogue_id", "financial_year", "period_label"],
        )
        for name in ("registration_id", "client_branch_id", "business_unit_id", "scope_key", "scope_type"):
            batch.drop_column(name)

    with op.batch_alter_table("client_service_plans") as batch:
        batch.drop_constraint("uq_csp_tenant_service_scope", type_="unique")
        batch.create_unique_constraint("uq_csp_tenant_client_service", ["tenant_id", "client_id", "service_catalogue_id"])
        for name in ("registration_id", "client_branch_id", "business_unit_id", "scope_key", "scope_type"):
            batch.drop_column(name)

    with op.batch_alter_table("service_catalogues") as batch:
        batch.drop_column("required_registration_type")
        batch.drop_column("service_scope_type")

    with op.batch_alter_table("client_registrations") as batch:
        for name in ("state", "trade_name", "legal_name", "client_branch_id", "business_unit_id"):
            batch.drop_column(name)

    op.drop_table("client_branches")
    op.drop_table("client_business_units")
