import { UAParser } from "ua-parser-js";

export interface DeviceInfo {
  os: string;
  browser: string;
  deviceType: string;
  applicationVersion: string;
  ipAddress: string;
  location: string;
  fcmToken: string;
}

export const getDeviceInfo = async (context?: {
  userAgent?: string | null;
  ipAddress?: string | null;
  location?: string | null;
}): Promise<DeviceInfo> => {
  try {
    let userAgent = context?.userAgent || "";
    if (!userAgent && typeof window !== "undefined" && window.navigator) {
      userAgent = window.navigator.userAgent;
    }
    if (!userAgent) {
      userAgent = "NodeServer";
    }

    // In v2, we can pass the UA string directly to the constructor
    const parser = new UAParser(userAgent);
    const result = parser.getResult();

    const location = context?.location || (await getUserLocation());
    const ipAddress = context?.ipAddress || (await getUserIP());

    const info: DeviceInfo = {
      os: result.os.name || "unknown",
      browser: result.browser.name || "unknown",
      deviceType: result.device.type || "desktop", // ua-parser often returns undefined for desktop
      applicationVersion: getApplicationVersion(),
      ipAddress: ipAddress,
      location: location,
      fcmToken: "", // Console app doesn't need FCM token
    };

    return info;
  } catch (error) {
    console.error("Error fetching device info:", error);
    return {
      os: "unknown",
      browser: "unknown",
      deviceType: "desktop",
      applicationVersion: getApplicationVersion(),
      ipAddress: "unknown",
      location: "unknown",
      fcmToken: "",
    };
  }
};

const getUserLocation = async (): Promise<string> => {
  if (
    typeof window === "undefined" ||
    typeof navigator === "undefined" ||
    !navigator.geolocation
  ) {
    return "Location unavailable";
  }
  return new Promise((resolve) => {

    navigator.geolocation.getCurrentPosition(
      (position) => {
        const { latitude, longitude } = position.coords;
        resolve(`${latitude},${longitude}`);
      },
      (_error) => {
        resolve("Location unavailable");
      },
      {
        enableHighAccuracy: true,
        timeout: 5000,
        maximumAge: 0,
      },
    );
  });
};

const getUserIP = async (): Promise<string> => {
  try {
    const response = await fetch("https://api.ipify.org?format=json");
    const data = (await response.json()) as { ip?: string };
    return data.ip ?? "Unknown";
  } catch (error) {
    console.error("Failed to get IP address:", error);
    return "Unknown";
  }
};

const getApplicationVersion = (): string => {
  return import.meta.env.VITE_APP_VERSION ?? "1.0.0";
};
