"""backfill_default_tree_author_id_to_service_account

Revision ID: 1490781700bc
Revises: 4f4137ce79e5
Create Date: 2026-02-25 21:26:00.000000

Backfill author_id on is_default trees to the ResolutionFlow service account
(noreply@resolutionflow.com). The service account is created here if it does
not yet exist (idempotent), so this migration is safe to run before or after
the app starts.
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
import uuid


# revision identifiers, used by Alembic.
revision: str = '1490781700bc'
down_revision: Union[str, None] = '4f4137ce79e5'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None

SERVICE_ACCOUNT_EMAIL = "noreply@resolutionflow.com"
SERVICE_ACCOUNT_NAME = "ResolutionFlow"
SYSTEM_ACCOUNT_NAME = "ResolutionFlow System"
SYSTEM_ACCOUNT_DISPLAY_CODE = "RF-SYS-1"


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

    # Check if service user already exists
    row = conn.execute(
        sa.text("SELECT id, account_id FROM users WHERE email = :email"),
        {"email": SERVICE_ACCOUNT_EMAIL},
    ).fetchone()

    if row is not None:
        service_id = str(row[0])
    else:
        # Ensure a system account exists for the service user
        acct_row = conn.execute(
            sa.text("SELECT id FROM accounts WHERE display_code = :code"),
            {"code": SYSTEM_ACCOUNT_DISPLAY_CODE},
        ).fetchone()

        if acct_row is None:
            account_id = str(uuid.uuid4())
            conn.execute(
                sa.text("""
                    INSERT INTO accounts (id, name, display_code, created_at, updated_at)
                    VALUES (:id, :name, :code, NOW(), NOW())
                """),
                {"id": account_id, "name": SYSTEM_ACCOUNT_NAME, "code": SYSTEM_ACCOUNT_DISPLAY_CODE},
            )
        else:
            account_id = str(acct_row[0])

        service_id = str(uuid.uuid4())
        conn.execute(
            sa.text("""
                INSERT INTO users (
                    id, email, name, password_hash, role,
                    is_super_admin, is_team_admin, is_active,
                    is_service_account, must_change_password,
                    account_id, account_role, created_at
                ) VALUES (
                    :id, :email, :name, :password_hash, 'engineer',
                    false, false, true,
                    true, false,
                    :account_id, 'engineer', NOW()
                )
            """),
            {
                "id": service_id,
                "email": SERVICE_ACCOUNT_EMAIL,
                "name": SERVICE_ACCOUNT_NAME,
                "password_hash": "!service-account-no-login",
                "account_id": account_id,
            },
        )

    # Backfill is_default trees that have no author
    result = conn.execute(
        sa.text("""
            UPDATE trees
            SET author_id = :service_id
            WHERE author_id IS NULL AND is_default = true
        """),
        {"service_id": service_id},
    )
    print(f"[backfill] Set author_id to service account on {result.rowcount} default trees")


def downgrade() -> None:
    conn = op.get_bind()
    row = conn.execute(
        sa.text("SELECT id FROM users WHERE email = :email"),
        {"email": SERVICE_ACCOUNT_EMAIL},
    ).fetchone()
    if row is None:
        return
    service_id = str(row[0])
    conn.execute(
        sa.text("""
            UPDATE trees
            SET author_id = NULL
            WHERE author_id = :service_id AND is_default = true
        """),
        {"service_id": service_id},
    )
