"""Example usage of NMEA parser for fishinfo SDK."""

import asyncio
from datetime import datetime, timezone
from uuid import UUID

from fishinfo import Client, Config
from fishinfo.nmea import (
    AISDecoder,
    NMEAConverter,
    NMEAParser,
    NMEASerialBatcher,
    NMEASerialReader,
)


def example_parse_nmea() -> None:
    """Example: Parse NMEA sentences."""
    print("=" * 60)
    print("Example 1: Parse NMEA Sentences")
    print("=" * 60)

    parser = NMEAParser()

    # Parse GGA sentence (position)
    gga = "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,47.0,M,,*47"
    gga_parsed = parser.parse(gga)
    print(f"\nGGA Sentence:")
    print(f"  Latitude: {gga_parsed.latitude:.4f}")
    print(f"  Longitude: {gga_parsed.longitude:.4f}")
    print(f"  Altitude: {gga_parsed.altitude} m")
    print(f"  Satellites: {gga_parsed.satellites}")
    print(f"  HDOP: {gga_parsed.hdop}")

    # Parse RMC sentence (position, speed, course)
    rmc = "$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A"
    rmc_parsed = parser.parse(rmc)
    print(f"\nRMC Sentence:")
    print(f"  Latitude: {rmc_parsed.latitude:.4f}")
    print(f"  Longitude: {rmc_parsed.longitude:.4f}")
    print(f"  Speed: {rmc_parsed.speed_knots} knots")
    print(f"  Course: {rmc_parsed.course}°")

    # Parse HDT sentence (heading)
    hdt = "$HEHDT,274.07,T*03"
    hdt_parsed = parser.parse(hdt)
    print(f"\nHDT Sentence:")
    print(f"  Heading: {hdt_parsed.heading}° True")

    # Parse DBT sentence (depth)
    dbt = "$SDDBT,12.3,f,3.7,M,2.0,F*31"
    dbt_parsed = parser.parse(dbt)
    print(f"\nDBT Sentence:")
    print(f"  Depth: {dbt_parsed.depth_meters} m")

    # Parse MWV sentence (wind)
    mwv = "$WIMWV,045.0,R,12.5,N,A*39"
    mwv_parsed = parser.parse(mwv)
    print(f"\nMWV Sentence:")
    print(f"  Wind Angle: {mwv_parsed.wind_angle}° ({mwv_parsed.reference})")
    print(f"  Wind Speed: {mwv_parsed.wind_speed} {mwv_parsed.speed_units}")

    # Parse MTW sentence (water temperature)
    mtw = "$YXMTW,15.5,C*1F"
    mtw_parsed = parser.parse(mtw)
    print(f"\nMTW Sentence:")
    print(f"  Water Temperature: {mtw_parsed.temperature}°C")


def example_decode_ais() -> None:
    """Example: Decode AIS messages."""
    print("\n" + "=" * 60)
    print("Example 2: Decode AIS Messages")
    print("=" * 60)

    decoder = AISDecoder()

    # Decode position report (type 1)
    ais_pos = "!AIVDM,1,1,,B,13u@Dp0P00PlT>HMGN4?vhR00<02,0*66"
    msg = decoder.decode(ais_pos)
    print(f"\nAIS Position Report (Type {msg.message_type}):")
    print(f"  MMSI: {msg.mmsi}")
    print(f"  Navigation Status: {msg.navigation_status.name}")
    if msg.latitude and msg.longitude:
        print(f"  Position: {msg.latitude:.4f}, {msg.longitude:.4f}")
    if msg.speed_over_ground:
        print(f"  Speed: {msg.speed_over_ground} knots")
    if msg.course_over_ground:
        print(f"  Course: {msg.course_over_ground}°")

    # Decode static data (type 5, multi-part)
    ais_static_1 = "!AIVDM,2,1,3,B,55?MbV02>H97PH97mR000<>0@T4@D0000000000015@T@10000000000000,0*7C"
    ais_static_2 = "!AIVDM,2,2,3,B,00000000000,2*20"

    decoder.decode(ais_static_1)  # First fragment
    static_msg = decoder.decode(ais_static_2)  # Complete message
    print(f"\nAIS Static Data (Type {static_msg.message_type}):")
    print(f"  MMSI: {static_msg.mmsi}")
    print(f"  Vessel Name: {static_msg.vessel_name}")
    print(f"  Call Sign: {static_msg.call_sign}")
    print(f"  Ship Type: {static_msg.ship_type}")
    print(
        f"  Dimensions: {static_msg.dimension_to_bow}m (bow) + "
        f"{static_msg.dimension_to_stern}m (stern)"
    )
    if static_msg.destination:
        print(f"  Destination: {static_msg.destination}")


