"""Fundir os dois nós da mesma pessoa.

O bloco de quotas de muitos actos está no formato antigo em prosa e **não traz
NIF nenhum**, enquanto a secção dos órgãos sociais do mesmo acto dá o NIF de cada
membro. Resultado: a mesma pessoa fica com dois nós.

Na GARCIA,GARCIA & CA S.A. são quatro dos cinco sócios: a Teresa Maria da Costa
Garcia Lima detém 235.000 € num nó sem NIF que não leva a lado nenhum, e é vogal
noutro nó — com NIF 183457390 — que está ligado ao resto do grafo. A cadeia de
propriedade parte-se exactamente onde interessa.

A tabela `registry_identity_links` já existia desde a Fase 8, com 531 candidatos
gerados todas as noites, **zero confirmados e zero rejeitados**: faltava a
interface para decidir e faltava alguém usar a decisão. Esta migration dá o sítio
onde a decisão fica: `merged_into` no nó absorvido.

Nada se apaga. O nó sem NIF continua a existir com o nome que o acto publicou —
é um facto da fonte — e as arestas dele passam a apontar para a identidade
confirmada. Desfazer é limpar o `merged_into` e reapontar de volta.
"""
from alembic import op

revision = "0029"
down_revision = "0028"
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.execute(
        """
        ALTER TABLE registry_entities
          ADD COLUMN merged_into UUID REFERENCES registry_entities(id) ON DELETE SET NULL
        """
    )
    # Um nó absorvido não pode absorver outro: a cadeia tem um degrau só, senão
    # resolver uma identidade passava a ser seguir uma lista ligada.
    op.execute(
        """
        ALTER TABLE registry_entities
          ADD CONSTRAINT registry_entities_merge_self CHECK (merged_into <> id)
        """
    )
    op.execute(
        "CREATE INDEX ix_rentities_merged ON registry_entities(merged_into)"
        " WHERE merged_into IS NOT NULL"
    )
    # `confirmed_by` nulo num link confirmado quer dizer **automático**: nome
    # exacto e a mesma empresa nas duas pontas. É a única evidência que dispensa
    # uma pessoa, e mesmo essa fica registada para se poder auditar.
    op.execute(
        "COMMENT ON COLUMN registry_identity_links.confirmed_by IS"
        " 'nulo com confirmed_at preenchido = fusão automática (nome+empresa)'"
    )


def downgrade() -> None:
    op.execute("DROP INDEX IF EXISTS ix_rentities_merged")
    op.execute(
        "ALTER TABLE registry_entities DROP CONSTRAINT IF EXISTS registry_entities_merge_self"
    )
    op.execute("ALTER TABLE registry_entities DROP COLUMN IF EXISTS merged_into")
