"""Add energy type breakdown and phase support to FactMeasurement and FactUsage

Revision ID: bfd15efaf68d
Revises: e2205fd93662
Create Date: 2026-01-19 10:23:11.216889

"""

from typing import Sequence, Union

import sqlalchemy as sa

from alembic import op

# revision identifiers, used by Alembic.
revision: str = "bfd15efaf68d"
down_revision: Union[str, None] = "e2205fd93662"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column(
        "fact_measurement", sa.Column("active_forward", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_measurement", sa.Column("active_reverse", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_measurement", sa.Column("reactive_forward", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_measurement", sa.Column("reactive_reverse", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_measurement", sa.Column("phase_number", sa.SmallInteger(), nullable=True)
    )
    op.add_column(
        "fact_measurement", sa.Column("measurement_type", sa.Text(), nullable=True)
    )
    op.alter_column(
        "fact_measurement",
        "value",
        existing_type=sa.DOUBLE_PRECISION(precision=53),
        nullable=True,
    )
    op.drop_constraint("uq_measurement_device_ts", "fact_measurement", type_="unique")
    op.create_index(
        "idx_measurement_phase",
        "fact_measurement",
        ["device_id", "phase_number", "measured_ts"],
        unique=False,
    )
    op.create_index(
        "idx_measurement_type", "fact_measurement", ["measurement_type"], unique=False
    )
    op.create_unique_constraint(
        "uq_measurement_device_ts_phase",
        "fact_measurement",
        ["tenant", "device_id", "measured_ts", "phase_number"],
    )
    op.add_column(
        "fact_usage", sa.Column("active_forward_start", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_usage", sa.Column("active_forward_end", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_usage", sa.Column("active_forward_consumption", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_usage", sa.Column("active_reverse_start", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_usage", sa.Column("active_reverse_end", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_usage", sa.Column("active_reverse_production", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_usage", sa.Column("reactive_forward_start", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_usage", sa.Column("reactive_forward_end", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_usage",
        sa.Column("reactive_forward_consumption", sa.Float(), nullable=True),
    )
    op.add_column(
        "fact_usage", sa.Column("reactive_reverse_start", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_usage", sa.Column("reactive_reverse_end", sa.Float(), nullable=True)
    )
    op.add_column(
        "fact_usage",
        sa.Column("reactive_reverse_production", sa.Float(), nullable=True),
    )
    op.add_column("fact_usage", sa.Column("net_consumption", sa.Float(), nullable=True))
    op.add_column(
        "fact_usage", sa.Column("phase_number", sa.SmallInteger(), nullable=True)
    )
    op.add_column("fact_usage", sa.Column("usage_type", sa.Text(), nullable=True))
    op.alter_column(
        "fact_usage",
        "consumption",
        existing_type=sa.DOUBLE_PRECISION(precision=53),
        nullable=True,
    )
    op.drop_constraint("uq_usage_device_period", "fact_usage", type_="unique")
    op.create_index(
        "idx_usage_net",
        "fact_usage",
        ["tenant", "start_ts"],
        unique=False,
        postgresql_where=sa.text("net_consumption IS NOT NULL"),
    )
    op.create_index(
        "idx_usage_phase",
        "fact_usage",
        ["device_id", "phase_number", "period_type", "start_ts"],
        unique=False,
    )
    op.create_unique_constraint(
        "uq_usage_device_period_phase",
        "fact_usage",
        ["tenant", "device_id", "period_type", "start_ts", "phase_number"],
    )
    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint("uq_usage_device_period_phase", "fact_usage", type_="unique")
    op.drop_index("idx_usage_phase", table_name="fact_usage")
    op.drop_index(
        "idx_usage_net",
        table_name="fact_usage",
        postgresql_where=sa.text("net_consumption IS NOT NULL"),
    )
    op.create_unique_constraint(
        "uq_usage_device_period",
        "fact_usage",
        ["tenant", "device_id", "period_type", "start_ts"],
    )
    op.alter_column(
        "fact_usage",
        "consumption",
        existing_type=sa.DOUBLE_PRECISION(precision=53),
        nullable=False,
    )
    op.drop_column("fact_usage", "usage_type")
    op.drop_column("fact_usage", "phase_number")
    op.drop_column("fact_usage", "net_consumption")
    op.drop_column("fact_usage", "reactive_reverse_production")
    op.drop_column("fact_usage", "reactive_reverse_end")
    op.drop_column("fact_usage", "reactive_reverse_start")
    op.drop_column("fact_usage", "reactive_forward_consumption")
    op.drop_column("fact_usage", "reactive_forward_end")
    op.drop_column("fact_usage", "reactive_forward_start")
    op.drop_column("fact_usage", "active_reverse_production")
    op.drop_column("fact_usage", "active_reverse_end")
    op.drop_column("fact_usage", "active_reverse_start")
    op.drop_column("fact_usage", "active_forward_consumption")
    op.drop_column("fact_usage", "active_forward_end")
    op.drop_column("fact_usage", "active_forward_start")
    op.drop_constraint(
        "uq_measurement_device_ts_phase", "fact_measurement", type_="unique"
    )
    op.drop_index("idx_measurement_type", table_name="fact_measurement")
    op.drop_index("idx_measurement_phase", table_name="fact_measurement")
    op.create_unique_constraint(
        "uq_measurement_device_ts",
        "fact_measurement",
        ["tenant", "device_id", "measured_ts"],
    )
    op.alter_column(
        "fact_measurement",
        "value",
        existing_type=sa.DOUBLE_PRECISION(precision=53),
        nullable=False,
    )
    op.drop_column("fact_measurement", "measurement_type")
    op.drop_column("fact_measurement", "phase_number")
    op.drop_column("fact_measurement", "reactive_reverse")
    op.drop_column("fact_measurement", "reactive_forward")
    op.drop_column("fact_measurement", "active_reverse")
    op.drop_column("fact_measurement", "active_forward")
    # ### end Alembic commands ###
