defmodule Towerops.Devices.Event do
  @moduledoc """
  Device event schema for tracking changes and incidents.
  """
  use Ecto.Schema

  import Ecto.Changeset

  @type severity :: :info | :warning | :critical

  @type event_type ::
          :interface_up
          | :interface_down
          | :interface_speed_change
          | :interface_mtu_change
          | :interface_mac_change
          | :interface_admin_status_change
          | :device_discovered
          | :device_rediscovered
          | :sensor_threshold_warning
          | :sensor_threshold_critical
          | :sensor_threshold_normal
          | :sensor_value_spike
          | :sensor_value_drop
          | :sensor_value_changed

  @primary_key {:id, :binary_id, autogenerate: true}
  @foreign_key_type :binary_id

  schema "device_events" do
    field :event_type, :string
    field :severity, :string
    field :message, :string
    field :metadata, :map, default: %{}
    field :occurred_at, :utc_datetime

    belongs_to :device, Towerops.Devices.Device

    timestamps(type: :utc_datetime, updated_at: false)
  end

  @doc false
  def changeset(event, attrs) do
    event
    |> cast(attrs, [:device_id, :event_type, :severity, :message, :metadata, :occurred_at])
    |> validate_required([:device_id, :event_type, :severity, :message, :occurred_at])
    |> validate_inclusion(:event_type, [
      "interface_up",
      "interface_down",
      "interface_speed_change",
      "interface_mtu_change",
      "interface_mac_change",
      "interface_admin_status_change",
      "device_discovered",
      "device_rediscovered",
      "sensor_threshold_warning",
      "sensor_threshold_critical",
      "sensor_threshold_normal",
      "sensor_value_spike",
      "sensor_value_drop",
      "sensor_value_changed"
    ])
    |> validate_inclusion(:severity, ["info", "warning", "critical"])
    |> foreign_key_constraint(:device_id)
  end
end
