"""historico de versoes das entradas de custo + snapshot das entradas no custeio

Adiciona `atualizado_em` (mes a partir do qual a versao atual vale) nas tabelas com entradas versionadas,
a tabela `historico_versao` (versoes antigas) e `competencia`/`entradas` em `custeio_execucao`.

Revision ID: a7c3e91d5f20
Revises: bb22393499ec
Create Date: 2026-10-16 18:00:00.000000

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


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

# Tabelas com entrada versionada. As linhas que ja existem ficam com a sentinela 2000-01-01
# ("desde o inicio"): nao sabemos desde quando cada valor vale, entao ele vale para todo o passado.
TABELAS_VERSIONADAS = [
    'ambiente_gasto',
    'maquina_gasto',
    'funcionario_gasto',
    'insumo',
    'funcionario',
    'maquina',
    'ambiente',
    'produto',
    'roteiro_maquina',
    'roteiro_ambiente',
    'roteiro_mao_de_obra',
    'roteiro_insumo',
]


def upgrade() -> None:
    for tabela in TABELAS_VERSIONADAS:
        op.add_column(
            tabela,
            sa.Column('atualizado_em', sa.Date(), nullable=False, server_default='2000-01-01'),
        )

    # competencia do custeio: nullable -> backfill (mes de executado_em) -> NOT NULL
    op.add_column('custeio_execucao', sa.Column('competencia', sa.Date(), nullable=True))
    if op.get_bind().dialect.name == 'postgresql':
        op.execute("UPDATE custeio_execucao SET competencia = date_trunc('month', executado_em)::date")
    else:
        op.execute("UPDATE custeio_execucao SET competencia = date(executado_em, 'start of month')")
    op.alter_column('custeio_execucao', 'competencia', nullable=False)
    op.add_column('custeio_execucao', sa.Column('entradas', sa.JSON(), nullable=True))

    op.create_table(
        'historico_versao',
        sa.Column('id', sa.Integer(), nullable=False),
        sa.Column('entidade', sa.String(length=40), nullable=False),
        sa.Column('registro_id', sa.Integer(), nullable=False),
        sa.Column('atualizado_em', sa.Date(), nullable=False),
        sa.Column('substituido_em', sa.Date(), nullable=False),
        sa.Column('acao', sa.String(length=10), nullable=False),
        sa.Column('valores', sa.JSON(), nullable=False),
        sa.Column('registrado_em', sa.DateTime(), nullable=False),
        sa.CheckConstraint("acao in ('alterado', 'removido')", name='ck_historico_versao_acao'),
        sa.PrimaryKeyConstraint('id'),
    )
    op.create_index('ix_historico_versao_entidade_registro', 'historico_versao', ['entidade', 'registro_id'])


def downgrade() -> None:
    op.drop_index('ix_historico_versao_entidade_registro', table_name='historico_versao')
    op.drop_table('historico_versao')
    op.drop_column('custeio_execucao', 'entradas')
    op.drop_column('custeio_execucao', 'competencia')
    for tabela in reversed(TABELAS_VERSIONADAS):
        op.drop_column(tabela, 'atualizado_em')
