"""crm rates: tarifarios (rate_sheets/lanes/breaks/charges)

Revision ID: f8a9b0c1d2e3
Revises: e7f8a9b0c1d2
Create Date: 2026-07-27 00:00:00.000000

Módulo Tarifario: base de costos para Cotizaciones (import por Excel + motor de costeo).
"""
from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op

revision: str = "f8a9b0c1d2e3"
down_revision: Union[str, None] = "e7f8a9b0c1d2"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None

SCHEMA = "crm"


def _scoped() -> list[sa.Column]:
    return [
        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),
    ]


def _idx(table: str) -> None:
    op.create_index(f"ix_{SCHEMA}_{table}_id", table, ["id"], schema=SCHEMA)
    op.create_index(f"ix_{SCHEMA}_{table}_tenant_id", table, ["tenant_id"], schema=SCHEMA)
    op.create_index(f"ix_{SCHEMA}_{table}_company_id", table, ["company_id"], schema=SCHEMA)


def upgrade() -> None:
    # ----- rate_sheets -----
    op.create_table(
        "rate_sheets",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("supplier_id", sa.Integer(), nullable=True),
        sa.Column("mode", sa.String(length=20), nullable=False),
        sa.Column("name", sa.String(length=255), nullable=False),
        sa.Column("currency", sa.String(length=3), nullable=True, server_default=sa.text("'USD'")),
        sa.Column("valid_from", sa.Date(), nullable=True),
        sa.Column("valid_to", sa.Date(), nullable=True),
        sa.Column("default_origin", sa.String(length=20), nullable=True),
        sa.Column("status", sa.String(length=20), nullable=False, server_default=sa.text("'borrador'")),
        sa.Column("source_file", sa.String(length=512), nullable=True),
        sa.Column("source_url", sa.String(length=1024), nullable=True),
        sa.Column("notes", sa.Text(), nullable=True),
        sa.Column("created_by", sa.String(length=64), nullable=True),
        sa.Column("updated_by", sa.String(length=64), nullable=True),
        *_scoped(),
        sa.PrimaryKeyConstraint("id"),
        sa.ForeignKeyConstraint(["tenant_id"], ["core.tenants.id"]),
        sa.ForeignKeyConstraint(["supplier_id"], [f"{SCHEMA}.suppliers.id"]),
        schema=SCHEMA,
    )
    _idx("rate_sheets")
    op.create_index("ix_crm_rate_sheets_mode", "rate_sheets", ["mode"], schema=SCHEMA)
    op.create_index("ix_crm_rate_sheets_supplier_id", "rate_sheets", ["supplier_id"], schema=SCHEMA)

    # ----- rate_lanes -----
    op.create_table(
        "rate_lanes",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("rate_sheet_id", sa.Integer(), nullable=False),
        sa.Column("origin", sa.String(length=20), nullable=True),
        sa.Column("destination", sa.String(length=20), nullable=True),
        sa.Column("region", sa.String(length=60), nullable=True),
        sa.Column("equipment_type", sa.String(length=20), nullable=True),
        sa.Column("rate_unit", sa.String(length=20), nullable=True),
        sa.Column("min_charge", sa.Numeric(precision=14, scale=4), nullable=True),
        sa.Column("flat_rate", sa.Numeric(precision=14, scale=4), nullable=True),
        sa.Column("transit_days", sa.Integer(), nullable=True),
        sa.Column("notes", sa.Text(), nullable=True),
        *_scoped(),
        sa.PrimaryKeyConstraint("id"),
        sa.ForeignKeyConstraint(["tenant_id"], ["core.tenants.id"]),
        sa.ForeignKeyConstraint(["rate_sheet_id"], [f"{SCHEMA}.rate_sheets.id"]),
        schema=SCHEMA,
    )
    _idx("rate_lanes")
    op.create_index("ix_crm_rate_lanes_rate_sheet_id", "rate_lanes", ["rate_sheet_id"], schema=SCHEMA)
    op.create_index("ix_crm_rate_lanes_origin", "rate_lanes", ["origin"], schema=SCHEMA)
    op.create_index("ix_crm_rate_lanes_destination", "rate_lanes", ["destination"], schema=SCHEMA)

    # ----- rate_breaks -----
    op.create_table(
        "rate_breaks",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("rate_lane_id", sa.Integer(), nullable=False),
        sa.Column("from_qty", sa.Numeric(precision=12, scale=3), nullable=False, server_default=sa.text("0")),
        sa.Column("rate", sa.Numeric(precision=14, scale=4), nullable=False, server_default=sa.text("0")),
        *_scoped(),
        sa.PrimaryKeyConstraint("id"),
        sa.ForeignKeyConstraint(["tenant_id"], ["core.tenants.id"]),
        sa.ForeignKeyConstraint(["rate_lane_id"], [f"{SCHEMA}.rate_lanes.id"]),
        schema=SCHEMA,
    )
    _idx("rate_breaks")
    op.create_index("ix_crm_rate_breaks_rate_lane_id", "rate_breaks", ["rate_lane_id"], schema=SCHEMA)

    # ----- rate_charges -----
    op.create_table(
        "rate_charges",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("rate_sheet_id", sa.Integer(), nullable=True),
        sa.Column("rate_lane_id", sa.Integer(), nullable=True),
        sa.Column("concept", sa.String(length=60), nullable=False),
        sa.Column("charge_type", sa.String(length=20), nullable=False, server_default=sa.text("'fijo'")),
        sa.Column("value", sa.Numeric(precision=14, scale=4), nullable=True),
        sa.Column("condition", sa.Text(), nullable=True),
        *_scoped(),
        sa.PrimaryKeyConstraint("id"),
        sa.ForeignKeyConstraint(["tenant_id"], ["core.tenants.id"]),
        sa.ForeignKeyConstraint(["rate_sheet_id"], [f"{SCHEMA}.rate_sheets.id"]),
        sa.ForeignKeyConstraint(["rate_lane_id"], [f"{SCHEMA}.rate_lanes.id"]),
        schema=SCHEMA,
    )
    _idx("rate_charges")


def downgrade() -> None:
    op.drop_table("rate_charges", schema=SCHEMA)
    op.drop_table("rate_breaks", schema=SCHEMA)
    op.drop_table("rate_lanes", schema=SCHEMA)
    op.drop_table("rate_sheets", schema=SCHEMA)