def example_convert_to_telemetry() -> None:
    """Example: Convert NMEA to TelemetryPoint."""
    print("\n" + "=" * 60)
    print("Example 3: Convert NMEA to TelemetryPoint")
    print("=" * 60)

    parser = NMEAParser()
    converter = NMEAConverter(
        vessel_id=UUID("12345678-1234-1234-1234-123456789abc"),
        tenant_id=UUID("87654321-4321-4321-4321-cba987654321"),
        source="nmea_0183",
    )

    # Convert GGA to TelemetryPoint
    gga = "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,47.0,M,,*47"
    gga_parsed = parser.parse(gga)
    point = converter.to_telemetry_point(gga_parsed)

    print(f"\nTelemetryPoint from GGA:")
    print(f"  Data Type: {point.data_type}")
    print(f"  Position: {point.latitude}, {point.longitude}")
    print(f"  Altitude: {point.value} m")
    print(f"  Quality: {point.quality}")
    print(f"  Satellites: {point.satellites}")
    print(f"  Source: {point.source}")

    # Convert RMC (generates multiple points)
    rmc = "$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A"
    rmc_parsed = parser.parse(rmc)
    points = converter.to_telemetry_point(rmc_parsed)

    print(f"\nTelemetryPoints from RMC ({len(points)} points):")
    for i, p in enumerate(points, 1):
        print(f"  Point {i}: {p.data_type} = {p.value or f'{p.latitude},{p.longitude}'}")


async def example_serial_streaming() -> None:
    """Example: Stream telemetry from serial port."""
    print("\n" + "=" * 60)
    print("Example 4: Stream Telemetry from Serial Port")
    print("=" * 60)

    # Create converter
    converter = NMEAConverter(
        vessel_id=UUID("12345678-1234-1234-1234-123456789abc"),
        tenant_id=UUID("87654321-4321-4321-4321-cba987654321"),
    )

    # Create serial reader
    reader = NMEASerialReader(
        port="/dev/ttyUSB0",  # Adjust for your system
        baudrate=4800,
        converter=converter,
        skip_invalid=True,
    )

    print("\nStreaming telemetry from serial port...")
    print("(This would read from actual serial port)")

    # In real usage:
    # async with reader:
    #     async for point in reader.stream():
    #         print(f"  {point.data_type}: {point.value or f'{point.latitude},{point.longitude}'}")


async def example_serial_with_client() -> None:
    """Example: Stream from serial port to fishinfo client."""
    print("\n" + "=" * 60)
    print("Example 5: Stream to Fishinfo Client")
    print("=" * 60)

    # Setup converter
    converter = NMEAConverter(
        vessel_id=UUID("12345678-1234-1234-1234-123456789abc"),
        tenant_id=UUID("87654321-4321-4321-4321-cba987654321"),
    )

    # Create serial reader
    reader = NMEASerialReader("/dev/ttyUSB0", converter=converter)

    # Create fishinfo client
    client = Client(
        Config(
            endpoint="ingestion.vikdata.io:443",
            api_key="vk_device_xxx...",
            vessel_id="vessel-uuid-here",
        )
    )

    print("\nStreaming to fishinfo client...")
    print("(This would connect to actual serial port and API)")

    # In real usage:
    # async with reader, client:
    #     async for point in reader.stream():
    #         await client.send(point)


async def example_batched_ingestion() -> None:
    """Example: Batched ingestion from serial port."""
    print("\n" + "=" * 60)
    print("Example 6: Batched Serial Ingestion")
    print("=" * 60)

    # Setup
    converter = NMEAConverter(
        vessel_id=UUID("12345678-1234-1234-1234-123456789abc"),
        tenant_id=UUID("87654321-4321-4321-4321-cba987654321"),
    )

    reader = NMEASerialReader("/dev/ttyUSB0", converter=converter)

    client = Client(
        Config(
            endpoint="ingestion.vikdata.io:443",
            api_key="vk_device_xxx...",
            vessel_id="vessel-uuid-here",
            batch_size=100,
            flush_interval=5.0,
        )
    )

    # Create batcher
    batcher = NMEASerialBatcher(
        reader=reader,
        batch_size=100,
        flush_interval=5.0,
    )

    print("\nBatched ingestion (100 points per batch, 5s flush interval)...")
    print("(This would run continuously)")

    # In real usage:
    # await batcher.run(client)


def main() -> None:
    """Run all examples."""
    # Synchronous examples
    example_parse_nmea()
    example_decode_ais()
    example_convert_to_telemetry()

    # Async examples (would need actual serial port)
    print("\n" + "=" * 60)
    print("Async Examples (require serial port)")
    print("=" * 60)
    print("\nTo run async examples:")
    print("  asyncio.run(example_serial_streaming())")
    print("  asyncio.run(example_serial_with_client())")
    print("  asyncio.run(example_batched_ingestion())")


if __name__ == "__main__":
    main()
