"""Publish sample locate points to the UlHub backend via MQTT.

The backend subscribes to devices/# and expects points at
devices/{mqttUsername}/points with a JSON body:

    {"serial": "...", "ticket": "TKT-...",
     "points": [{"lat": .., "lng": .., "ts": "ISO8601", ...}]}

The MQTT username identifies the publisher (app/gateway) and its org; "serial"
names the locator receiver the readings came from (auto-registered on first
sight). Points for an unknown ticket auto-create a stub job (source=DEVICE).
"""

import random

import json
import os
import time
from datetime import datetime, timezone

import paho.mqtt.client as mqtt

BROKER_HOST = os.getenv("MQTT_HOST", "127.0.0.1")
BROKER_PORT = int(os.getenv("MQTT_PORT", "1883"))
USERNAME = os.getenv("MQTT_USERNAME", "testuser")
PASSWORD = os.getenv("MQTT_PASSWORD", "testpass")
SERIAL = os.getenv("SERIAL", "DEMO-0001")
TICKET = os.getenv("TICKET", "TKT-2026-0001")
INTERVAL = float(os.getenv("MQTT_INTERVAL", "2"))

# Walk northeast from this location, one point per interval
START_LAT = float(os.getenv("START_LAT", "33.15012345"))
START_LNG = float(os.getenv("START_LNG", "-96.83512345"))

TOPIC = f"devices/{USERNAME}/points"

client = mqtt.Client()
client.username_pw_set(USERNAME, PASSWORD)
client.connect(BROKER_HOST, BROKER_PORT, 60)
client.loop_start()

try:
    seq = 0
    while True:
        payload = {
            "serial": SERIAL,
            "ticket": TICKET,
            "points": [
                {
                    "lat": START_LAT + seq * 0.0000135,
                    "lng": START_LNG + seq * 0.0000042,
                    "alt": 187.4 + seq * 0.02,
                    "fix": "FIXED_RTK",
                    "hAcc": 0.014,
                    "vAcc": 0.021,
                    "sats": random.randint(18, 26),
                    "hdop": 0.7,
                    "depth": round(1.1 + random.uniform(0, 0.3), 2),
                    "freqHz": 33000,
                    "currentMa": round(50 - seq * 0.4 + random.uniform(-1, 1), 1),
                    "signalDb": round(62 - seq * 0.2 + random.uniform(-0.5, 0.5), 1),
                    "gainDb": 40,
                    "mode": "PEAK",
                    "compassDeg": round(17.5 + random.uniform(-3, 3), 1),
                    "distortionPct": round(random.uniform(2, 8), 1),
                    "utility": "GAS",
                    "seq": seq + 1,
                    "ts": datetime.now(timezone.utc).isoformat(),
                }
            ],
        }
        client.publish(TOPIC, json.dumps(payload), qos=1)
        print(f"published point {seq + 1} to {TOPIC} (ticket {TICKET})")
        seq += 1
        time.sleep(INTERVAL)
except KeyboardInterrupt:
    print("stopped")
finally:
    client.loop_stop()
    client.disconnect()
