"""Centro de Resultados: descrição, "Produção a alocar", despesas adicionais por Centro; sai o cadastro de Cliente

Revision ID: f5b7d9e1a3c4
Revises: e4a6b8c0d2f3
Create Date: 2026-11-04 10:00:00.000000

`cenario_precificacao` ganha `descricao` e `a_alocar` (e nasce o Centro "Produção a alocar", código A_ALOCAR); `despesa.cenario_id` (nulo = do
Planejamento; preenchido = adicional do Centro). As tabelas `projecao_volume_cliente`, `investimento_cliente` e `cliente` saem (o investimento de
cliente passa a ser uma despesa adicional do Centro). 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 = 'f5b7d9e1a3c4'
down_revision: Union[str, None] = 'e4a6b8c0d2f3'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


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.add_column('cenario_precificacao', sa.Column('descricao', sa.String(500), nullable=True))
    op.add_column('cenario_precificacao', sa.Column('a_alocar', sa.Boolean(), nullable=False, server_default=sa.false()))
    op.add_column('despesa', sa.Column('cenario_id', sa.Integer(), nullable=True))
    op.create_foreign_key('despesa_cenario_id_fkey', 'despesa', 'cenario_precificacao', ['cenario_id'], ['id'])
    liga = op.get_bind()
    existe = liga.execute(sa.text("select 1 from cenario_precificacao where codigo = 'A_ALOCAR'")).first()
    if existe is None:
        liga.execute(sa.text(
            "insert into cenario_precificacao (codigo, nome, descricao, percentual_desconto, a_alocar) "
            "values ('A_ALOCAR', 'Produção a alocar', 'Produção ainda não alocada a nenhum Centro de Resultados (calculada)', 0, :v)"
        ), {'v': True})
    op.drop_table('projecao_volume_cliente')
    op.drop_table('investimento_cliente')
    op.drop_table('cliente')


def downgrade() -> None:
    if _no_schema_comum():
        return
    op.create_table(
        'cliente',
        sa.Column('id', sa.Integer(), primary_key=True),
        sa.Column('codigo', sa.String(20), nullable=False, unique=True),
        sa.Column('nome', sa.String(200), nullable=False),
        sa.Column('cnpj', sa.String(20), nullable=True),
        sa.Column('cenario_id', sa.Integer(), sa.ForeignKey('cenario_precificacao.id'), nullable=True),
    )
    op.create_table(
        'investimento_cliente',
        sa.Column('id', sa.Integer(), primary_key=True),
        sa.Column('cliente_id', sa.Integer(), sa.ForeignKey('cliente.id'), nullable=False, unique=True),
        sa.Column('valor_entrada', sa.Numeric(14, 6), nullable=False),
        sa.Column('valor_manutencao_anual', sa.Numeric(14, 6), nullable=False),
        sa.Column('prazo_meses', sa.Integer(), nullable=False, server_default='12'),
    )
    op.create_table(
        'projecao_volume_cliente',
        sa.Column('id', sa.Integer(), primary_key=True),
        sa.Column('cliente_id', sa.Integer(), sa.ForeignKey('cliente.id'), nullable=False, unique=True),
        sa.Column('volume_mensal_estimado', sa.Numeric(14, 6), nullable=False),
    )
    liga = op.get_bind()
    liga.execute(sa.text("delete from despesa where cenario_id is not null"))
    op.drop_constraint('despesa_cenario_id_fkey', 'despesa', type_='foreignkey')
    op.drop_column('despesa', 'cenario_id')
    liga.execute(sa.text("delete from volume_projetado where cenario_id in (select id from cenario_precificacao where a_alocar)"))
    liga.execute(sa.text("delete from cenario_precificacao where a_alocar"))
    op.drop_column('cenario_precificacao', 'a_alocar')
    op.drop_column('cenario_precificacao', 'descricao')
