defmodule TarakanWeb.BountyLive.Index do
  @moduledoc "Open contracts - the public reward board."
  use TarakanWeb, :live_view

  import TarakanWeb.BountyComponents

  alias Tarakan.Market

  @filters [
    {"all", "All"},
    {"repository", "Repositories"},
    {"infestation", "Infestations"},
    {"finding", "Findings"}
  ]

  @impl true
  def mount(_params, _session, socket) do
    {:ok,
     socket
     |> assign(:page_title, "Contracts")
     |> assign(
       :meta_description,
       "Open contracts on Tarakan. Sponsors post rewards for security work on public targets."
     )
     |> assign(:canonical_path, ~p"/bounties")
     |> assign(:filters, @filters)}
  end

  @impl true
  def handle_params(params, _uri, socket) do
    filter = normalize_filter(params["type"])
    bounties = Market.list_open(target_type: filter)

    {:noreply,
     socket
     |> assign(:filter, filter || "all")
     |> assign(:bounties, bounties)
     |> assign(:bounty_count, length(bounties))
     |> assign(:open_cents, sum_by(bounties, :amount_cents))
     |> assign(:open_credits, sum_by(bounties, :credit_amount))}
  end

  defp sum_by(bounties, key) do
    Enum.reduce(bounties, 0, fn bounty, total -> total + (Map.get(bounty, key) || 0) end)
  end

  defp normalize_filter(filter) when filter in ["repository", "infestation", "finding"],
    do: filter

  defp normalize_filter(_), do: nil

  @impl true
  def render(assigns) do
    ~H"""
    <Layouts.app flash={@flash} current_scope={@current_scope} current_path={assigns[:current_path]}>
      <Layouts.page width={:wide}>
        <div class="flex flex-col gap-6 border-b-2 border-strong pb-6 sm:flex-row sm:items-end sm:justify-between">
          <div class="min-w-0 max-w-2xl">
            <h1 class="font-display text-3xl font-medium uppercase leading-none tracking-[0.02em] text-ink sm:text-5xl">
              Contracts
            </h1>
          </div>
          <div class="flex shrink-0 flex-wrap items-center gap-4">
            <p class="font-mono text-sm tabular-nums text-ink">
              <span class="font-display text-3xl">{@bounty_count}</span>
              <span class="ml-1 text-xs uppercase tracking-[0.12em] text-ink-faint">open</span>
            </p>
            <p :if={@open_cents > 0} class="font-mono text-sm tabular-nums text-ink">
              <span class="font-display text-3xl">${div(@open_cents, 100)}</span>
              <span class="ml-1 text-xs uppercase tracking-[0.12em] text-ink-faint">escrowed</span>
            </p>
            <p :if={@open_credits > 0} class="font-mono text-sm tabular-nums text-ink">
              <span class="font-display text-3xl">{@open_credits}</span>
              <span class="ml-1 text-xs uppercase tracking-[0.12em] text-ink-faint">credits</span>
            </p>
            <.link
              navigate={~p"/bounties/new"}
              class="border-2 border-signal px-4 py-1.5 font-display text-xs uppercase tracking-[0.12em] text-signal transition hover:bg-signal hover:text-ground"
            >
              Post a contract
            </.link>
          </div>
        </div>

        <div id="bounty-filters" class="mt-6 flex flex-wrap items-center gap-2">
          <.link
            :for={{value, label} <- @filters}
            patch={~p"/bounties?#{%{type: value}}"}
            class={[
              "wire-badge font-display text-[10px] uppercase tracking-[0.12em] transition",
              @filter == value && "bg-signal text-ground",
              @filter != value && "text-ink-muted hover:text-ink"
            ]}
          >
            <span class="wire-badge-label">{label}</span>
          </.link>
        </div>

        <div
          :if={@bounties == []}
          id="bounties-empty"
          class="mt-8 bg-panel px-6 py-12 text-center"
        >
          <p class="text-sm font-medium text-ink">No open contracts right now</p>
          <p class="mt-2 text-xs leading-5 text-ink-muted">
            <.link navigate={~p"/bounties/new"} class="font-semibold text-signal hover:underline">
              Post the first one
            </.link>
            or browse the <.link
              navigate={~p"/jobs"}
              class="font-semibold text-signal hover:underline"
            >jobs queue</.link>.
          </p>
        </div>

        <ul
          :if={@bounties != []}
          id="bounties"
          class="mt-8 grid gap-4 sm:grid-cols-2 xl:grid-cols-3"
        >
          <li :for={bounty <- @bounties} id={"bounty-#{bounty.public_id}"}>
            <.link
              navigate={~p"/bounties/#{bounty.public_id}"}
              class="group flex h-full flex-col border-2 border-strong bg-panel transition-colors hover:bg-ground"
            >
              <div class="flex items-center justify-between border-b-2 border-strong px-4 py-2">
                <.notch_badge class="bg-signal text-ground">Contract</.notch_badge>
                <span class="font-mono text-[10px] uppercase tracking-[0.12em] text-ink-faint">
                  {bounty.target_type}
                </span>
              </div>
              <div class="flex flex-1 flex-col px-4 py-4">
                <p class="font-display text-3xl font-medium leading-none text-signal">
                  {amount_label(bounty)}
                </p>
                <p class="mt-3 text-sm font-semibold leading-5 text-ink group-hover:text-signal">
                  {bounty.title}
                </p>
                <p class="mt-2 line-clamp-2 text-xs leading-5 text-ink-muted">
                  {bounty.description}
                </p>
                <p class="mt-auto pt-4 font-mono text-[11px] text-ink-faint">
                  {target_label(bounty)}
                  <span :if={bounty.sponsor_account} class="mx-1">·</span>
                  <span :if={bounty.sponsor_account}>by @{bounty.sponsor_account.handle}</span>
                  <span :if={bounty.expires_at} class="mx-1">·</span>
                  <span :if={bounty.expires_at}>
                    expires {Calendar.strftime(bounty.expires_at, "%b %-d")}
                  </span>
                </p>
              </div>
            </.link>
          </li>
        </ul>
      </Layouts.page>
    </Layouts.app>
    """
  end
end
