"""decouple dsmr_reading from the telegram id

The DSMR Reader's own ``id`` field is auto-incrementing but is known to overflow
and require a manual reset to zero (a long-standing DSMR firmware quirk).  If we
keep a UNIQUE constraint on ``source_id`` (the telegram id) and use it for
idempotency, an overflow/reset would make legitimately-new telegrams collide with
old ids and be silently dropped as "duplicates" — data loss.

This migration removes that coupling:

- Drops the UNIQUE constraint on ``source_id`` (the column is kept as a plain,
  nullable reference value; it is no longer relied upon for uniqueness/dedup).
- Makes ``recorded_at`` (the telegram timestamp) UNIQUE instead — a single P1
  meter emits one telegram per timestamp, so this is a robust, telegram-id-
  independent idempotency key.  The table's own autoincrement ``id`` PK remains
  the stable internal identity.

Revision ID: 20260624_12_dsmr_decouple_telegram_id
Revises: 20260623_11_energy_tables
Create Date: 2026-06-24 00:00:00.000000
"""

from typing import Sequence, Union

from alembic import op


revision: str = "20260624_12_dsmr_decouple_telegram_id"
down_revision: Union[str, None] = "20260623_11_energy_tables"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    # SQLite cannot ALTER away a constraint in place, so recreate the table via
    # Alembic's batch mode.  The table is recreated and rows are copied; existing
    # data (if any) is preserved.  recorded_at must be unique for this to succeed
    # — a single meter never emits two telegrams at the exact same timestamp.
    with op.batch_alter_table("dsmr_reading", schema=None) as batch_op:
        # Old non-unique index on recorded_at is replaced by the unique constraint.
        batch_op.drop_index("ix_dsmr_reading_recorded_at")
        # Telegram id is no longer a uniqueness/idempotency key.
        batch_op.drop_constraint("uq_dsmr_reading_source_id", type_="unique")
        # Timestamp becomes the telegram-id-independent dedup key.
        batch_op.create_unique_constraint(
            "uq_dsmr_reading_recorded_at", ["recorded_at"]
        )


def downgrade() -> None:
    with op.batch_alter_table("dsmr_reading", schema=None) as batch_op:
        batch_op.drop_constraint("uq_dsmr_reading_recorded_at", type_="unique")
        batch_op.create_unique_constraint(
            "uq_dsmr_reading_source_id", ["source_id"]
        )
        batch_op.create_index(
            "ix_dsmr_reading_recorded_at", ["recorded_at"], unique=False
        )
