"""Expediente (crm.cases) + case_id en el ciclo comercial

Revision ID: d4e5f6a7b8c9
Revises: f0a1b2c3d4e5
Create Date: 2026-08-07 02:00:00.000000

Crea crm.cases (expediente, hilo maestro con folio EXP...) y agrega case_id a
crm.opportunities/service_requests/quotes, ops.shipments y fin.invoices.
"""
from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op

revision: str = "d4e5f6a7b8c9"
down_revision: Union[str, None] = "f0a1b2c3d4e5"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None

# (schema, tabla) donde se agrega case_id
_CASE_FK_TABLES = [
    ("crm", "opportunities"),
    ("crm", "service_requests"),
    ("crm", "quotes"),
    ("ops", "shipments"),
    ("fin", "invoices"),
]


def upgrade() -> None:
    op.create_table(
        "cases",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("reference", sa.String(length=40), nullable=True),
        sa.Column("account_id", sa.Integer(), nullable=True),
        sa.Column("title", sa.String(length=255), nullable=True),
        sa.Column("stage", sa.String(length=20), nullable=False, server_default=sa.text("'oportunidad'")),
        sa.Column("status", sa.String(length=20), nullable=False, server_default=sa.text("'abierto'")),
        sa.Column("created_by", sa.String(length=64), nullable=True),
        sa.Column("updated_by", sa.String(length=64), nullable=True),
        sa.Column("tenant_id", sa.Integer(), nullable=False),
        sa.Column("company_id", sa.Integer(), nullable=False),
        sa.Column("created_at", sa.DateTime(), nullable=False, server_default=sa.text("now()")),
        sa.Column("updated_at", sa.DateTime(), nullable=False, server_default=sa.text("now()")),
        sa.Column("deleted_at", sa.DateTime(), nullable=True),
        sa.PrimaryKeyConstraint("id"),
        sa.ForeignKeyConstraint(["tenant_id"], ["core.tenants.id"]),
        sa.ForeignKeyConstraint(["account_id"], ["crm.accounts.id"]),
        schema="crm",
    )
    op.create_index("ix_crm_cases_id", "cases", ["id"], schema="crm")
    op.create_index("ix_crm_cases_reference", "cases", ["reference"], schema="crm")
    op.create_index("ix_crm_cases_tenant_id", "cases", ["tenant_id"], schema="crm")
    op.create_index("ix_crm_cases_company_id", "cases", ["company_id"], schema="crm")
    op.create_index("ix_crm_cases_account_id", "cases", ["account_id"], schema="crm")
    op.create_index("ix_crm_cases_status", "cases", ["status"], schema="crm")

    for schema, table in _CASE_FK_TABLES:
        op.add_column(table, sa.Column("case_id", sa.Integer(), nullable=True), schema=schema)
        op.create_index(f"ix_{schema}_{table}_case_id", table, ["case_id"], schema=schema)
        op.create_foreign_key(
            f"fk_{schema}_{table}_case_id", table, "cases",
            ["case_id"], ["id"], source_schema=schema, referent_schema="crm",
        )


def downgrade() -> None:
    for schema, table in _CASE_FK_TABLES:
        op.drop_constraint(f"fk_{schema}_{table}_case_id", table, schema=schema, type_="foreignkey")
        op.drop_index(f"ix_{schema}_{table}_case_id", table_name=table, schema=schema)
        op.drop_column(table, "case_id", schema=schema)

    for idx in ("status", "account_id", "company_id", "tenant_id", "reference", "id"):
        op.drop_index(f"ix_crm_cases_{idx}", table_name="cases", schema="crm")
    op.drop_table("cases", schema="crm")
