"""lucro pretendido = soma de socios + reserva + expansao + outros (% do preco); desconto comercial passa para o cenario

Revision ID: c1e8a5b37d92
Revises: b9d4f27e6a13
Create Date: 2026-10-28 14:00:00.000000

Conversao preservando o total e as proporcoes: antes, socios/reserva/expansao eram fatias do resultado
(podiam somar menos de 100%) e `percentual_margem` era digitado. Agora cada elemento e % do preco e
`percentual_margem` e a soma dos quatro, entao o preco sugerido nao muda.
"""
from decimal import Decimal
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


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

_Q = Decimal("0.0001")


def upgrade() -> None:
    op.add_column('regra_de_margem', sa.Column('percentual_outros', sa.Numeric(6, 4), server_default='0', nullable=False))
    op.add_column('cenario_precificacao', sa.Column('percentual_desconto', sa.Numeric(6, 4), server_default='0', nullable=False))
    bind = op.get_bind()
    linhas = bind.execute(sa.text(
        "select id, cenario_id, percentual_margem, percentual_desconto, percentual_socios, percentual_reserva, percentual_expansao "
        "from regra_de_margem")).all()
    for r in linhas:
        margem = Decimal(r.percentual_margem)
        fatias = [Decimal(r.percentual_socios), Decimal(r.percentual_reserva), Decimal(r.percentual_expansao)]
        s = sum(fatias)
        if s > 1:  # mais de 100% do resultado: normaliza, nada fica em "outros"
            novos = [(margem * f / s).quantize(_Q) for f in fatias]
            outros = Decimal(0)
        else:
            novos = [(margem * f).quantize(_Q) for f in fatias]
            outros = (margem * (1 - s)).quantize(_Q)
        total = sum(novos) + outros
        bind.execute(sa.text(
            "update regra_de_margem set percentual_socios = :a, percentual_reserva = :b, percentual_expansao = :c, "
            "percentual_outros = :d, percentual_margem = :m where id = :id"),
            {"a": novos[0], "b": novos[1], "c": novos[2], "d": outros, "m": total, "id": r.id})
        bind.execute(sa.text("update cenario_precificacao set percentual_desconto = :d where id = :c"),
                     {"d": r.percentual_desconto, "c": r.cenario_id})
    op.drop_column('regra_de_margem', 'percentual_desconto')


def downgrade() -> None:
    op.add_column('regra_de_margem', sa.Column('percentual_desconto', sa.Numeric(6, 4), server_default='0', nullable=False))
    bind = op.get_bind()
    for r in bind.execute(sa.text(
            "select id, cenario_id, percentual_margem, percentual_socios, percentual_reserva, percentual_expansao from regra_de_margem")).all():
        margem = Decimal(r.percentual_margem)
        divisor = margem if margem else Decimal(1)
        bind.execute(sa.text(
            "update regra_de_margem set percentual_socios = :a, percentual_reserva = :b, percentual_expansao = :c, "
            "percentual_desconto = (select percentual_desconto from cenario_precificacao where id = :cen) where id = :id"),
            {"a": (Decimal(r.percentual_socios) / divisor).quantize(_Q), "b": (Decimal(r.percentual_reserva) / divisor).quantize(_Q),
             "c": (Decimal(r.percentual_expansao) / divisor).quantize(_Q), "cen": r.cenario_id, "id": r.id})
    op.drop_column('cenario_precificacao', 'percentual_desconto')
    op.drop_column('regra_de_margem', 'percentual_outros')
