defmodule WhoNeedHelp.Support.SupportRequest do
  use Ecto.Schema
  import Ecto.Changeset

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

  schema "support_requests" do
    field :reference, :string

    field :kind, Ecto.Enum,
      values: [
        :account_access,
        :technical_issue,
        :safety_concern,
        :moderation_appeal,
        :account_deletion,
        :data_export,
        :privacy_request,
        :other
      ]

    field :status, Ecto.Enum,
      values: [:open, :reviewing, :waiting_for_requester, :resolved, :closed],
      default: :open

    field :contact_email, :string
    field :subject, :string
    field :details, :string
    field :contact_verified_at, :utc_datetime
    field :resolution_note, :string
    field :reviewed_at, :utc_datetime
    field :response_sent_at, :utc_datetime
    belongs_to :requester, WhoNeedHelp.Accounts.User
    belongs_to :reviewed_by, WhoNeedHelp.Accounts.User
    timestamps(type: :utc_datetime)
  end

  def submission_changeset(request, attrs) do
    request
    |> cast(attrs, [:kind, :contact_email, :subject, :details])
    |> validate_required([:kind, :contact_email, :subject, :details, :reference])
    |> update_change(:contact_email, &normalize_email/1)
    |> validate_format(:contact_email, ~r/^[^@,;\s]+@[^@,;\s]+$/,
      message: "must have the @ sign and no spaces"
    )
    |> validate_length(:contact_email, max: 160)
    |> validate_length(:subject, min: 3, max: 160)
    |> validate_length(:details, min: 10, max: 5_000)
    |> unique_constraint(:reference)
  end

  def moderation_changeset(request, attrs) do
    request
    |> cast(attrs, [:status, :resolution_note, :reviewed_at, :reviewed_by_id, :response_sent_at])
    |> validate_required([:status, :reviewed_at, :reviewed_by_id])
    |> validate_length(:resolution_note, max: 5_000)
  end

  defp normalize_email(email), do: email |> String.trim() |> String.downcase()
end
