import { fileURLToPath } from "node:url";
import type { PluginOption } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import { tanstackRouter } from "@tanstack/router-plugin/vite";
import executorVitePlugin from "@executor-js/vite-plugin";

import { routes } from "./tsr.routes.ts";

const APP_ROOT = fileURLToPath(new URL("./", import.meta.url));

interface AppPluginOptions {
  /**
   * Absolute path to the `executor.config.ts` whose plugin list should
   * feed `virtual:executor/plugins-client`. The Vite root for this app
   * is `packages/app/` which has no executor.config, so consumers must
   * point this at their own (typically `apps/local/executor.config.ts`).
   *
   * If omitted, no plugin UIs get bundled — the renderer still works
   * for built-in pages but Sources / Connections / etc. plugin pages
   * stay empty.
   */
  readonly executorConfigPath?: string;
  /** Absolute path to `executor.jsonc`. Optional companion to executorConfigPath. */
  readonly executorJsoncPath?: string;
}

/**
 * Vite plugin bundle for the executor React app.
 *
 * Layered into apps/local's vite config (web build) and apps/desktop's
 * electron.vite renderer config. Consumers must pass `executorConfigPath`
 * so plugin client bundles get included — see option docs above.
 *
 * Does NOT include consumer-specific defines (VITE_APP_VERSION etc.) or
 * server-side middleware (api/mcp). Consumers layer those on top.
 */
export default function appPlugin(options: AppPluginOptions = {}): PluginOption[] {
  return [
    {
      name: "executor-app:config",
      config() {
        return {
          resolve: {
            alias: {
              "@executor-app": APP_ROOT,
            },
            dedupe: ["react", "react-dom"],
          },
        };
      },
    },
    tailwindcss(),
    executorVitePlugin({
      ...(options.executorConfigPath ? { configPath: options.executorConfigPath } : {}),
      ...(options.executorJsoncPath ? { jsoncPath: options.executorJsoncPath } : {}),
    }),
    tanstackRouter({
      target: "react",
      autoCodeSplitting: true,
      routesDirectory: fileURLToPath(new URL("./src/routes", import.meta.url)),
      generatedRouteTree: fileURLToPath(new URL("./src/routeTree.gen.ts", import.meta.url)),
      // The route tree definition lives in tsr.routes.ts (shared with
      // packages/react's routes:gen so a CLI regen matches dev/build).
      virtualRouteConfig: routes,
    }),
    ...react(),
  ];
}
