defmodule Towerops.Preseem.DeviceBaseline do
  @moduledoc """
  Rolling 14-day baseline for individual Preseem access points.
  Computed nightly to detect deviations from normal behavior.
  """
  use Ecto.Schema

  import Ecto.Changeset

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

  @valid_periods ~w(busy offpeak all)
  @valid_metrics ~w(qoe_score capacity_score rf_score p95_latency avg_latency avg_jitter avg_loss avg_throughput subscriber_count airtime_utilization)

  schema "preseem_device_baselines" do
    field :metric_name, :string
    field :period, :string
    field :mean, :float
    field :stddev, :float
    field :p5, :float
    field :p95, :float
    field :sample_count, :integer
    field :computed_at, :utc_datetime

    belongs_to :preseem_access_point, Towerops.Preseem.AccessPoint
  end

  def changeset(baseline, attrs) do
    baseline
    |> cast(attrs, [
      :preseem_access_point_id,
      :metric_name,
      :period,
      :mean,
      :stddev,
      :p5,
      :p95,
      :sample_count,
      :computed_at
    ])
    |> validate_required([
      :preseem_access_point_id,
      :metric_name,
      :period,
      :mean,
      :sample_count,
      :computed_at
    ])
    |> validate_inclusion(:period, @valid_periods)
    |> validate_inclusion(:metric_name, @valid_metrics)
    |> unique_constraint([:preseem_access_point_id, :metric_name, :period],
      name: :preseem_device_baselines_ap_metric_period_idx
    )
    |> foreign_key_constraint(:preseem_access_point_id)
  end
end
