defmodule Tarakan.Market.BountyClaim do
  @moduledoc """
  One hunter's claim on a bounty, backed by a Work queue review task.

  The linked `review_task_id` carries the actual work lifecycle (claim lease,
  submission, acceptance); the claim row mirrors the bounty-relevant slice of
  that state so settlement can find the winning hunter without walking tasks.
  A partial unique index allows only one active (`claimed`/`submitted`) claim
  per hunter per bounty.
  """

  use Ecto.Schema
  import Ecto.Changeset

  alias Tarakan.Accounts.Account
  alias Tarakan.Market.Bounty
  alias Tarakan.Work.ReviewTask

  @statuses ~w(claimed submitted accepted rejected withdrawn)
  @active_statuses ~w(claimed submitted)

  schema "bounty_claims" do
    field :status, :string, default: "claimed"

    belongs_to :bounty, Bounty
    belongs_to :account, Account
    belongs_to :review_task, ReviewTask

    timestamps(type: :utc_datetime_usec)
  end

  def statuses, do: @statuses
  def active_statuses, do: @active_statuses

  @doc false
  def changeset(claim, attrs) do
    claim
    |> cast(attrs, [:bounty_id, :account_id, :review_task_id, :status])
    |> validate_required([:bounty_id, :account_id, :status])
    |> validate_inclusion(:status, @statuses)
    |> unique_constraint([:bounty_id, :account_id],
      name: :bounty_claims_active_unique_index
    )
    |> foreign_key_constraint(:bounty_id)
    |> foreign_key_constraint(:account_id)
    |> foreign_key_constraint(:review_task_id)
    |> check_constraint(:status, name: :bounty_claims_status_must_be_valid)
  end
end
