import type * as __ManduBunTypes0 from "bun";
import type * as __ManduPluginsHooksTypes1 from "../plugins/hooks";
/**
 * Mandu Bundler Types
 */

/**
 * 번들 빌드 결과
 */
export interface BundleResult {
  success: boolean;
  outputs: BundleOutput[];
  errors: string[];
  manifest: BundleManifest;
  stats: BundleStats;
}

/**
 * 개별 번들 출력
 */
export interface BundleOutput {
  /** 라우트 ID */
  routeId: string;
  /** 원본 엔트리포인트 */
  entrypoint: string;
  /** 출력 경로 (서버 기준) */
  outputPath: string;
  /** 파일 크기 (bytes) */
  size: number;
  /** gzip 압축 크기 (bytes) */
  gzipSize: number;
}

/**
 * 번들 매니페스트
 */
export interface BundleManifest {
  /** 매니페스트 버전 */
  version: number;
  /** 빌드 시간 */
  buildTime: string;
  /** 환경 */
  env: "development" | "production";
  /** 라우트별 번들 정보 */
  bundles: Record<
    string,
    {
      /** JavaScript 번들 경로 */
      js: string;
      /** CSS 번들 경로 (있는 경우) */
      css?: string;
      /** 의존하는 공유 청크 */
      dependencies: string[];
      /** Hydration 우선순위 */
      priority: "immediate" | "visible" | "idle" | "interaction";
    }
  >;
  /** Per-island bundles (code splitting: each island file gets its own JS bundle) */
  islands?: Record<
    string,
    {
      /** JavaScript bundle path */
      js: string;
      /** Route that owns this island */
      route: string;
      /** Hydration priority */
      priority: "immediate" | "visible" | "idle" | "interaction";
    }
  >;
  /** Inline partial bundles (from *.partial.tsx / *.partial.ts files) */
  partials?: Record<
    string,
    {
      /** JavaScript bundle path */
      js: string;
      /** Hydration priority */
      priority: "immediate" | "visible" | "idle" | "interaction";
    }
  >;
  /** Compiler-owned client boundary bundles keyed by boundary id. */
  boundaries?: Record<
    string,
    {
      /** Owning route id */
      route: string;
      /** JavaScript bundle path */
      js: string;
      /** Source client module */
      module: string;
      /** Client export name */
      exportName: string;
      /** Hydration priority */
      priority: "immediate" | "visible" | "idle" | "interaction";
      /** Hydration mode emitted into data-hydrate */
      hydrate: string;
    }
  >;
  /** 공유 청크 */
  shared: {
    /** Hydration 런타임 */
    runtime: string;
    /** React 번들 경로 */
    vendor: string;
    /** Client-side Router 런타임 */
    router?: string;
    /**
     * Phase 7.1 B-2: dev-only Fast Refresh assets. Absent in prod
     * manifests so the HTML preamble short-circuits without trying to
     * load a nonexistent URL.
     */
    fastRefresh?: {
      /** Bundled `react-refresh/runtime` (e.g. `/.mandu/client/_vendor-react-refresh.js`). */
      runtime: string;
      /** Mandu's glue module exposing `installGlobal` / `__MANDU_HMR__`. */
      glue: string;
    };
  };
  /** Import map for bare specifiers (react, react-dom, etc.) */
  importMap?: {
    imports: Record<string, string>;
  };
}

/**
 * 번들 통계
 */
export interface BundleStats {
  /** 전체 크기 */
  totalSize: number;
  /** 전체 gzip 크기 */
  totalGzipSize: number;
  /** 가장 큰 번들 */
  largestBundle: {
    routeId: string;
    size: number;
  };
  /** 빌드 시간 (ms) */
  buildTime: number;
  /** 번들 수 */
  bundleCount: number;
}

/** Per-island code splitting entry (used by scanIslandFiles) */
export interface IslandFileEntry {
  name: string;
  filePath: string;
  routeId: string;
  priority: "immediate" | "visible" | "idle" | "interaction";
}

