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

type Plugin = Record<string, (...args: unknown[]) => unknown>;

function plugin(name: string): Plugin | undefined {
  const root = globalThis as typeof globalThis & {
    Capacitor?: { Plugins?: Record<string, Plugin> };
  };
  return root.Capacitor?.Plugins?.[name];
}

function capacitorAdapter(pluginName: string, method: string): NativeCapability["mobile"] {
  return {
    supported: () => typeof plugin(pluginName)?.[method] === "function",
    run: (options) => plugin(pluginName)![method]!(options),
  };
}

function transformedCapacitorAdapter(
  pluginName: string,
  method: string,
  transform: (options: unknown) => unknown,
): NativeCapability["mobile"] {
  return {
    supported: () => typeof plugin(pluginName)?.[method] === "function",
    run: (options) => plugin(pluginName)![method]!(transform(options)),
  };
}

export const mobileCapabilities: Record<string, NativeCapability> = {
  camera: { mobile: capacitorAdapter("Camera", "getPhoto") },
  "clipboard.write": {
    mobile: transformedCapacitorAdapter("Clipboard", "write", (options) => {
      const value = options as { text?: unknown; string?: unknown };
      return { string: String(value?.text ?? value?.string ?? "") };
    }),
  },
  share: { mobile: capacitorAdapter("Share", "share") },
  geolocation: { mobile: capacitorAdapter("Geolocation", "getCurrentPosition") },
  network: { mobile: capacitorAdapter("Network", "getStatus") },
  haptics: { mobile: capacitorAdapter("Haptics", "impact") },
  "storage.get": { mobile: capacitorAdapter("Preferences", "get") },
  "storage.set": { mobile: capacitorAdapter("Preferences", "set") },
  "filesystem.read": { mobile: capacitorAdapter("Filesystem", "readFile") },
  "filesystem.write": { mobile: capacitorAdapter("Filesystem", "writeFile") },
  "notifications.schedule": {
    mobile: transformedCapacitorAdapter("LocalNotifications", "schedule", (options) => {
      const value = options as {
        notifications?: unknown[];
        id?: number;
        title?: string;
        body?: string;
        schedule?: unknown;
      };
      if (value?.notifications) return value;
      return {
        notifications: [
          {
            id: value?.id ?? Date.now() % 2_147_483_647,
            title: value?.title ?? "Notification",
            body: value?.body ?? "",
            schedule: value?.schedule,
          },
        ],
      };
    }),
  },
  "device.info": { mobile: capacitorAdapter("Device", "getInfo") },
};
