"""classificação de créditos (ICMS | CBS | IR/CSLL) e configuração de alíquotas

Revision ID: d6f8a0b2c4e5
Revises: c5e7a9b1d3f4
Create Date: 2026-10-30 23:00:00.000000

Cria `classificacao_credito` (classes de crédito por item), `aliquota_imposto` (alíquota padrão por vigência), `icms_destino` (UFs de
destino e alíquota do ICMS da venda, já com as 27 UFs), `cenario_destino_icms` (mix de destinos por Centro de Resultado) e
`icms_desenvolve` (benefício Desenvolve-BA). Só roda nos schemas de Planejamento (ver f1a9c3d7e284).
"""
from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision: str = 'd6f8a0b2c4e5'
down_revision: Union[str, None] = 'c5e7a9b1d3f4'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None

# UF, nome, faixa. Interna da Bahia e interestaduais (7% Sul/Sudeste exceto ES; 12% as demais) — a alíquota interna é a modal da Bahia
# (valor de partida, editável na tela de Impostos).
UFS = [
    ('BA', 'Bahia', 'BA'),
    ('SP', 'São Paulo', 'SUL_SUDESTE'), ('RJ', 'Rio de Janeiro', 'SUL_SUDESTE'), ('MG', 'Minas Gerais', 'SUL_SUDESTE'),
    ('PR', 'Paraná', 'SUL_SUDESTE'), ('SC', 'Santa Catarina', 'SUL_SUDESTE'), ('RS', 'Rio Grande do Sul', 'SUL_SUDESTE'),
    ('ES', 'Espírito Santo', 'NORTE_NE_CO_ES'),
    ('AL', 'Alagoas', 'NORTE_NE_CO_ES'), ('CE', 'Ceará', 'NORTE_NE_CO_ES'), ('MA', 'Maranhão', 'NORTE_NE_CO_ES'),
    ('PB', 'Paraíba', 'NORTE_NE_CO_ES'), ('PE', 'Pernambuco', 'NORTE_NE_CO_ES'), ('PI', 'Piauí', 'NORTE_NE_CO_ES'),
    ('RN', 'Rio Grande do Norte', 'NORTE_NE_CO_ES'), ('SE', 'Sergipe', 'NORTE_NE_CO_ES'),
    ('AC', 'Acre', 'NORTE_NE_CO_ES'), ('AP', 'Amapá', 'NORTE_NE_CO_ES'), ('AM', 'Amazonas', 'NORTE_NE_CO_ES'),
    ('PA', 'Pará', 'NORTE_NE_CO_ES'), ('RO', 'Rondônia', 'NORTE_NE_CO_ES'), ('RR', 'Roraima', 'NORTE_NE_CO_ES'),
    ('TO', 'Tocantins', 'NORTE_NE_CO_ES'),
    ('DF', 'Distrito Federal', 'NORTE_NE_CO_ES'), ('GO', 'Goiás', 'NORTE_NE_CO_ES'), ('MT', 'Mato Grosso', 'NORTE_NE_CO_ES'),
    ('MS', 'Mato Grosso do Sul', 'NORTE_NE_CO_ES'),
]
ALIQUOTA_DA_FAIXA = {'BA': '0.205', 'SUL_SUDESTE': '0.07', 'NORTE_NE_CO_ES': '0.12'}


def _no_schema_comum() -> bool:
    contexto = op.get_context()
    return contexto.dialect.name == 'postgresql' and contexto.version_table_schema is None