/** Inline partial bundle entry (used by scanPartialFiles) */
export interface PartialFileEntry {
  name: string;
  filePath: string;
  priority: "immediate" | "visible" | "idle" | "interaction";
}

/**
 * 번들러 옵션
 */
export interface BundlerOptions {
  /**
   * Build mode. This controls development-only transforms such as React
   * Fast Refresh independently from minification.
   */
  mode?: "development" | "production";
  /** 코드 압축 여부 (기본: production에서 true) */
  minify?: boolean;
  /** 소스맵 생성 여부 */
  sourcemap?: boolean;
  /** 파일 감시 모드 */
  watch?: boolean;
  /** 출력 디렉토리 (기본: .mandu/client) */
  outDir?: string;
  /** 외부 모듈 (번들에서 제외) */
  external?: string[];
  /** 환경 변수 주입 */
  define?: Record<string, string>;
  /**
   * 코드 스플리팅 활성화
   * - true: Island들 간 공통 코드를 별도 청크로 추출 (캐시 효율 향상)
   * - false: 각 Island가 독립 번들로 생성 (기본값)
   *
   * 주의: splitting=true인 경우 청크 파일 관리가 필요합니다.
   */
  splitting?: boolean;
  /**
   * 빌드할 Island routeId 목록 (부분 빌드용, #122)
   * - 지정 시 해당 Island만 재빌드 (Runtime/Router/Vendor 스킵)
   * - 미지정 시 전체 빌드 (기본값)
   */
  targetRouteIds?: string[];
  /**
   * Framework-internal 번들 (runtime/router/vendor/devtools) 스킵 (#185)
   * - true: 사용자 island만 재빌드, runtime/router/vendor/devtools 출력은 기존 매니페스트에서 재사용
   * - 주 용도: 공통 디렉토리(src/shared 등) 파일 변경 시 dev watcher가 수행하는 rebuild.
   *   사용자 코드 변경은 framework 번들 출력에 영향을 주지 않으므로 재빌드 불필요.
   * - 안전성: 기존 `.mandu/manifest.json` 이 없으면 자동으로 full build로 fallback.
   */
  skipFrameworkBundles?: boolean;
  /**
   * Issue #207 — opt-out for the `mandu:block-generated-imports` bundler
   * plugin. Default `true` (plugin installed on every build). Set
   * `false` to skip installation — mirrors
   * `ManduConfig.guard.blockGeneratedImport`. CLI callers pass the
   * resolved config flag straight through.
   */
  blockGeneratedImport?: boolean;

  /**
   * Issue #240 — React Compiler opt-in. When `enabled: true` the
   * bundler's client-path invocations install
   * `mandu:react-compiler` (Babel + `babel-plugin-react-compiler`)
   * on every `.jsx`/`.tsx` file. SSR-only builds ignore this —
   * memoization has no effect on a one-shot HTML render.
   */
  reactCompiler?: {
    enabled?: boolean;
    compilerConfig?: Record<string, unknown>;
  };

  /**
   * Phase 18.τ — consumer-supplied `BunPlugin`s contributed via plugin
   * `defineBundlerPlugin()` hook. Composed AFTER Mandu's defaults so
   * user transforms see already-resolved imports. Omitted / empty
   * array is a zero-overhead passthrough.
   *
   * Resolved by the CLI (`cli/commands/build.ts`, `cli/commands/dev.ts`)
   * via `runDefineBundlerPlugin()` and fed into every `safeBuild(...)`
   * call-site; library users may populate it directly.
   */
  pluginBundlerPlugins?: readonly __ManduBunTypes0.BunPlugin[];

  /**
   * Phase 18.τ — fire per-build `onBundleComplete(stats)` hook after
   * `buildClientBundles()` finishes. Paired with `configHooks` for
   * config-level hooks. Zero-overhead when both are omitted.
   */
  plugins?: readonly __ManduPluginsHooksTypes1.ManduPlugin[];
  configHooks?: Partial<__ManduPluginsHooksTypes1.ManduHooks>;
}
