"""Add inventory_transactions table

Revision ID: o3c4d5e6f7a8
Revises: n2c3d4e5f6a7
Create Date: 2026-01-01

Adds an audit trail for inventory movements:
- Track all stock changes (reserve, fulfill, release, adjust, set)
- Link transactions to orders for traceability
- Store quantity snapshots for historical analysis
"""

import sqlalchemy as sa

from alembic import op

# revision identifiers, used by Alembic.
revision = "o3c4d5e6f7a8"
down_revision = "n2c3d4e5f6a7"
branch_labels = None
depends_on = None


def upgrade() -> None:
    # Create transaction type enum
    transaction_type_enum = sa.Enum(
        "reserve",
        "fulfill",
        "release",
        "adjust",
        "set",
        "import",
        "return",
        name="transactiontype",
    )

    op.create_table(
        "inventory_transactions",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("vendor_id", sa.Integer(), nullable=False),
        sa.Column("product_id", sa.Integer(), nullable=False),
        sa.Column("inventory_id", sa.Integer(), nullable=True),
        sa.Column("transaction_type", transaction_type_enum, nullable=False),
        sa.Column("quantity_change", sa.Integer(), nullable=False),
        sa.Column("quantity_after", sa.Integer(), nullable=False),
        sa.Column("reserved_after", sa.Integer(), nullable=False, server_default="0"),
        sa.Column("location", sa.String(), nullable=True),
        sa.Column("warehouse", sa.String(), nullable=True),
        sa.Column("order_id", sa.Integer(), nullable=True),
        sa.Column("order_number", sa.String(), nullable=True),
        sa.Column("reason", sa.Text(), nullable=True),
        sa.Column("created_by", sa.String(), nullable=True),
        sa.Column(
            "created_at",
            sa.DateTime(timezone=True),
            nullable=False,
            server_default=sa.func.now(),
        ),
        sa.ForeignKeyConstraint(["vendor_id"], ["vendors.id"]),
        sa.ForeignKeyConstraint(["product_id"], ["products.id"]),
        sa.ForeignKeyConstraint(["inventory_id"], ["inventory.id"]),
        sa.ForeignKeyConstraint(["order_id"], ["orders.id"]),
        sa.PrimaryKeyConstraint("id"),
    )

    # Create indexes
    op.create_index(
        "ix_inventory_transactions_id",
        "inventory_transactions",
        ["id"],
    )
    op.create_index(
        "ix_inventory_transactions_vendor_id",
        "inventory_transactions",
        ["vendor_id"],
    )
    op.create_index(
        "ix_inventory_transactions_product_id",
        "inventory_transactions",
        ["product_id"],
    )
    op.create_index(
        "ix_inventory_transactions_inventory_id",
        "inventory_transactions",
        ["inventory_id"],
    )
    op.create_index(
        "ix_inventory_transactions_transaction_type",
        "inventory_transactions",
        ["transaction_type"],
    )
    op.create_index(
        "ix_inventory_transactions_order_id",
        "inventory_transactions",
        ["order_id"],
    )
    op.create_index(
        "ix_inventory_transactions_created_at",
        "inventory_transactions",
        ["created_at"],
    )
    op.create_index(
        "idx_inv_tx_vendor_product",
        "inventory_transactions",
        ["vendor_id", "product_id"],
    )
    op.create_index(
        "idx_inv_tx_vendor_created",
        "inventory_transactions",
        ["vendor_id", "created_at"],
    )
    op.create_index(
        "idx_inv_tx_type_created",
        "inventory_transactions",
        ["transaction_type", "created_at"],
    )


def downgrade() -> None:
    op.drop_index("idx_inv_tx_type_created", table_name="inventory_transactions")
    op.drop_index("idx_inv_tx_vendor_created", table_name="inventory_transactions")
    op.drop_index("idx_inv_tx_vendor_product", table_name="inventory_transactions")
    op.drop_index(
        "ix_inventory_transactions_created_at", table_name="inventory_transactions"
    )
    op.drop_index(
        "ix_inventory_transactions_order_id", table_name="inventory_transactions"
    )
    op.drop_index(
        "ix_inventory_transactions_transaction_type", table_name="inventory_transactions"
    )
    op.drop_index(
        "ix_inventory_transactions_inventory_id", table_name="inventory_transactions"
    )
    op.drop_index(
        "ix_inventory_transactions_product_id", table_name="inventory_transactions"
    )
    op.drop_index(
        "ix_inventory_transactions_vendor_id", table_name="inventory_transactions"
    )
    op.drop_index("ix_inventory_transactions_id", table_name="inventory_transactions")
    op.drop_table("inventory_transactions")

    # Drop enum
    sa.Enum(name="transactiontype").drop(op.get_bind(), checkfirst=True)
