"""Add owner_id to projects and installation cache table for user scoping.

Revision ID: 0004
Revises: 0003
"""

from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op

revision: str = "0004"
down_revision: Union[str, None] = "0003"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    conn = op.get_bind()

    # Add owner_id column to projects (nullable — agent-created projects have no user)
    conn.execute(sa.text(
        "ALTER TABLE projects ADD COLUMN IF NOT EXISTS owner_id INTEGER REFERENCES users(id)"
    ))
    conn.execute(sa.text(
        "CREATE INDEX IF NOT EXISTS idx_projects_owner_id ON projects(owner_id)"
    ))

    # Installation cache table for user-scoped GitHub org lookups
    conn.execute(sa.text("""
        CREATE TABLE IF NOT EXISTS user_github_installations (
            id SERIAL PRIMARY KEY,
            user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
            org_login TEXT NOT NULL,
            installation_id TEXT NOT NULL,
            fetched_at TIMESTAMPTZ NOT NULL DEFAULT now(),
            UNIQUE(user_id, org_login)
        )
    """))
    conn.execute(sa.text(
        "CREATE INDEX IF NOT EXISTS idx_user_gh_installs_user_id"
        " ON user_github_installations(user_id)"
    ))

    # Data migration: assign existing projects to pyrabbit (if that user exists)
    conn.execute(sa.text("""
        UPDATE projects SET owner_id = (SELECT id FROM users WHERE login = 'pyrabbit')
        WHERE owner_id IS NULL
        AND EXISTS (SELECT 1 FROM users WHERE login = 'pyrabbit')
    """))


def downgrade() -> None:
    conn = op.get_bind()
    conn.execute(sa.text("DROP TABLE IF EXISTS user_github_installations"))
    conn.execute(sa.text("ALTER TABLE projects DROP COLUMN IF EXISTS owner_id"))
