"""
Add user_roles and billing_customers tables.
Migrate paddle_customer_id from subscriptions to billing_customers.
Rename paddle_subscription_id -> provider_subscription_id.
Drop UNIQUE on subscriptions.user_id (allow multiple subs per user).
"""


def _column_names(conn, table):
    return [r[1] for r in conn.execute(f"PRAGMA table_info({table})").fetchall()]


def up(conn):
    # 1. Create new tables (idempotent)
    conn.execute("""
        CREATE TABLE IF NOT EXISTS user_roles (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
            role TEXT NOT NULL,
            granted_at TEXT NOT NULL DEFAULT (datetime('now')),
            UNIQUE(user_id, role)
        )
    """)
    conn.execute("CREATE INDEX IF NOT EXISTS idx_user_roles_user ON user_roles(user_id)")
    conn.execute("CREATE INDEX IF NOT EXISTS idx_user_roles_role ON user_roles(role)")
    conn.execute("""
        CREATE TABLE IF NOT EXISTS billing_customers (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id INTEGER NOT NULL UNIQUE REFERENCES users(id),
            provider_customer_id TEXT NOT NULL,
            created_at TEXT NOT NULL DEFAULT (datetime('now'))
        )
    """)
    conn.execute(
        "CREATE INDEX IF NOT EXISTS idx_billing_customers_user ON billing_customers(user_id)"
    )
    conn.execute(
        "CREATE INDEX IF NOT EXISTS idx_billing_customers_provider"
        " ON billing_customers(provider_customer_id)"
    )

    cols = _column_names(conn, "subscriptions")

    # Already migrated — nothing to do
    if "provider_subscription_id" in cols and "paddle_customer_id" not in cols:
        return

    # 2. Migrate paddle_customer_id from subscriptions to billing_customers
    if "paddle_customer_id" in cols:
        conn.execute("""
            INSERT OR IGNORE INTO billing_customers (user_id, provider_customer_id)
            SELECT user_id, paddle_customer_id
            FROM subscriptions
            WHERE paddle_customer_id IS NOT NULL AND paddle_customer_id != ''
            GROUP BY user_id
            HAVING MAX(created_at)
        """)

    # 3. Recreate subscriptions table:
    #    - Drop paddle_customer_id (moved to billing_customers)
    #    - Rename paddle_subscription_id -> provider_subscription_id
    #    - Drop UNIQUE constraint on user_id (allow multiple subs per user)
    old_sub_col = "paddle_subscription_id" if "paddle_subscription_id" in cols else "provider_subscription_id"

    conn.execute("ALTER TABLE subscriptions RENAME TO _subscriptions_old")
    conn.execute("""
        CREATE TABLE subscriptions (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id INTEGER NOT NULL REFERENCES users(id),
            plan TEXT NOT NULL DEFAULT 'free',
            status TEXT NOT NULL DEFAULT 'free',
            provider_subscription_id TEXT,
            current_period_end TEXT,
            created_at TEXT NOT NULL,
            updated_at TEXT
        )
    """)
    conn.execute(
        "CREATE INDEX IF NOT EXISTS idx_subscriptions_user ON subscriptions(user_id)"
    )
    conn.execute(
        "CREATE INDEX IF NOT EXISTS idx_subscriptions_provider"
        " ON subscriptions(provider_subscription_id)"
    )
    conn.execute(f"""
        INSERT INTO subscriptions (id, user_id, plan, status, provider_subscription_id,
                                   current_period_end, created_at, updated_at)
        SELECT id, user_id, plan, status, {old_sub_col},
               current_period_end, created_at, updated_at
        FROM _subscriptions_old
    """)
    conn.execute("DROP TABLE _subscriptions_old")
