defmodule Microwaveprop.Repo.Migrations.AddMultiBandRoverPlanning do
  use Ecto.Migration

  def up do
    # Mission carries the SET of bands the operator wants to evaluate.
    # `band_mhz` stays as a denormalized "primary band" for any legacy
    # readers; new code reads `bands_mhz`.
    alter table(:rover_missions) do
      add :bands_mhz, {:array, :integer}, default: [], null: false
    end

    execute(
      "UPDATE rover_missions SET bands_mhz = ARRAY[band_mhz] WHERE coalesce(array_length(bands_mhz, 1), 0) = 0"
    )

    # Each computed path is now scoped to a specific band — the worker
    # uses this for its loss budget + propagation-score lookup.
    alter table(:rover_mission_paths) do
      add :band_mhz, :integer
    end

    execute("""
    UPDATE rover_mission_paths p
    SET band_mhz = m.band_mhz
    FROM rover_missions m
    WHERE p.mission_id = m.id AND p.band_mhz IS NULL
    """)

    alter table(:rover_mission_paths) do
      modify :band_mhz, :integer, null: false
    end

    drop_if_exists(
      unique_index(:rover_mission_paths, [:mission_id, :rover_location_id, :station_id],
        name: :rover_mission_paths_unique
      )
    )

    create unique_index(
             :rover_mission_paths,
             [:mission_id, :rover_location_id, :station_id, :band_mhz],
             name: :rover_mission_paths_unique
           )
  end

  def down do
    drop_if_exists(
      unique_index(
        :rover_mission_paths,
        [:mission_id, :rover_location_id, :station_id, :band_mhz],
        name: :rover_mission_paths_unique
      )
    )

    create unique_index(:rover_mission_paths, [:mission_id, :rover_location_id, :station_id],
             name: :rover_mission_paths_unique
           )

    alter table(:rover_mission_paths) do
      remove :band_mhz
    end

    alter table(:rover_missions) do
      remove :bands_mhz
    end
  end
end
