"use client";
import {
  createContext,
  useState,
  useEffect,
  useCallback,
  type ReactNode,
} from "react";
import type { LocationData, LocationState, PermissionStatus } from "@/types/location";
import {
  getCurrentPosition,
  reverseGeocode,
  saveLocation,
  getSavedLocation,
  clearSavedLocation,
} from "@/services/locationService";
import { LocationPermissionModal } from "@/components/marketplace/LocationPermissionModal";

interface LocationContextType extends LocationState {
  requestLocation: () => Promise<void>;
  refreshLocation: () => Promise<void>;
  clearLocation: () => void;
  dismissModal: () => void;
}

export const LocationContext = createContext<LocationContextType | null>(null);

export function LocationProvider({ children }: { children: ReactNode }) {
  const [permission, setPermission] = useState<PermissionStatus>("prompt");
  const [location, setLocation] = useState<LocationData | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [showModal, setShowModal] = useState(false);

  const fetchLocation = useCallback(async () => {
    setIsLoading(true);
    setError(null);
    try {
      const pos = await getCurrentPosition();
      const coords = { lat: pos.coords.latitude, lng: pos.coords.longitude };
      const data = await reverseGeocode(coords);
      setLocation(data);
      setPermission("granted");
      saveLocation(data);
    } catch (err: unknown) {
      const geoErr = err as GeolocationPositionError;
      if (geoErr?.code === 1) {
        setPermission("denied");
        setError("Location access denied");
      } else if (geoErr?.code === 2) {
        setError("Location unavailable");
      } else if (geoErr?.code === 3) {
        setError("Location request timed out");
      } else {
        setError("Could not get location");
      }
    } finally {
      setIsLoading(false);
    }
  }, []);

  useEffect(() => {
    const saved = getSavedLocation();
    if (saved) {
      setLocation(saved);
      setPermission("granted");
      return;
    }

    if (typeof window === "undefined" || !("permissions" in navigator)) {
      setShowModal(true);
      return;
    }

    navigator.permissions
      .query({ name: "geolocation" })
      .then((result) => {
        if (result.state === "granted") {
          fetchLocation();
        } else if (result.state === "denied") {
          setPermission("denied");
        } else {
          setShowModal(true);
        }
      })
      .catch(() => {
        setShowModal(true);
      });
  }, [fetchLocation]);

  const requestLocation = useCallback(async () => {
    setShowModal(false);
    await fetchLocation();
  }, [fetchLocation]);

  const refreshLocation = useCallback(async () => {
    clearSavedLocation();
    await fetchLocation();
  }, [fetchLocation]);

  const clearLocation = useCallback(() => {
    clearSavedLocation();
    setLocation(null);
    setPermission("prompt");
    setError(null);
  }, []);

  const dismissModal = useCallback(() => {
    setShowModal(false);
  }, []);

  return (
    <LocationContext.Provider
      value={{
        permission,
        location,
        isLoading,
        error,
        requestLocation,
        refreshLocation,
        clearLocation,
        dismissModal,
      }}
    >
      {children}
      {showModal && (
        <LocationPermissionModal onAllow={requestLocation} onSkip={dismissModal} />
      )}
    </LocationContext.Provider>
  );
}
