"""Create correction_attempts table.

Adds the ``correction_attempts`` table for tracking decision correction
workflows (revert/append modes) as defined in the specification DDL.
Each row records one correction attempt against a plan's decision tree.

Revision ID: m8_001_correction_attempts
Revises: m4_003_plan_env_columns
Create Date: 2026-03-24 00:00:00

"""

from collections.abc import Sequence

import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision: str = "m8_001_correction_attempts"
down_revision: str | Sequence[str] | None = "m4_003_plan_env_columns"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
    """Create correction_attempts table with spec-aligned schema."""

    op.create_table(
        "correction_attempts",
        sa.Column("correction_attempt_id", sa.String(26), primary_key=True),
        sa.Column(
            "plan_id",
            sa.String(26),
            sa.ForeignKey("v3_plans.plan_id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column(
            "original_decision_id",
            sa.String(26),
            sa.ForeignKey("decisions.decision_id", ondelete="RESTRICT"),
            nullable=False,
        ),
        sa.Column(
            "new_decision_id",
            sa.String(26),
            sa.ForeignKey("decisions.decision_id", ondelete="RESTRICT"),
            nullable=True,
        ),
        sa.Column("mode", sa.String(20), nullable=False),
        sa.Column("guidance", sa.Text(), nullable=False),
        sa.Column("archived_artifacts_path", sa.Text(), nullable=True),
        sa.Column(
            "state",
            sa.String(20),
            nullable=False,
            server_default="pending",
        ),
        sa.Column(
            "created_at",
            sa.String(30),
            nullable=False,
            server_default=sa.text("(strftime('%Y-%m-%dT%H:%M:%f', 'now'))"),
        ),
        sa.Column("completed_at", sa.String(30), nullable=True),
        sa.CheckConstraint(
            "mode IN ('revert', 'append')",
            name="ck_correction_attempts_mode",
        ),
        sa.CheckConstraint(
            "state IN ('pending', 'executing', 'complete', 'failed')",
            name="ck_correction_attempts_state",
        ),
    )

    op.create_index(
        "idx_corrections_plan",
        "correction_attempts",
        ["plan_id"],
    )


def downgrade() -> None:
    """Drop correction_attempts table."""

    op.drop_index("idx_corrections_plan", table_name="correction_attempts")
    op.drop_table("correction_attempts")