def upgrade() -> None:
    if _no_schema_comum():
        return
    op.create_table(
        'classificacao_credito',
        sa.Column('id', sa.Integer(), primary_key=True),
        sa.Column('origem', sa.String(30), nullable=False),
        sa.Column('origem_id', sa.Integer(), nullable=False),
        sa.Column('classe', sa.String(10), nullable=False),
        sa.Column('aliquota_pct', sa.Numeric(8, 6), nullable=True),
        sa.UniqueConstraint('origem', 'origem_id', 'classe', name='uq_classificacao_credito'),
        sa.CheckConstraint("classe in ('icms', 'cbs', 'ir_csll')", name='ck_classificacao_credito_classe'),
        sa.CheckConstraint(
            "origem in ('insumo', 'ambiente_gasto', 'maquina_gasto', 'funcionario_gasto', 'despesa', 'produto_revenda')",
            name='ck_classificacao_credito_origem',
        ),
    )
    op.create_table(
        'aliquota_imposto',
        sa.Column('id', sa.Integer(), primary_key=True),
        sa.Column('classe', sa.String(15), nullable=False),
        sa.Column('vigencia', sa.Date(), nullable=False),
        sa.Column('aliquota_pct', sa.Numeric(8, 6), nullable=False),
        sa.Column('nota', sa.String(300), nullable=True),
        sa.UniqueConstraint('classe', 'vigencia', name='uq_aliquota_imposto'),
        sa.CheckConstraint("classe in ('cbs', 'ir_csll', 'icms_credito')", name='ck_aliquota_imposto_classe'),
    )
    destino = op.create_table(
        'icms_destino',
        sa.Column('id', sa.Integer(), primary_key=True),
        sa.Column('uf', sa.String(2), nullable=False, unique=True),
        sa.Column('nome', sa.String(40), nullable=False),
        sa.Column('faixa', sa.String(15), nullable=False),
        sa.Column('aliquota_pct', sa.Numeric(8, 6), nullable=False),
        sa.Column('reducao_base_pct', sa.Numeric(8, 6), nullable=False),
        sa.Column('frete_adicional_pct', sa.Numeric(8, 6), nullable=False),
        sa.CheckConstraint("faixa in ('BA', 'SUL_SUDESTE', 'NORTE_NE_CO_ES')", name='ck_icms_destino_faixa'),
    )
    op.bulk_insert(destino, [
        {'uf': uf, 'nome': nome, 'faixa': faixa, 'aliquota_pct': ALIQUOTA_DA_FAIXA[faixa], 'reducao_base_pct': 0, 'frete_adicional_pct': 0}
        for uf, nome, faixa in UFS
    ])
    op.create_table(
        'cenario_destino_icms',
        sa.Column('id', sa.Integer(), primary_key=True),
        sa.Column('cenario_id', sa.Integer(), sa.ForeignKey('cenario_precificacao.id'), nullable=False),
        sa.Column('uf', sa.String(2), nullable=False),
        sa.Column('percentual', sa.Numeric(8, 6), nullable=False),
        sa.UniqueConstraint('cenario_id', 'uf', name='uq_cenario_destino_icms'),
    )
    op.create_table(
        'icms_desenvolve',
        sa.Column('id', sa.Integer(), primary_key=True),
        sa.Column('ativo', sa.Boolean(), nullable=False, server_default=sa.false()),
        sa.Column('vigencia_inicio', sa.Date(), nullable=True),
        sa.Column('vigencia_fim', sa.Date(), nullable=True),
        sa.Column('pct_dilatado', sa.Numeric(8, 6), nullable=False),
        sa.Column('piso_mensal', sa.Numeric(14, 6), nullable=False),
        sa.Column('prazo_meses', sa.Integer(), nullable=False),
        sa.Column('desconto_liquidacao_pct', sa.Numeric(8, 6), nullable=False),
        sa.Column('taxa_atualizacao_aa', sa.Numeric(8, 6), nullable=False),
        sa.Column('taxa_desconto_aa', sa.Numeric(8, 6), nullable=False),
        sa.Column('observacao', sa.String(500), nullable=True),
    )


def downgrade() -> None:
    if _no_schema_comum():
        return
    for tabela in ('icms_desenvolve', 'cenario_destino_icms', 'icms_destino', 'aliquota_imposto', 'classificacao_credito'):
        op.drop_table(tabela)
