"use client";

import { useEffect } from "react";
import { importLibrary } from "@googlemaps/js-api-loader";
import { GOOGLE_MAPS_KEY, SESSION_STORAGE_KEY } from "@/config/site";
import { configureGoogleMaps } from "@/lib/google-maps";
import { http } from "@/services/http";

const REPORTED_KEY = "kapitano.device-location";

function sessionMark(): string | null {
  try {
    const token = localStorage.getItem(SESSION_STORAGE_KEY);
    return token ? token.slice(-10) : null;
  } catch {
    return null;
  }
}

function alreadyAsked(mark: string): boolean {
  try {
    return localStorage.getItem(REPORTED_KEY) === mark;
  } catch {
    return true;
  }
}

function remember(mark: string) {
  try {
    localStorage.setItem(REPORTED_KEY, mark);
  } catch {
    // private mode: the browser is simply asked again next time
  }
}

/** The area the coordinates fall in, named by Google when the dashboard has a Maps key; otherwise null and the coordinates stand alone. */
async function nameThePlace(latitude: number, longitude: number): Promise<string | null> {
  if (!GOOGLE_MAPS_KEY) return null;

  try {
    configureGoogleMaps();
    await importLibrary("geocoding");
    const { results } = await new google.maps.Geocoder().geocode({ location: { lat: latitude, lng: longitude } });
    return results[0]?.formatted_address ?? null;
  } catch {
    return null;
  }
}

/**
 * Tells the back office where this device is, once per sign-in, so the sign-in history can show the real place and not only
 * where the internet connection is.
 *
 * It is the browser's own location (GPS or Wi-Fi), so the browser asks the person first; if they decline, nothing is sent and
 * the history keeps the place worked out from the IP address. Asked once per session: a refusal is not asked again until the next
 * sign-in. Renders nothing.
 */
export function DeviceLocationReporter() {
  useEffect(() => {
    const mark = sessionMark();
    if (!mark || alreadyAsked(mark) || !("geolocation" in navigator)) return;

    // Let the page settle first: a permission prompt the moment the dashboard opens competes with everything else on screen.
    const timer = window.setTimeout(() => {
      remember(mark);

      navigator.geolocation.getCurrentPosition(
        async ({ coords }) => {
          const place = await nameThePlace(coords.latitude, coords.longitude);

          try {
            await http.post("/auth/session-location", {
              latitude: coords.latitude,
              longitude: coords.longitude,
              accuracy: coords.accuracy,
              place,
            });
          } catch {
            // The history just keeps the IP's place.
          }
        },
        () => undefined,
        { enableHighAccuracy: false, timeout: 20000, maximumAge: 10 * 60 * 1000 },
      );
    }, 2500);

    return () => window.clearTimeout(timer);
  }, []);

  return null;
}
