"""Initial schema: runs, audit_events, processed_webhooks."""

from __future__ import annotations

from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

revision: str = "0001_initial"
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None

# Match packages.db.models: store WorkflowState as VARCHAR, not a PG ENUM type.
workflow_state = sa.Enum(
    "RECEIVED",
    "ANALYZING",
    "NEEDS_CLARIFICATION",
    "ARCHITECTING",
    "DESIGN_REVIEW",
    "IMPLEMENTING",
    "REVIEWING",
    "TESTING",
    "PR_CREATED",
    "HUMAN_REVIEW",
    "COMPLETED",
    "FAILED",
    name="workflow_state",
    native_enum=False,
)


def upgrade() -> None:
    op.create_table(
        "runs",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column("jira_key", sa.String(64), nullable=False),
        sa.Column("state", workflow_state, nullable=False),
        sa.Column("retry_count", sa.Integer(), nullable=False, server_default="0"),
        sa.Column("branch_name", sa.String(255), nullable=True),
        sa.Column("pr_url", sa.String(1024), nullable=True),
        sa.Column("error", sa.Text(), nullable=True),
        sa.Column("artifact_dir", sa.String(1024), nullable=True),
        sa.Column("artifacts", postgresql.JSONB(), nullable=False, server_default=sa.text("'{}'::jsonb")),
        sa.Column("idempotency_key", sa.String(255), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()")),
        sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("now()")),
    )
    op.create_index("ix_runs_jira_key", "runs", ["jira_key"])
    op.create_unique_constraint("uq_runs_idempotency_key", "runs", ["idempotency_key"])

    op.create_table(
        "audit_events",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column("run_id", postgresql.UUID(as_uuid=True), sa.ForeignKey("runs.id", ondelete="CASCADE")),
        sa.Column("event_type", sa.String(128), nullable=False),
        sa.Column("message", sa.Text(), nullable=False),
        sa.Column("payload", postgresql.JSONB(), nullable=False, server_default=sa.text("'{}'::jsonb")),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()")),
    )
    op.create_index("ix_audit_events_run_id", "audit_events", ["run_id"])

    op.create_table(
        "processed_webhooks",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column("delivery_id", sa.String(255), nullable=False),
        sa.Column("jira_key", sa.String(64), nullable=True),
        sa.Column("event_type", sa.String(128), nullable=False),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()")),
        sa.UniqueConstraint("delivery_id", name="uq_processed_webhooks_delivery"),
    )


def downgrade() -> None:
    op.drop_table("processed_webhooks")
    op.drop_index("ix_audit_events_run_id", table_name="audit_events")
    op.drop_table("audit_events")
    op.drop_constraint("uq_runs_idempotency_key", "runs", type_="unique")
    op.drop_index("ix_runs_jira_key", table_name="runs")
    op.drop_table("runs")
