defmodule Tarakan.Billing.Subscription do
  @moduledoc """
  A paid plan subscription for one account, mirrored from Stripe.

  Rows are upserted from Stripe webhook events keyed by
  `stripe_subscription_id`; `status` follows Stripe's lifecycle collapsed to
  `active | past_due | canceled | incomplete` (see `Tarakan.Billing`).
  """

  use Ecto.Schema

  import Ecto.Changeset

  alias Tarakan.Accounts.Account

  @plans ~w(team enterprise)
  @statuses ~w(active past_due canceled incomplete)

  schema "subscriptions" do
    field :plan, :string
    field :status, :string, default: "incomplete"
    field :stripe_customer_id, :string
    field :stripe_subscription_id, :string
    field :current_period_end, :utc_datetime_usec

    belongs_to :account, Account

    timestamps(type: :utc_datetime_usec)
  end

  def plans, do: @plans
  def statuses, do: @statuses

  @doc false
  def changeset(subscription, attrs) do
    subscription
    |> cast(attrs, [
      :account_id,
      :plan,
      :status,
      :stripe_customer_id,
      :stripe_subscription_id,
      :current_period_end
    ])
    |> validate_required([:account_id, :plan, :status])
    |> validate_inclusion(:plan, @plans)
    |> validate_inclusion(:status, @statuses)
    |> unique_constraint(:account_id)
    |> unique_constraint(:stripe_subscription_id)
  end
end
