defmodule AprsmeWeb.MapLive.ComponentsTest do
  use ExUnit.Case, async: true

  import Phoenix.LiveViewTest

  alias AprsmeWeb.MapLive.Components

  describe "map_container/1" do
    test "renders aprs-map div with encoded center and zoom" do
      html =
        render_component(&Components.map_container/1,
          map_center: %{lat: 40.0, lng: -100.0},
          map_zoom: 5,
          slideover_open: false
        )

      assert html =~ ~s(id="aprs-map")
      assert html =~ ~s(phx-hook="APRSMap")
      assert html =~ "data-zoom=\"5\""
      assert html =~ "40.0"
      assert html =~ "-100.0"
    end

    test "adds slideover-open class when panel is open" do
      html =
        render_component(&Components.map_container/1,
          map_center: %{lat: 0.0, lng: 0.0},
          map_zoom: 5,
          slideover_open: true
        )

      assert html =~ "slideover-open"
    end

    test "adds slideover-closed class when panel is closed" do
      html =
        render_component(&Components.map_container/1,
          map_center: %{lat: 0.0, lng: 0.0},
          map_zoom: 5,
          slideover_open: false
        )

      assert html =~ "slideover-closed"
    end
  end

  describe "slideover_panel/1" do
    defp base_assigns(overrides \\ %{}) do
      Enum.into(overrides, %{
        slideover_open: true,
        loading: false,
        connection_status: "connected",
        packets: [],
        show_all_packets: true,
        tracked_callsign: "",
        tracked_callsign_latest_packet: nil
      })
    end

    test "renders header + content when open" do
      html = render_component(&Components.slideover_panel/1, base_assigns())
      assert html =~ "APRS Packets"
      assert html =~ "slideover-panel"
    end

    test "shows the 'connected' indicator text for a connected status" do
      html =
        render_component(
          &Components.slideover_panel/1,
          base_assigns(%{connection_status: "connected"})
        )

      assert html =~ "Connected to APRS-IS"
    end

    test "shows 'connecting' indicator text" do
      html =
        render_component(
          &Components.slideover_panel/1,
          base_assigns(%{connection_status: "connecting"})
        )

      assert html =~ "Connecting to APRS-IS"
    end

    test "shows 'disconnected' indicator text" do
      html =
        render_component(
          &Components.slideover_panel/1,
          base_assigns(%{connection_status: "disconnected"})
        )

      assert html =~ "Disconnected from APRS-IS"
    end

    test "shows 'Initializing...' for pending/unknown status" do
      html =
        render_component(
          &Components.slideover_panel/1,
          base_assigns(%{connection_status: "pending"})
        )

      assert html =~ "Initializing"
    end

    test "shows the loading spinner when loading" do
      html =
        render_component(
          &Components.slideover_panel/1,
          base_assigns(%{loading: true})
        )

      assert html =~ "Loading packets"
      # Spinner SVG has an animate-spin class.
      assert html =~ "animate-spin"
    end

    test "shows a clear button only when a callsign is tracked" do
      with_tracked =
        render_component(
          &Components.slideover_panel/1,
          base_assigns(%{tracked_callsign: "K5ABC"})
        )

      assert with_tracked =~ "clear_callsign_filter"

      without_tracked =
        render_component(
          &Components.slideover_panel/1,
          base_assigns(%{tracked_callsign: ""})
        )

      refute without_tracked =~ "clear_callsign_filter"
    end

    test "renders the 'All' and 'With Position' radio options" do
      html = render_component(&Components.slideover_panel/1, base_assigns())
      assert html =~ "All Packets"
      assert html =~ "With Position"
    end

    test "renders packet cards for stations with positions" do
      packet = %{
        sender: "K5GVL-10",
        ssid: "10",
        lat: 33.1,
        lon: -96.5,
        has_position: true,
        comment: "Mobile station",
        path: "WIDE1-1",
        received_at: DateTime.utc_now()
      }

      html =
        render_component(
          &Components.slideover_panel/1,
          base_assigns(%{packets: [{"packet-1", packet}]})
        )

      assert html =~ "K5GVL-10"
      assert html =~ "Mobile station"
      # The center-on-packet button is rendered for packets with position.
      assert html =~ "center_on_packet"
    end

    test "packet cards for stations without position hide the center button" do
      packet = %{
        sender: "K5GVL",
        ssid: "0",
        lat: nil,
        lon: nil,
        has_position: false,
        comment: nil,
        path: nil,
        received_at: DateTime.utc_now()
      }

      html =
        render_component(
          &Components.slideover_panel/1,
          base_assigns(%{packets: [{"packet-2", packet}]})
        )

      assert html =~ "K5GVL"
      assert html =~ "direct"
      refute html =~ "center_on_packet"
    end

    test "shows the last-seen timestamp for a tracked callsign" do
      latest = %{received_at: DateTime.add(DateTime.utc_now(), -60, :second)}

      html =
        render_component(
          &Components.slideover_panel/1,
          base_assigns(%{
            tracked_callsign: "K5ABC",
            tracked_callsign_latest_packet: latest
          })
        )

      assert html =~ "Last seen"
    end
  end

  describe "map_styles/1" do
    test "renders a <style> block" do
      html = render_component(&Components.map_styles/1, %{})
      assert html =~ "<style>"
      assert html =~ "#aprs-map"
      assert html =~ ".slideover-panel"
    end
  end
end
