defmodule MicrowavepropWeb.ContactMapLive do
  @moduledoc false
  use MicrowavepropWeb, :live_view

  alias Microwaveprop.Radio

  @band_colors %{
    1296 => "#475569",
    2304 => "#7c3aed",
    3400 => "#4f46e5",
    5760 => "#2563eb",
    10_000 => "#059669",
    24_000 => "#d97706",
    47_000 => "#ea580c",
    68_000 => "#dc2626",
    75_000 => "#c026d3",
    122_000 => "#db2777",
    134_000 => "#e11d48",
    241_000 => "#b91c1c"
  }

  @impl true
  def mount(_params, _session, socket) do
    # Shell renders immediately with filter chrome (count + bands list). The
    # JS hook fetches the ~5 MB contacts payload from `/api/contacts/map`
    # after mount, which streams it as pre-gzipped bytes via the browser's
    # native `Content-Encoding: gzip` handling. This gets the heavy payload
    # off the initial HTML entirely.
    #
    # Band toggles are handled entirely client-side in the ContactsMap hook
    # (per-band Leaflet LayerGroups) so there's no enabled_bands state on
    # the server. Callsign filter still roundtrips (debounced) to push the
    # filter string to the hook.
    %{count: count, bands: bands} = Radio.contact_map_payload()

    {:ok,
     assign(socket,
       page_title: "Contact Map",
       contact_count: count,
       all_bands: bands,
       callsign_filter: ""
     )}
  end

  @impl true
  def handle_event("filter_callsign", %{"callsign" => callsign}, socket) do
    trimmed = String.trim(callsign)

    socket =
      socket
      |> assign(callsign_filter: trimmed)
      |> push_event("apply_filter", %{callsign: trimmed})

    {:noreply, socket}
  end

  defp band_label(mhz) when mhz >= 1000 do
    ghz = mhz / 1000
    label = if ghz == trunc(ghz), do: "#{trunc(ghz)}", else: "#{Float.round(ghz / 1, 1)}"
    "#{label} GHz"
  end

  defp band_label(mhz), do: "#{mhz} MHz"

  defp band_color(mhz), do: Map.get(@band_colors, mhz, "#64748b")

  @impl true
  def render(assigns) do
    ~H"""
    <div class="fixed inset-0 flex">
      <div class="flex-1 relative">
        <div
          id="contacts-map"
          phx-hook="ContactsMap"
          phx-update="ignore"
          data-fetch-url="/api/contacts/map"
          class="absolute inset-0 z-0"
        >
        </div>

        <%!-- Mobile floating controls --%>
        <div
          id="map-controls"
          class="md:hidden absolute top-2 left-12 z-[1000] flex flex-col gap-2 max-w-[calc(100vw-4rem)]"
        >
          <div
            data-theme="dark"
            class="bg-neutral text-neutral-content shadow rounded-box border border-base-300 p-2 flex flex-col gap-2"
          >
            <div class="font-bold text-sm leading-tight px-1 flex items-center justify-between gap-2">
              <div class="min-w-0">
                <span>Contact Map</span>
                <div id="contact-count-mobile" class="font-normal text-xs opacity-70">
                  {Integer.to_string(@contact_count)} contacts
                </div>
              </div>
              <button
                id="mobile-panel-toggle"
                class="btn btn-xs btn-square btn-ghost"
                onclick="document.getElementById('panel-extras').classList.toggle('hidden')"
              >
                <.icon name="hero-bars-3" class="size-4" />
              </button>
            </div>

            <div id="panel-extras" class="hidden flex-col gap-2">
              <input
                type="text"
                placeholder="Filter callsign..."
                phx-keyup="filter_callsign"
                phx-key="Enter"
                phx-change="filter_callsign"
                phx-debounce="300"
                name="callsign"
                value={@callsign_filter}
                class="input input-xs w-full"
              />

              <div class="flex items-center justify-between">
                <span class="text-xs font-bold">Bands</span>
                <span class="flex gap-2">
                  <button
                    type="button"
                    data-band-action="all"
                    class="text-[10px] underline opacity-70"
                  >
                    All
                  </button>
                  <button
                    type="button"
                    data-band-action="none"
                    class="text-[10px] underline opacity-70"
                  >
                    None
                  </button>
                </span>
              </div>

              <div id="band-checkboxes-mobile" phx-update="ignore">
                <%= for band <- @all_bands do %>
                  <label class="flex items-center gap-2 cursor-pointer text-xs">
                    <input
                      type="checkbox"
                      checked
                      data-band={band}
                      style={"accent-color:#{band_color(band)}"}
                    />
                    <span
                      class="inline-block w-3 h-0.5 rounded-sm shrink-0"
                      style={"background:#{band_color(band)}"}
                    >
                    </span>
                    <span>{band_label(band)}</span>
                  </label>
                <% end %>
              </div>

              <div class="flex flex-col gap-1 border-t border-base-300 pt-2">
                <.link navigate="/map" class="btn btn-xs btn-ghost justify-start">
                  Propagation Map
                </.link>
                <.link navigate="/path" class="btn btn-xs btn-ghost justify-start">
                  Path Calculator
                </.link>
                <.link navigate="/beacons" class="btn btn-xs btn-ghost justify-start">
                  Beacons
                </.link>
                <.link navigate="/contacts" class="btn btn-xs btn-ghost justify-start">
                  Contacts
                </.link>
                <.link navigate="/submit" class="btn btn-xs btn-ghost justify-start">
                  Submit a Contact
                </.link>
                <.link navigate="/about" class="btn btn-xs btn-ghost justify-start">
                  About
                </.link>
              </div>
            </div>
          </div>
        </div>
      </div>

      <%!-- Desktop right sidebar --%>
      <div
        id="sidebar"
        data-theme="dark"
        class="hidden md:flex flex-col w-56 shrink-0 h-full bg-neutral text-neutral-content border-l border-base-300 overflow-hidden"
      >
        <div class="p-3 flex flex-col gap-2 shrink-0 overflow-y-auto flex-1">
          <div class="font-bold text-sm leading-tight px-1">
            <span>Contact Map</span>
            <div id="contact-count" class="font-normal text-xs opacity-70">
              {Integer.to_string(@contact_count)} contacts
            </div>
          </div>

          <%!-- Callsign filter --%>
          <input
            type="text"
            placeholder="Filter callsign..."
            phx-keyup="filter_callsign"
            phx-key="Enter"
            phx-change="filter_callsign"
            phx-debounce="300"
            name="callsign"
            value={@callsign_filter}
            class="input input-sm w-full"
          />

          <%!-- Band checkboxes --%>
          <div class="flex items-center justify-between px-1">
            <span class="text-xs font-bold">Bands</span>
            <span class="flex gap-2">
              <button type="button" data-band-action="all" class="text-[10px] underline opacity-70">
                All
              </button>
              <button type="button" data-band-action="none" class="text-[10px] underline opacity-70">
                None
              </button>
            </span>
          </div>

          <div id="band-checkboxes" class="flex flex-col" phx-update="ignore">
            <%= for band <- @all_bands do %>
              <label class="flex items-center gap-2 cursor-pointer px-1 text-sm leading-relaxed">
                <input
                  type="checkbox"
                  checked
                  data-band={band}
                  style={"accent-color:#{band_color(band)}"}
                />
                <span
                  class="inline-block w-3.5 h-0.5 rounded-sm shrink-0"
                  style={"background:#{band_color(band)}"}
                >
                </span>
                <span>{band_label(band)}</span>
              </label>
            <% end %>
          </div>

          <%!-- Navigation --%>
          <ul class="menu menu-xs border-t border-base-300 pt-2 px-0">
            <li>
              <.link navigate="/map">Propagation Map</.link>
            </li>
            <li>
              <.link navigate="/path">Path Calculator</.link>
            </li>
            <li>
              <.link navigate="/beacons">Beacons</.link>
            </li>
            <li>
              <.link navigate="/contacts">Contacts</.link>
            </li>
            <li>
              <.link navigate="/submit">Submit a Contact</.link>
            </li>
            <li>
              <.link navigate="/about">About</.link>
            </li>
          </ul>

          <%!-- Auth --%>
          <ul class="menu menu-xs border-t border-base-300 pt-2 px-0">
            <%= if @current_scope && @current_scope.user do %>
              <li>
                <.link navigate={~p"/u/#{@current_scope.user.callsign}"} class="font-semibold">
                  {@current_scope.user.callsign}
                </.link>
              </li>
              <li>
                <.link href={~p"/users/settings"}>Settings</.link>
              </li>
              <li>
                <.link href={~p"/users/log-out"} method="delete">Log out</.link>
              </li>
            <% else %>
              <li>
                <.link href={~p"/users/register"}>Register</.link>
              </li>
              <li>
                <.link href={~p"/users/log-in"}>Log in</.link>
              </li>
            <% end %>
          </ul>
        </div>
      </div>
    </div>

    <Layouts.flash_group flash={@flash} />
    """
  end
end
