defmodule Aprsme.EnhancedParserTest do
  use Aprsme.DataCase, async: true

  alias Aprsme.Packet

  describe "enhanced parser field extraction" do
    test "dead parser compat fields are dropped (not preserved)" do
      attrs = %{
        srccallsign: "W1AW",
        dstcallsign: "APRS",
        body: "!1234.56N/12345.67W-Test",
        origpacket: "W1AW>APRS:!1234.56N/12345.67W-Test",
        header: "W1AW>APRS",
        alive: 1,
        posambiguity: 0,
        symboltable: "/",
        symbolcode: "-",
        messaging: 0,
        sender: "W1AW",
        base_callsign: "W1AW",
        ssid: "0",
        destination: "APRS",
        data_type: "position",
        received_at: DateTime.utc_now()
      }

      result = Packet.extract_additional_data(attrs, "W1AW>APRS:!1234.56N/12345.67W-Test")

      # Dead fields should not be in result
      refute Map.has_key?(result, :srccallsign)
      refute Map.has_key?(result, :dstcallsign)
      refute Map.has_key?(result, :body)
      refute Map.has_key?(result, :origpacket)
      refute Map.has_key?(result, :header)
      refute Map.has_key?(result, :alive)
      refute Map.has_key?(result, :posambiguity)
      refute Map.has_key?(result, :symboltable)
      refute Map.has_key?(result, :symbolcode)
      refute Map.has_key?(result, :messaging)
    end

    test "extracts radio range into data map" do
      attrs = %{
        radiorange: "0050",
        sender: "W1AW",
        base_callsign: "W1AW",
        ssid: "0",
        destination: "APRS",
        data_type: "position",
        received_at: DateTime.utc_now()
      }

      result = Packet.extract_additional_data(attrs)

      assert result[:data]["radiorange"] == "0050"
    end

    test "handles weather data from wx field" do
      attrs = %{
        sender: "WX1STN",
        base_callsign: "WX1STN",
        ssid: "0",
        destination: "APRS",
        data_type: "weather",
        received_at: DateTime.utc_now(),
        data_extended: %{
          wx: %{
            temperature: 72.5,
            humidity: 65,
            pressure: 1013.2,
            wind_speed: 12.5,
            wind_direction: 180
          }
        }
      }

      result = Packet.extract_additional_data(attrs)

      assert result[:temperature] == 72.5
      assert result[:humidity] == 65
      assert result[:pressure] == 1013.2
      assert result[:wind_speed] == 12.5
      assert result[:wind_direction] == 180
    end

    test "handles PHG data in string format and moves to data map" do
      attrs = %{
        sender: "W1AW",
        base_callsign: "W1AW",
        ssid: "0",
        destination: "APRS",
        data_type: "position",
        received_at: DateTime.utc_now(),
        data_extended: %{
          phg: "5430"
        }
      }

      result = Packet.extract_additional_data(attrs)

      # PHG 5430: power=5^2=25W, height=4->160ft, gain=3dB, dir=0->omni
      # PHG fields should be in the data map
      assert result[:data]["phg_power"] == 25
      assert result[:data]["phg_height"] == 160
      assert result[:data]["phg_gain"] == 3
      assert result[:data]["phg_directivity"] == 0
    end

    test "handles PHG data in legacy map format and moves to data map" do
      attrs = %{
        sender: "W1AW",
        base_callsign: "W1AW",
        ssid: "0",
        destination: "APRS",
        data_type: "position",
        received_at: DateTime.utc_now(),
        data_extended: %{
          phg: %{
            power: 25,
            height: 160,
            gain: 3,
            directivity: 0
          }
        }
      }

      result = Packet.extract_additional_data(attrs)

      assert result[:data]["phg_power"] == 25
      assert result[:data]["phg_height"] == 160
      assert result[:data]["phg_gain"] == 3
      assert result[:data]["phg_directivity"] == 0
    end

    test "collect_into_data_map sweeps all 14 fields into data" do
      attrs = %{
        sender: "W1AW",
        base_callsign: "W1AW",
        ssid: "0",
        destination: "APRS",
        data_type: "position",
        received_at: DateTime.utc_now(),
        data_extended: %{
          phg: "5430",
          format: :uncompressed,
          posresolution: 18.52,
          position_ambiguity: 0,
          comment: "Test PHG5430"
        }
      }

      result = Packet.extract_additional_data(attrs)

      # These fields should be in the data map, not at top level
      assert result[:data]["phg_power"] == 25
      assert result[:data]["format"] == "uncompressed"
      assert result[:data]["posresolution"] == 18.52
      assert result[:data]["position_ambiguity"] == 0

      # They should NOT be at top level
      refute Map.has_key?(result, :phg_power)
      refute Map.has_key?(result, :format)
      refute Map.has_key?(result, :posresolution)
      refute Map.has_key?(result, :position_ambiguity)
    end

    test "telemetry fields are moved into data map" do
      attrs = %{
        sender: "W1AW",
        base_callsign: "W1AW",
        ssid: "0",
        destination: "APRS",
        data_type: "telemetry",
        received_at: DateTime.utc_now(),
        data_extended: %{
          telemetry: %{
            seq: 123,
            vals: [1, 2, 3, 4, 5],
            bits: "11111111"
          }
        }
      }

      result = Packet.extract_additional_data(attrs)

      assert result[:data]["telemetry_seq"] == 123
      assert result[:data]["telemetry_vals"] == [1, 2, 3, 4, 5]
      assert result[:data]["telemetry_bits"] == "11111111"

      refute Map.has_key?(result, :telemetry_seq)
      refute Map.has_key?(result, :telemetry_vals)
      refute Map.has_key?(result, :telemetry_bits)
    end

    test "luminosity and rain_midnight are moved into data map" do
      attrs = %{
        sender: "WX1STN",
        base_callsign: "WX1STN",
        ssid: "0",
        destination: "APRS",
        data_type: "weather",
        received_at: DateTime.utc_now(),
        data_extended: %{
          wx: %{
            temperature: 72.5,
            luminosity: 500,
            rain_midnight: 0.5
          }
        }
      }

      result = Packet.extract_additional_data(attrs)

      # luminosity and rain_midnight should be in data map
      assert result[:data]["luminosity"] == 500
      assert result[:data]["rain_midnight"] == 0.5

      # temperature stays at top level
      assert result[:temperature] == 72.5
    end
  end

  describe "enhanced parser packet storage" do
    test "stores packet with data map fields" do
      attrs = %{
        sender: "W1AW-1",
        base_callsign: "W1AW",
        ssid: "1",
        destination: "APRS",
        data_type: "position",
        received_at: DateTime.utc_now(),
        raw_packet: "W1AW-1>APRS:!1234.56N/12345.67W-Test RNG0050",
        lat: 12.576,
        lon: -123.761,
        symbol_code: "-",
        symbol_table_id: "/",
        comment: "Test station",
        radiorange: "0050",
        information_field: "!1234.56N/12345.67W-Test"
      }

      processed_attrs = Packet.extract_additional_data(attrs)

      assert {:ok, packet} = Aprsme.Packets.store_packet(processed_attrs)

      # radiorange and information_field should be in data map
      assert packet.data["radiorange"] == "0050"
      assert packet.data["information_field"] == "!1234.56N/12345.67W-Test"
    end
  end
end
