import type { NativeCapability } from "./types.ts";

type ShareOptions = { title?: string; text?: string; url?: string };
type PositionOptions = globalThis.PositionOptions;

export const browserCapabilities: Record<string, NativeCapability> = {
  "clipboard.write": {
    browser: {
      supported: () => typeof navigator !== "undefined" && !!navigator.clipboard?.writeText,
      run: (options) =>
        navigator.clipboard.writeText(String((options as { text?: unknown })?.text ?? "")),
    },
  },
  share: {
    browser: {
      supported: () => typeof navigator !== "undefined" && typeof navigator.share === "function",
      run: (options) => navigator.share(options as ShareOptions),
    },
  },
  geolocation: {
    browser: {
      supported: () => typeof navigator !== "undefined" && !!navigator.geolocation,
      run: (options) =>
        new Promise((resolve, reject) =>
          navigator.geolocation.getCurrentPosition(resolve, reject, options as PositionOptions),
        ),
    },
  },
  network: {
    browser: {
      supported: () => typeof navigator !== "undefined",
      run: () => ({ connected: navigator.onLine }),
    },
  },
  camera: {
    browser: {
      supported: () => typeof navigator !== "undefined" && !!navigator.mediaDevices?.getUserMedia,
      run: (options) =>
        navigator.mediaDevices.getUserMedia({ video: options ?? true, audio: false }),
    },
  },
  "storage.get": {
    browser: {
      supported: () => typeof localStorage !== "undefined",
      run: (options) => ({
        value: localStorage.getItem(String((options as { key?: unknown })?.key ?? "")),
      }),
    },
  },
  "storage.set": {
    browser: {
      supported: () => typeof localStorage !== "undefined",
      run: (options) => {
        const value = options as { key?: unknown; value?: unknown };
        localStorage.setItem(String(value?.key ?? ""), String(value?.value ?? ""));
      },
    },
  },
  "notifications.schedule": {
    browser: {
      supported: () => typeof Notification !== "undefined",
      run: async (options) => {
        if (Notification.permission === "default") await Notification.requestPermission();
        if (Notification.permission !== "granted")
          throw new Error("Notification permission was not granted");
        const value = options as { title?: string; body?: string };
        return new Notification(value?.title ?? "Notification", { body: value?.body });
      },
    },
  },
  "device.info": {
    browser: {
      supported: () => typeof navigator !== "undefined",
      run: () => ({
        platform: "web",
        userAgent: navigator.userAgent,
        language: navigator.language,
      }),
    },
  },
  haptics: {
    browser: {
      supported: () => typeof navigator !== "undefined" && typeof navigator.vibrate === "function",
      run: (options) => navigator.vibrate((options as { duration?: number })?.duration ?? 20),
    },
  },
  "filesystem.read": {
    browser: {
      supported: () => typeof window !== "undefined" && "showOpenFilePicker" in window,
      run: async () => {
        const picker = (
          window as unknown as Window & {
            showOpenFilePicker(): Promise<Array<{ getFile(): Promise<File> }>>;
          }
        ).showOpenFilePicker;
        const [handle] = await picker.call(window);
        return handle?.getFile();
      },
    },
  },
  "filesystem.write": {
    browser: {
      supported: () => typeof window !== "undefined" && "showSaveFilePicker" in window,
      run: async (options) => {
        const picker = (
          window as unknown as Window & {
            showSaveFilePicker(): Promise<{
              createWritable(): Promise<{
                write(value: unknown): Promise<void>;
                close(): Promise<void>;
              }>;
            }>;
          }
        ).showSaveFilePicker;
        const writable = await (await picker.call(window)).createWritable();
        await writable.write((options as { data?: unknown })?.data ?? "");
        await writable.close();
      },
    },
  },
};
