interface CopyLinkHook extends ViewHook {
  el: HTMLElement
}

export const CopyLink = {
  mounted(this: CopyLinkHook): void {
    this.el.addEventListener("click", () => {
      navigator.clipboard.writeText(window.location.href).then(() => {
        const orig = this.el.innerHTML
        this.el.innerHTML = '<span class="text-success">Copied!</span>'
        setTimeout(() => { this.el.innerHTML = orig }, 1500)
      })
    })
  }
}

interface LocateMeHook extends ViewHook {
  el: HTMLElement
  watchId: number | null
  lastSentAt: number
  startWatching(): void
}

export const LocateMe = {
  mounted(this: LocateMeHook): void {
    this.watchId = null
    this.lastSentAt = 0

    this.el.addEventListener("click", () => this.startWatching())

    // Also respond to server-pushed request (for source=gps URLs)
    this.handleEvent("request_gps", () => this.startWatching())
  },

  destroyed(this: LocateMeHook): void {
    if (this.watchId !== null) {
      navigator.geolocation.clearWatch(this.watchId)
    }
  },

  startWatching(this: LocateMeHook): void {
    if (!navigator.geolocation) {
      alert("Geolocation is not supported by this browser")
      return
    }

    // Already watching — don't start another
    if (this.watchId !== null) return

    this.el.classList.add("loading", "loading-spinner")

    this.watchId = navigator.geolocation.watchPosition(
      (pos: GeolocationPosition) => {
        const now = Date.now()
        // Send immediately on first fix, then at most once per minute
        if (this.lastSentAt === 0 || now - this.lastSentAt >= 60000) {
          this.lastSentAt = now
          this.el.classList.remove("loading", "loading-spinner")
          this.pushEvent("gps_location", {
            lat: pos.coords.latitude,
            lon: pos.coords.longitude
          })
        }
      },
      (err: GeolocationPositionError) => {
        this.el.classList.remove("loading", "loading-spinner")
        navigator.geolocation.clearWatch(this.watchId!)
        this.watchId = null
        alert("Could not get location: " + err.message)
      },
      { enableHighAccuracy: true, timeout: 10000 }
    )
  }
}
