/**
 * Location utilities for geolocation and address resolution
 */

export interface LocationData {
  latitude: number;
  longitude: number;
  address: string;
}

export interface GeolocationError {
  code: number;
  message: string;
}

/**
 * Get current position using browser geolocation API
 */
export const getCurrentPosition = (): Promise<GeolocationPosition> => {
  return new Promise((resolve, reject) => {
    if (!navigator.geolocation) {
      reject({
        code: 0,
        message: "Geolocation is not supported by this browser",
      });
      return;
    }

    const options: PositionOptions = {
      enableHighAccuracy: true,
      timeout: 15000, // 15 seconds
      maximumAge: 300000, // 5 minutes
    };

    navigator.geolocation.getCurrentPosition(
      (position) => resolve(position),
      (error) => {
        let message = "Unknown error occurred";

        switch (error.code) {
          case error.PERMISSION_DENIED:
            message =
              "Location access is required to submit this activity. Please enable location services.";
            break;
          case error.POSITION_UNAVAILABLE:
            message = "Location information is unavailable. Please try again.";
            break;
          case error.TIMEOUT:
            message = "Location request timed out. Please try again.";
            break;
        }

        reject({
          code: error.code,
          message,
        });
      },
      options
    );
  });
};

/**
 * Get address from coordinates using Google Reverse Geocoding API
 */
export const getAddressFromCoordinates = async (
  latitude: number,
  longitude: number
): Promise<string> => {
  try {
    const apiKey = process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY;

    if (!apiKey) {
      console.warn("Google Maps API key not found");
      return "";
    }

    const response = await fetch(
      `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&key=${apiKey}`
    );

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();

    if (data.status === "OK" && data.results && data.results.length > 0) {
      return data.results[0].formatted_address;
    } else {
      console.warn("No address found for coordinates:", data.status);
      return `${latitude.toFixed(6)}, ${longitude.toFixed(6)}`;
    }
  } catch (error) {
    console.error("Error fetching address:", error);
    // Return coordinates as fallback
    return `${latitude.toFixed(6)}, ${longitude.toFixed(6)}`;
  }
};

/**
 * Get complete location data (coordinates + address)
 */
export const getLocationData = async (): Promise<LocationData> => {
  try {
    // Get coordinates
    const position = await getCurrentPosition();
    const { latitude, longitude } = position.coords;

    return {
      latitude,
      longitude,
      address: "",
    };
  } catch (error) {
    throw error;
  }
};

/**
 * Check if location permission is granted
 */
export const checkLocationPermission = async (): Promise<PermissionState> => {
  if (!navigator.permissions) {
    return "prompt"; // Assume prompt if permissions API not available
  }

  try {
    const permission = await navigator.permissions.query({
      name: "geolocation",
    });
    return permission.state;
  } catch (error) {
    console.warn("Error checking location permission:", error);
    return "prompt";
  }
};
