import { useEffect, useState, useCallback } from 'react'
import { api, endpoints } from '../../api'
import type {
  GpsDeviceResponse,
  GpsDeviceSettings,
  GpsDeviceTelemetry,
} from '../../types'

type Status = 'idle' | 'loading' | 'ready' | 'saving' | 'pinging' | 'reconnecting' | 'error'

// Factory defaults — UI stays interactive when GET fails (no backend).
const FACTORY_GPS_SETTINGS: GpsDeviceSettings = {
  address: '192.168.1.100',
  port: 9001,
  protocol: 'NMEA',
}

export function useGpsSettings() {
  const [draft, setDraft] = useState<GpsDeviceSettings>(FACTORY_GPS_SETTINGS)
  const [persisted, setPersisted] = useState<GpsDeviceSettings>(FACTORY_GPS_SETTINGS)
  const [telemetry, setTelemetry] = useState<GpsDeviceTelemetry | null>(null)
  const [status, setStatus] = useState<Status>('idle')
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    let cancelled = false
    setStatus('loading')
    api.get<GpsDeviceResponse>(endpoints.admin.gpsSettings())
      .then(res => {
        if (cancelled) return
        setDraft(res.settings)
        setPersisted(res.settings)
        setTelemetry(res.telemetry)
        setStatus('ready')
      })
      .catch(() => {
        if (cancelled) return
        setStatus('error')
        setError('Failed to load GPS settings')
      })
    return () => { cancelled = true }
  }, [])

  const save = useCallback(async () => {
    setStatus('saving')
    setError(null)
    try {
      const res = await api.patch<GpsDeviceResponse>(endpoints.admin.gpsSettings(), draft)
      setDraft(res.settings)
      setPersisted(res.settings)
      setTelemetry(res.telemetry)
      setStatus('ready')
    } catch {
      setStatus('error')
      setError('Failed to save GPS settings')
    }
  }, [draft])

  const ping = useCallback(async () => {
    setStatus('pinging')
    setError(null)
    try {
      await api.post(endpoints.admin.gpsPing(), {})
      setStatus('ready')
    } catch {
      setStatus('error')
      setError('Ping failed')
    }
  }, [])

  const reconnect = useCallback(async () => {
    setStatus('reconnecting')
    setError(null)
    try {
      const res = await api.post<GpsDeviceResponse>(endpoints.admin.gpsReconnect(), {})
      setTelemetry(res.telemetry)
      setStatus('ready')
    } catch {
      setStatus('error')
      setError('Reconnect failed')
    }
  }, [])

  const reset = useCallback(() => {
    setDraft(persisted)
  }, [persisted])

  return { draft, setDraft, telemetry, status, error, save, ping, reconnect, reset } as const
}
