/**
 * Metadata for a client-side component used within a ZX file.
 * 
 * This type represents the metadata for components that are marked with the `@rendering` attribute
 * in ZX files. When a component is declared with `@rendering={.react}` or `@rendering={.client}` in a
 * `.zx` file, the ZX transpiler generates a `ComponentMetadata` entry that is included in the
 * generated `components` array.
 * 
 * @example
 * ```tsx
 * // In a ZX file (page.zx):
 * <CounterComponent @rendering={.react} max_count={10} />
 * 
 * // Generated components array (components.ts):
 * export const components: ComponentMetadata[] = [
 *   {
 *     name: "CounterComponent",
 *     path: "./components/CounterComponent.tsx",
 *     id: "zx-dcde04c415da9d1b15ca2690d8b497ae",
 *     type: "react",
 *     import: () => import('./components/CounterComponent.tsx')
 *   }
 * ];
 * ```
 * 
 * @example
 * ```tsx
 * // Using ComponentMetadata with prepareComponent:
 * import { prepareComponent, type ComponentMetadata } from "ziex";
 * 
 * for (const component of components) {
 *   const { domNode, props, Component } = await prepareComponent(component);
 *   // Render component to DOM node
 * }
 * ```
 */
export type ComponentMetadata = {
  /**
   * The name of the component as declared in the ZX file.
   * 
   * This is the tag name used in JSX syntax within `.zx` files. It corresponds to the component
   * identifier used in the component declaration (e.g., `<CounterComponent />`).
   * 
   * @example
   * ```tsx
   * // In ZX file:
   * <CounterComponent @rendering={.react} />
   * 
   * // name will be: "CounterComponent"
   * ```
   */
  name: string;
  
  /**
   * The file path to the component module.
   * 
   * This is the relative or absolute path to the component file that will be dynamically imported
   * at runtime. For CSR components, this typically points to a `.tsx` or `.jsx` file. For Client
   * components, this points to a Zig component file.
   * 
   * The path is determined from the `@jsImport` directive in the ZX file, or defaults to
   * `./{componentName}.tsx` if not explicitly specified.
   * 
   * @example
   * ```tsx
   * // In ZX file:
   * const CounterComponent = @jsImport("components/Counter.tsx");
   * <CounterComponent @rendering={.react} />
   * 
   * // path will be: "components/Counter.tsx"
   * ```
   * 
   * @example
   * ```tsx
   * // Without explicit @jsImport:
   * <MyComponent @rendering={.react} />
   * 
   * // path will default to: "./MyComponent.tsx"
   * ```
   */
  path: string;

  /**
   * The route of of the component in which page the component was used,
   * null in case the component was used in other non-page/layout context.
   * ```
   */
  route: string | null;
  
  /**
   * A unique identifier for the component's hydration boundary.
   * 
   * This ID is generated by hashing the component's path and name using MD5, then formatting it
   * as a hex string with the "zx-" prefix and a counter suffix. The ID is used to locate the
   * component's comment markers in the DOM during client-side hydration.
   * 
   * The ID format is: `zx-{32 hex characters}-{counter}` (e.g., `zx-dcde04c415da9d1b15ca2690d8b497ae-0`)
   * 
   * The ZX runtime renders components with comment markers in the format:
   * `<!--$id name props-->...<!--/$id-->`
   * 
   * @example
   * ```tsx
   * // Component metadata:
   * {
   *   name: "CounterComponent",
   *   path: "./components/Counter.tsx",
   *   id: "zx-dcde04c415da9d1b15ca2690d8b497ae-0"
   * }
   * 
   * // Generated HTML with comment markers:
   * <!--$zx-dcde04c415da9d1b15ca2690d8b497ae-0 CounterComponent {"max_count":10}-->
   * <button>0</button>
   * <!--/$zx-dcde04c415da9d1b15ca2690d8b497ae-0-->
   * ```
   */
  id: string;
  
  /**
   * The rendering type of the component, determining how it will be rendered on the client.
   * 
   * - **"react"** (Client Side React): The component is a React component that will be rendered
   *   using React's client-side rendering. The component file should export a default React
   *   component function. This is the most common type for interactive UI components.
   * 
   * - **"client"** (Client Side Zig): The component is a Zig component that will be compiled to
   *   WebAssembly and rendered on the client side. This allows you to use Zig's performance
   *   and type safety for client-side components.
   * 
   * The type is determined by the `@rendering` attribute value in the ZX file (`.react` or `.client`).
   * 
   * @example
   * ```tsx
   * // CSR component (React):
   * <CounterComponent @rendering={.react} max_count={10} />
   * // type: "react"
   * 
   * // Component file (CounterComponent.tsx):
   * export default function CounterComponent({ max_count }: { max_count: number }) {
   *   return <div>Count: {max_count}</div>;
   * }
   * ```
   * 
   * @example
   * ```tsx
   * // Client component (Zig/WASM):
   * <CounterComponent @rendering={.client} />
   * // type: "client"
   * 
   * // Component file (CounterComponent.zig):
   * pub fn CounterComponent(allocator: zx.Allocator) zx.Component {
   *   return (<div @allocator={allocator}>Counter</div>);
   * }
   * ```
   */
  type: "react" | "client";
  
  /**
   * A lazy-loading function that dynamically imports the component module.
   * 
   * This function returns a Promise that resolves to the component function. It enables
   * code-splitting and lazy loading of components, improving initial page load performance
   * by only loading components when they are needed.
   * 
   * For CSR components, the imported module should export a default React component.
   * For Client components, the import mechanism depends on the WASM module structure.
   * 
   * The function is called during client-side hydration to load and render the component
   * into its corresponding DOM container element.
   * 
   * @returns A Promise that resolves to a component function that accepts props and returns a React element.
   * 
   * @example
   * ```tsx
   * // Component metadata:
   * {
   *   import: () => import('./components/CounterComponent.tsx')
   * }
   * 
   * // Usage:
   * const Component = await component.import();
   * // Component is now the default export from CounterComponent.tsx
   * ```
   * 
   * @example
   * ```tsx
   * // With prepareComponent helper:
   * import { prepareComponent } from "ziex";
   * 
   * const { Component, props, domNode } = await prepareComponent(component);
   * // Component is loaded and ready to render with props
   * ```
   */
  import: () => Promise<(props: any) => React.ReactElement>;
};
