import { lazy } from "react";
import type { PlimiPlugin } from "../../core/plugins/plugin-types";
import { runBackgroundRemover } from "./run";
import {
  estimateUncachedDownloadBytes,
  type BackgroundRemoverOptions,
} from "./remove";
import BgWorker from "./worker?worker";

export type { BackgroundRemoverOptions } from "./remove";

const BackgroundRemoverUi = lazy(() => import("./BackgroundRemoverUi"));

function formatMb(bytes: number): string {
  return `${(bytes / 1024 / 1024).toFixed(0)} MB`;
}

export const backgroundRemoverPlugin: PlimiPlugin<BackgroundRemoverOptions> = {
  manifest: {
    id: "background-remover",
    name: "Background Remover",
    description:
      "Remove the background from any image with AI, entirely in your browser. Your photo is never uploaded.",
    category: "image",
    version: "1.0.0",
    tags: ["image", "background", "remove", "ai", "transparent", "cutout"],
    input: {
      type: "files",
      accept: ["image/png", "image/jpeg", "image/webp"],
      multiple: false,
    },
    output: { type: "files" },
    offlineReady: true,
  },

  optionsSchema: {
    fields: [
      {
        type: "select",
        key: "quality",
        label: "Quality",
        defaultValue: "small",
        options: [
          { label: "Smallest download (quantized)", value: "small" },
          { label: "Balanced (FP16)", value: "medium" },
          { label: "Best quality (FP32)", value: "large" },
        ],
      },
      {
        type: "boolean",
        key: "useGpu",
        label: "Use GPU (WebGPU) when available",
        defaultValue: true,
      },
    ],
  },

  capabilities: {
    cancelable: false,
    worker: true,
    persistentWorker: true,
    wasm: true,
    customUi: true,
    preview: true,
  },

  getRunWarning: async (_input, options) => {
    const bytes = await estimateUncachedDownloadBytes(options, self.location.origin);
    if (bytes <= 0) return null;
    const label =
      options.quality === "small"
        ? "Smallest download"
        : options.quality === "medium"
          ? "Balanced"
          : "Best quality";
    return (
      `Running the “${label}” model needs a one-time download of about ` +
      `${formatMb(bytes)} to your device. It is cached afterwards, so future ` +
      `runs are instant and fully offline. Continue?`
    );
  },

  run: runBackgroundRemover,
  worker: () => new BgWorker(),
  customUi: BackgroundRemoverUi,
};
