defmodule Pain.Order do
  import Acuity, only: [headers: 0]

  @doc """
      order = %{
        schedule: "2023-09-09T15:00",
        employed: %{1 => "_fem", 2 => "_masc", 3 => "Andy Ji", 4 => "Bin Wang"},
        customer: %{ "email" => "mail@assembled.app", "name" => "Zi", "phone" => "222-333-4444", "reference" => "", "surname" => "Ao" },
        limbs: %{2 => ["Front / Left pectoral", "Front / Abs"]},
      }

      cs = PainWeb.BookLive.chosen_services(%{
        1 => "90Min Reflexology with Chinese Medicine",
        2 => "90min Massage", 3 => "Cupping", 4 => "Wet Cupping"
      })

      IEx.Helpers.recompile
      order |> Pain.Order.book(cs)
  """
  def book order, services, addons do
    address = "https://acuityscheduling.com/api/v1/appointments?admin=true" # <> "&noEmail=true"

    services
    |> Enum.sort_by(fn {n, _} -> employee_key(order[:employed][n]) end)
    |> Enum.map(fn {n, service} ->
      [name, surname] = case order[:customer]["name"] |> String.split(" ") do
        [n | []] -> [n,"_"]
        [n | [s]] -> [n, s]
      end
      body = %{
        datetime: order[:schedule],
        appointmentTypeID: service["schedule_key"],
        firstName: name,
        lastName: surname,
        email: order[:customer]["email"],
        phone: order[:customer]["phone"],
        notes: compile_remarks(order[:employed][n], order[:limbs][n]),
        addonIDs: addons[n],
        smsOptIn: true,
      }
      body = case employee_key(order[:employed][n]) do
        nil -> body
        key -> body |> Map.put(:calendarID, key)
      end |> IO.inspect

        case Req.post(address, json: body, headers: headers()) do
        {:error, r} -> Pain.Schedule.log r; "/error"
        {:ok, r = %Req.Response{status: 400}} -> Pain.Schedule.log r; "/error"
        {:ok, r } -> r.body["confirmationPagePaymentLink"]
      end
    end)
  end

  def employee_key name do
    (case name do

      "_any" ->
        Pain.Schedule.employees()
        |> Enum.random()

      "_" <> gender ->
        Pain.Schedule.employees()
        |> Enum.filter(&(&1[:gender] |> String.starts_with?(gender)))
        |> Enum.random()

      n ->
        Pain.Schedule.employees()
        |> Enum.find(&(&1[:name] == n))

    end)[:schedule_key]
  end

  def compile_remarks(employed, limbs) do
    employee = case employed do
      "_masc" -> "Masculine employee"
      "_fem" -> "Feminine employee"
      "_any" -> "Any employee"

      name -> name
    end

    [employee, describe_limbs(limbs)]
    |> Enum.filter(& &1) |> Enum.join("\n\n")
  end

  defp describe_limbs(nil), do: nil
  defp describe_limbs([]), do: nil
  defp describe_limbs([limb]), do: "Body location: " <> limb
  defp describe_limbs(limbs) do
    (["Body locations:"] ++
      Enum.map(limbs, fn limb -> case limb do
        nil -> nil
        "" -> nil
        "_choose" -> nil
        place -> "- #{place}"
      end end))
      |> Enum.filter(& &1)
      |> Enum.join("\n")
  end

end
