defmodule WhoNeedHelpWeb.SupportOperationsLive do
  use WhoNeedHelpWeb, :live_view

  alias WhoNeedHelp.{ContentRemoval, Support}

  @impl true
  def mount(_params, _session, socket) do
    {:ok, socket |> assign(:page_title, gettext("Support operations")) |> load()}
  end

  @impl true
  def handle_event("moderate-support", %{"id" => id, "moderation" => params}, socket) do
    respond(
      socket,
      Support.moderate(socket.assigns.current_scope, id, params),
      gettext("Support request updated.")
    )
  end

  def handle_event("moderate-removal", %{"id" => id, "moderation" => params}, socket) do
    respond(
      socket,
      ContentRemoval.moderate(socket.assigns.current_scope, id, params),
      gettext("Removal notice updated.")
    )
  end

  def handle_event("load-more-support", _params, socket) do
    page =
      Support.paginate_for_staff(socket.assigns.current_scope,
        after: socket.assigns.support_cursor
      )

    {:noreply, append_page(socket, :support_requests, :support_cursor, page)}
  end

  def handle_event("load-more-removals", _params, socket) do
    page =
      ContentRemoval.paginate_for_staff(socket.assigns.current_scope,
        after: socket.assigns.removal_cursor
      )

    {:noreply, append_page(socket, :removal_notices, :removal_cursor, page)}
  end

  defp respond(socket, {:ok, _record}, message) do
    {:noreply, socket |> put_flash(:info, message) |> load()}
  end

  defp respond(socket, {:error, reason}, _message) do
    {:noreply, put_flash(socket, :error, error_message(reason))}
  end

  defp load(socket) do
    support = Support.paginate_for_staff(socket.assigns.current_scope)
    removals = ContentRemoval.paginate_for_staff(socket.assigns.current_scope)

    socket
    |> assign(:support_requests, support.entries)
    |> assign(:support_cursor, support.next_cursor)
    |> assign(:removal_notices, removals.entries)
    |> assign(:removal_cursor, removals.next_cursor)
  end

  defp append_page(socket, entries_key, cursor_key, page) do
    existing = socket.assigns[entries_key]
    existing_ids = MapSet.new(existing, & &1.id)
    entries = existing ++ Enum.reject(page.entries, &MapSet.member?(existing_ids, &1.id))

    socket |> assign(entries_key, entries) |> assign(cursor_key, page.next_cursor)
  end

  defp error_message(:forbidden), do: gettext("Moderator access is required.")
  defp error_message(:not_found), do: gettext("The selected record is no longer available.")
  defp error_message(%Ecto.Changeset{}), do: gettext("Please check the submitted fields.")
  defp error_message(_reason), do: gettext("Could not update the request. Please try again.")

  defp support_kind(:account_access), do: gettext("Account access")
  defp support_kind(:technical_issue), do: gettext("Technical issue")
  defp support_kind(:safety_concern), do: gettext("Safety concern")
  defp support_kind(:moderation_appeal), do: gettext("Moderation appeal")
  defp support_kind(:account_deletion), do: gettext("Account deletion")
  defp support_kind(:data_export), do: gettext("Data export")
  defp support_kind(:privacy_request), do: gettext("Privacy request")
  defp support_kind(:other), do: gettext("Other")
  defp support_kind(value), do: to_string(value)

  defp removal_category(:illegal_content), do: gettext("Illegal content")
  defp removal_category(:privacy_violation), do: gettext("Privacy violation")
  defp removal_category(:copyright), do: gettext("Copyright")
  defp removal_category(:impersonation), do: gettext("Impersonation")

  defp removal_category(:non_consensual_intimate_media),
    do: gettext("Non-consensual intimate image or video")

  defp removal_category(:child_sexual_abuse_material),
    do: gettext("Sexual material involving a minor")

  defp removal_category(:threat_to_life_or_safety), do: gettext("Threat to life or safety")
  defp removal_category(:other), do: gettext("Other")
  defp removal_category(value), do: to_string(value)

  defp status_label(value), do: value |> to_string() |> String.replace("_", " ")

  defp scoped_form(data, id), do: to_form(data, as: :moderation, id: id)

  @impl true
  def render(assigns) do
    ~H"""
    <Layouts.app flash={@flash} current_scope={@current_scope}>
      <div class="text-sm font-semibold text-warning">{gettext("RESTRICTED WORKSPACE")}</div>
      <div class="flex flex-wrap items-end justify-between gap-3">
        <div>
          <h1 class="mt-1 text-4xl font-black">{gettext("Support operations")}</h1>
          <p class="mt-2 text-base-content/60">
            {gettext(
              "Support requests and legal removal notices are separate queues. Decisions and operator identity are audited."
            )}
          </p>
        </div>
        <.link navigate={~p"/moderation"} class="btn btn-outline btn-sm">
          {gettext("Trust and safety moderation")}
        </.link>
      </div>

      <section class="mt-8">
        <h2 class="text-2xl font-bold">{gettext("Content removal and TAKE IT DOWN")}</h2>
        <div class="mt-4 space-y-4">
          <article
            :for={notice <- @removal_notices}
            class={[
              "rounded-2xl border p-5",
              notice.status == :urgent_review && "border-error bg-error/5",
              notice.status != :urgent_review && "border-base-300"
            ]}
          >
            <% form =
              scoped_form(
                %{
                  "status" => to_string(notice.status),
                  "resolution_note" => notice.resolution_note || ""
                },
                "removal-#{notice.id}"
              ) %>
            <div class="flex flex-wrap items-center gap-2">
              <span class="badge badge-error">{notice.reference}</span>
              <span class="badge badge-outline">{notice.regime}</span>
              <span class="badge">{status_label(notice.status)}</span>
              <span :if={is_nil(notice.contact_verified_at)} class="badge badge-warning">
                {gettext("contact unverified")}
              </span>
              <span class="text-xs text-base-content/55">{removal_category(notice.category)}</span>
              <span :if={notice.response_due_at} class="badge badge-error badge-outline">
                {gettext("review by %{time}", time: notice.response_due_at)}
              </span>
            </div>
            <dl class="mt-4 grid gap-2 text-sm sm:grid-cols-[10rem_1fr]">
              <dt class="font-semibold">{gettext("Submitter")}</dt>
              <dd>{notice.submitter_name || gettext("Not provided")}</dd>
              <dt class="font-semibold">{gettext("Contact")}</dt>
              <dd>{notice.contact_email || gettext("Not provided")}</dd>
              <dt class="font-semibold">{gettext("Locations")}</dt>
              <dd class="space-y-1">
                <div
                  :for={url <- WhoNeedHelp.ContentRemoval.Notice.content_urls(notice)}
                  class="break-all font-mono text-xs"
                >
                  {url}
                </div>
              </dd>
            </dl>
            <p class="mt-4 whitespace-pre-wrap text-sm">{notice.explanation}</p>
            <p
              :if={notice.legal_basis not in [nil, ""]}
              class="mt-3 whitespace-pre-wrap text-sm text-base-content/65"
            >
              <strong>{gettext("Stated basis:")}</strong> {notice.legal_basis}
            </p>
            <.form
              for={form}
              phx-submit="moderate-removal"
              phx-value-id={notice.id}
              class="mt-4 grid gap-2 md:grid-cols-[13rem_1fr_auto]"
            >
              <.input
                field={form[:status]}
                type="select"
                options={[
                  {gettext("Open"), "open"},
                  {gettext("Urgent review"), "urgent_review"},
                  {gettext("Reviewing"), "reviewing"},
                  {gettext("More information needed"), "needs_information"},
                  {gettext("Action taken"), "actioned"},
                  {gettext("Rejected"), "rejected"},
                  {gettext("Closed"), "closed"}
                ]}
              />
              <.input
                field={form[:resolution_note]}
                type="textarea"
                placeholder={gettext("Decision or information request")}
              />
              <.button class="btn btn-error self-end">{gettext("Save and notify")}</.button>
            </.form>
          </article>
          <p :if={@removal_notices == []} class="text-base-content/50">
            {gettext("No removal notices.")}
          </p>
        </div>
        <button
          :if={@removal_cursor}
          phx-click="load-more-removals"
          class="btn btn-outline btn-sm mt-4"
        >
          {gettext("Load more")}
        </button>
      </section>

      <section class="mt-12">
        <h2 class="text-2xl font-bold">{gettext("General support and data requests")}</h2>
        <div class="mt-4 space-y-4">
          <article :for={request <- @support_requests} class="rounded-2xl border border-base-300 p-5">
            <% form =
              scoped_form(
                %{
                  "status" => to_string(request.status),
                  "resolution_note" => request.resolution_note || ""
                },
                "support-#{request.id}"
              ) %>
            <div class="flex flex-wrap items-center gap-2">
              <span class="badge badge-primary">{request.reference}</span>
              <span class="badge">{status_label(request.status)}</span>
              <span :if={is_nil(request.contact_verified_at)} class="badge badge-warning">
                {gettext("contact unverified")}
              </span>
              <span class="text-xs text-base-content/55">{support_kind(request.kind)}</span>
            </div>
            <h3 class="mt-3 font-bold">{request.subject}</h3>
            <p class="mt-1 text-xs text-base-content/55">{request.contact_email}</p>
            <p class="mt-3 whitespace-pre-wrap text-sm">{request.details}</p>
            <.form
              for={form}
              phx-submit="moderate-support"
              phx-value-id={request.id}
              class="mt-4 grid gap-2 md:grid-cols-[13rem_1fr_auto]"
            >
              <.input
                field={form[:status]}
                type="select"
                options={[
                  {gettext("Open"), "open"},
                  {gettext("Reviewing"), "reviewing"},
                  {gettext("Waiting for requester"), "waiting_for_requester"},
                  {gettext("Resolved"), "resolved"},
                  {gettext("Closed"), "closed"}
                ]}
              />
              <.input
                field={form[:resolution_note]}
                type="textarea"
                placeholder={gettext("Support response")}
              />
              <.button class="btn btn-primary self-end">{gettext("Save and notify")}</.button>
            </.form>
          </article>
          <p :if={@support_requests == []} class="text-base-content/50">
            {gettext("No support requests.")}
          </p>
        </div>
        <button
          :if={@support_cursor}
          phx-click="load-more-support"
          class="btn btn-outline btn-sm mt-4"
        >
          {gettext("Load more")}
        </button>
      </section>
    </Layouts.app>
    """
  end
end
