"""add_letzshop_integration_tables

Revision ID: 987b4ecfa503
Revises: 82ea1b4a3ccb
Create Date: 2025-12-13

This migration adds:
- vendor_letzshop_credentials: Per-vendor encrypted API key storage
- letzshop_orders: Track imported orders with external IDs
- letzshop_fulfillment_queue: Queue outbound operations with retry
- letzshop_sync_logs: Audit trail for sync operations
- Adds channel fields to orders table for multi-marketplace support
"""
from collections.abc import Sequence

import sqlalchemy as sa

from alembic import op

# revision identifiers, used by Alembic.
revision: str = "987b4ecfa503"
down_revision: str | None = "82ea1b4a3ccb"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
    # Add channel fields to orders table
    op.add_column("orders", sa.Column("channel", sa.String(length=50), nullable=True, server_default="direct"))
    op.add_column("orders", sa.Column("external_order_id", sa.String(length=100), nullable=True))
    op.add_column("orders", sa.Column("external_channel_data", sa.JSON(), nullable=True))
    op.create_index(op.f("ix_orders_channel"), "orders", ["channel"], unique=False)
    op.create_index(op.f("ix_orders_external_order_id"), "orders", ["external_order_id"], unique=False)

    # Create vendor_letzshop_credentials table
    op.create_table("vendor_letzshop_credentials",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("vendor_id", sa.Integer(), nullable=False),
        sa.Column("api_key_encrypted", sa.Text(), nullable=False),
        sa.Column("api_endpoint", sa.String(length=255), server_default="https://letzshop.lu/graphql", nullable=True),
        sa.Column("auto_sync_enabled", sa.Boolean(), server_default="0", nullable=True),
        sa.Column("sync_interval_minutes", sa.Integer(), server_default="15", nullable=True),
        sa.Column("last_sync_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("last_sync_status", sa.String(length=50), nullable=True),
        sa.Column("last_sync_error", sa.Text(), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False),
        sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False),
        sa.ForeignKeyConstraint(["vendor_id"], ["vendors.id"], ),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint("vendor_id")
    )
    op.create_index(op.f("ix_vendor_letzshop_credentials_id"), "vendor_letzshop_credentials", ["id"], unique=False)
    op.create_index(op.f("ix_vendor_letzshop_credentials_vendor_id"), "vendor_letzshop_credentials", ["vendor_id"], unique=True)

    # Create letzshop_orders table
    op.create_table("letzshop_orders",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("vendor_id", sa.Integer(), nullable=False),
        sa.Column("letzshop_order_id", sa.String(length=100), nullable=False),
        sa.Column("letzshop_shipment_id", sa.String(length=100), nullable=True),
        sa.Column("letzshop_order_number", sa.String(length=100), nullable=True),
        sa.Column("local_order_id", sa.Integer(), nullable=True),
        sa.Column("letzshop_state", sa.String(length=50), nullable=True),
        sa.Column("customer_email", sa.String(length=255), nullable=True),
        sa.Column("customer_name", sa.String(length=255), nullable=True),
        sa.Column("total_amount", sa.String(length=50), nullable=True),
        sa.Column("currency", sa.String(length=10), server_default="EUR", nullable=True),
        sa.Column("raw_order_data", sa.JSON(), nullable=True),
        sa.Column("inventory_units", sa.JSON(), nullable=True),
        sa.Column("sync_status", sa.String(length=50), server_default="pending", nullable=True),
        sa.Column("last_synced_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("sync_error", sa.Text(), nullable=True),
        sa.Column("confirmed_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("rejected_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("tracking_set_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("tracking_number", sa.String(length=100), nullable=True),
        sa.Column("tracking_carrier", sa.String(length=100), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False),
        sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False),
        sa.ForeignKeyConstraint(["local_order_id"], ["orders.id"], ),
        sa.ForeignKeyConstraint(["vendor_id"], ["vendors.id"], ),
        sa.PrimaryKeyConstraint("id")
    )
    op.create_index(op.f("ix_letzshop_orders_id"), "letzshop_orders", ["id"], unique=False)
    op.create_index(op.f("ix_letzshop_orders_letzshop_order_id"), "letzshop_orders", ["letzshop_order_id"], unique=False)
    op.create_index(op.f("ix_letzshop_orders_letzshop_shipment_id"), "letzshop_orders", ["letzshop_shipment_id"], unique=False)
    op.create_index(op.f("ix_letzshop_orders_vendor_id"), "letzshop_orders", ["vendor_id"], unique=False)
    op.create_index("idx_letzshop_order_vendor", "letzshop_orders", ["vendor_id", "letzshop_order_id"], unique=False)
    op.create_index("idx_letzshop_order_state", "letzshop_orders", ["vendor_id", "letzshop_state"], unique=False)
    op.create_index("idx_letzshop_order_sync", "letzshop_orders", ["vendor_id", "sync_status"], unique=False)

    # Create letzshop_fulfillment_queue table
    op.create_table("letzshop_fulfillment_queue",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("vendor_id", sa.Integer(), nullable=False),
        sa.Column("letzshop_order_id", sa.Integer(), nullable=False),
        sa.Column("operation", sa.String(length=50), nullable=False),
        sa.Column("payload", sa.JSON(), nullable=False),
        sa.Column("status", sa.String(length=50), server_default="pending", nullable=True),
        sa.Column("attempts", sa.Integer(), server_default="0", nullable=True),
        sa.Column("max_attempts", sa.Integer(), server_default="3", nullable=True),
        sa.Column("last_attempt_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("next_retry_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("error_message", sa.Text(), nullable=True),
        sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("response_data", sa.JSON(), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False),
        sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False),
        sa.ForeignKeyConstraint(["letzshop_order_id"], ["letzshop_orders.id"], ),
        sa.ForeignKeyConstraint(["vendor_id"], ["vendors.id"], ),
        sa.PrimaryKeyConstraint("id")
    )
    op.create_index(op.f("ix_letzshop_fulfillment_queue_id"), "letzshop_fulfillment_queue", ["id"], unique=False)
    op.create_index(op.f("ix_letzshop_fulfillment_queue_vendor_id"), "letzshop_fulfillment_queue", ["vendor_id"], unique=False)
    op.create_index("idx_fulfillment_queue_status", "letzshop_fulfillment_queue", ["status", "vendor_id"], unique=False)
    op.create_index("idx_fulfillment_queue_retry", "letzshop_fulfillment_queue", ["status", "next_retry_at"], unique=False)

    # Create letzshop_sync_logs table
    op.create_table("letzshop_sync_logs",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("vendor_id", sa.Integer(), nullable=False),
        sa.Column("operation_type", sa.String(length=50), nullable=False),
        sa.Column("direction", sa.String(length=10), nullable=False),
        sa.Column("status", sa.String(length=50), nullable=False),
        sa.Column("records_processed", sa.Integer(), server_default="0", nullable=True),
        sa.Column("records_succeeded", sa.Integer(), server_default="0", nullable=True),
        sa.Column("records_failed", sa.Integer(), server_default="0", nullable=True),
        sa.Column("error_details", sa.JSON(), nullable=True),
        sa.Column("started_at", sa.DateTime(timezone=True), nullable=False),
        sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("duration_seconds", sa.Integer(), nullable=True),
        sa.Column("triggered_by", sa.String(length=100), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False),
        sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False),
        sa.ForeignKeyConstraint(["vendor_id"], ["vendors.id"], ),
        sa.PrimaryKeyConstraint("id")
    )
    op.create_index(op.f("ix_letzshop_sync_logs_id"), "letzshop_sync_logs", ["id"], unique=False)
    op.create_index(op.f("ix_letzshop_sync_logs_vendor_id"), "letzshop_sync_logs", ["vendor_id"], unique=False)
    op.create_index("idx_sync_log_vendor_type", "letzshop_sync_logs", ["vendor_id", "operation_type"], unique=False)
    op.create_index("idx_sync_log_vendor_date", "letzshop_sync_logs", ["vendor_id", "started_at"], unique=False)


def downgrade() -> None:
    # Drop letzshop_sync_logs table
    op.drop_index("idx_sync_log_vendor_date", table_name="letzshop_sync_logs")
    op.drop_index("idx_sync_log_vendor_type", table_name="letzshop_sync_logs")
    op.drop_index(op.f("ix_letzshop_sync_logs_vendor_id"), table_name="letzshop_sync_logs")
    op.drop_index(op.f("ix_letzshop_sync_logs_id"), table_name="letzshop_sync_logs")
    op.drop_table("letzshop_sync_logs")

    # Drop letzshop_fulfillment_queue table
    op.drop_index("idx_fulfillment_queue_retry", table_name="letzshop_fulfillment_queue")
    op.drop_index("idx_fulfillment_queue_status", table_name="letzshop_fulfillment_queue")
    op.drop_index(op.f("ix_letzshop_fulfillment_queue_vendor_id"), table_name="letzshop_fulfillment_queue")
    op.drop_index(op.f("ix_letzshop_fulfillment_queue_id"), table_name="letzshop_fulfillment_queue")
    op.drop_table("letzshop_fulfillment_queue")

    # Drop letzshop_orders table
    op.drop_index("idx_letzshop_order_sync", table_name="letzshop_orders")
    op.drop_index("idx_letzshop_order_state", table_name="letzshop_orders")
    op.drop_index("idx_letzshop_order_vendor", table_name="letzshop_orders")
    op.drop_index(op.f("ix_letzshop_orders_vendor_id"), table_name="letzshop_orders")
    op.drop_index(op.f("ix_letzshop_orders_letzshop_shipment_id"), table_name="letzshop_orders")
    op.drop_index(op.f("ix_letzshop_orders_letzshop_order_id"), table_name="letzshop_orders")
    op.drop_index(op.f("ix_letzshop_orders_id"), table_name="letzshop_orders")
    op.drop_table("letzshop_orders")

    # Drop vendor_letzshop_credentials table
    op.drop_index(op.f("ix_vendor_letzshop_credentials_vendor_id"), table_name="vendor_letzshop_credentials")
    op.drop_index(op.f("ix_vendor_letzshop_credentials_id"), table_name="vendor_letzshop_credentials")
    op.drop_table("vendor_letzshop_credentials")

    # Drop channel fields from orders table
    op.drop_index(op.f("ix_orders_external_order_id"), table_name="orders")
    op.drop_index(op.f("ix_orders_channel"), table_name="orders")
    op.drop_column("orders", "external_channel_data")
    op.drop_column("orders", "external_order_id")
    op.drop_column("orders", "channel")
