import { ClassValue as ClassValue$1 } from 'clsx';

/**
 * Represents the `class` and `className` props for `cva` and `sva`.
 * Ensures that only one of `class` or `className` is present.
 */
type ClassProp = {
    class?: ClassValue;
    className?: never;
} | {
    class?: never;
    className?: ClassValue;
};
/**
 * **This is the `ClassValue` type from [clsx](https://github.com/lukeed/clsx/tree/master)**.
 * - Represents a value that can be used as a class name.
 * - It can be a `string`, `number`, `bigint`, `null`, `boolean`, `undefined`, an array of ClassValue, or a Record with values of `any`.
 */
type ClassValue = ClassValue$1;
/**
 * Represents a function that merges class names.
 *
 * @param {...ClassValue[]} classes - An array of class names to merge.
 * @returns {string} The merged class name string.
 */
type MergeClassFn = (...classes: ClassValue[]) => string;
/**
 * Represents a dictionary where keys are strings and values are ClassValue.
 */
type RecordClassValue = Record<string, ClassValue>;
/**
 * Converts "true" or "false" string literals to boolean types.
 * Otherwise, returns the original type.
 *
 * @template T - The type to convert.
 * @returns {T extends "true" | "false" ? boolean : T} The converted type.
 */
type StringToBoolean<T> = T extends "true" | "false" ? boolean : T;
/**
 * Represents the variant configurations for `cva`.
 * Each variant is a record of class names, keyed by variant values.
 *
 * @example
 * ```ts
 * {
 *   size: {
 *     small: "text-sm py-1 px-2",
 *     medium: "text-base py-2 px-4",
 *   },
 *   intent: {
 *     primary: "bg-blue-500 text-white",
 *     secondary: "bg-gray-200 text-gray-800",
 *   }
 * }
 * ```
 */
type Variant = Record<string, RecordClassValue>;
/**
 * Represents the schema for variant props in `cva`.
 * Each variant prop is typed as a StringToBoolean of the corresponding variant value keys.
 *
 * @template V - The type of variants.
 * @example
 * ```ts
 * type ButtonVariants = CVAVariants<{
 *   size: { small: string; medium: string };
 *   intent: { primary: string; secondary: string };
 * }>;
 * // ButtonVariants = { size?: "small" | "medium"; intent?: "primary" | "secondary" };
 * ```
 */
type CVAVariants<V extends Variant> = {
    [K in keyof V]?: StringToBoolean<keyof V[K]>;
};
/**
 * Represents the configuration object for the `cva` function.
 *
 * @template V - The type of variants.
 * @property {string=} name - Optional component name.
 * @property {ClassValue=} base - The base class name for the component.
 * @property {V=} variants - Variants allow you to create multiple versions of the same component.
 * @property {(V extends Variant ? (CVAVariants<V> | { [K in keyof V]?: StringToBoolean<keyof V[K]> | StringToBoolean<keyof V[K]>[]; }) & ClassProp : ClassProp)[]=} compoundVariants - Compound variants allow you to apply classes to multiple variants at once.
 * @property {CVAVariants<V>=} defaultVariants - Default variants allow you to set default variants for a component.
 *
 * @example
 * ```ts
 * const buttonConfig: CVAConfig<{
 *   size: { small: string; medium: string };
 *   intent: { primary: string; secondary: string };
 * }> = {
 *   base: "rounded-md",
 *   variants: {
 *     size: {
 *       small: "text-sm",
 *       medium: "text-base"
 *     },
 *     intent: {
 *       primary: "bg-blue-500",
 *       secondary: "bg-gray-200"
 *     }
 *   },
 *   compoundVariants: [
 *     {
 *       size: "small",
 *       intent: "primary",
 *       class: "font-bold"
 *     }
 *   ],
 *   defaultVariants: {
 *     size: "medium",
 *     intent: "primary"
 *   }
 * };
 * ```
 */
type CVAConfig<V extends Variant> = {
    /**
     * The name of the cva component.
     */
    name?: string;
    /**
     * The base class name for the component.
     */
    base?: ClassValue;
    /**
     * Variants allow you to create multiple versions of the same component.
     */
    variants?: V;
    /**
     * Compound variants allow you to apply classes to multiple variants at once.
     */
    compoundVariants?: (V extends Variant ? (CVAVariants<V> | {
        [K in keyof V]?: StringToBoolean<keyof V[K]> | StringToBoolean<keyof V[K]>[];
    }) & ClassProp : ClassProp)[];
    /**
     * Default variants allow you to set default variants for a component.
     */
    defaultVariants?: CVAVariants<V>;
};
/**
 * Represents the class values for slots, where keys are slot names and values are class names.
 *
 * @template RCV - The type of record class values.
 * @example
 * ```ts
 * type ButtonSlots = SlotsClassValue<{ root: string; item: string }>;
 * // ButtonSlots = { root?: ClassValue; item?: ClassValue };
 * ```
 */
type SlotsClassValue<RCV extends RecordClassValue> = {
    [K in keyof RCV]?: ClassValue;
};
/**
 * Represents the default variants for a component.
 *
 * @template RCV - The type of record class values.
 * @example
 * ```ts
 * {
 *   size: {
 *     small: {
 *       root: "text-sm"
 *     },
 *     medium: {
 *       root: "text-base"
 *     }
 *   }
 * }
 * ```
 */
type DefaultVariants<RCV extends RecordClassValue> = {
    [key: string]: {
        [key: string]: SlotsClassValue<RCV>;
    };
};
/**
 * Represents the variants for a component.
 *
 * @template RCV - The type of record class values.
 * @template V - The type of variants.
 * @example
 * ```ts
 * type ButtonVariants = Variants<
 *   {
 *     root: string;
 *     item: string;
 *   },
 *   {
 *     size: {
 *       small: {
 *         root: string;
 *       };
 *       medium: {
 *         root: string;
 *       };
 *     };
 *   }
 * >;
 * // type ButtonVariants =
 * // | { size?: { small?: { root?: ClassValue }; medium?: { root?: ClassValue } } }
 * // | { size: { small: { root: ClassValue }; medium: { root: ClassValue } } };
 * ```
 */
type Variants<RCV extends RecordClassValue, V extends DefaultVariants<RCV> = DefaultVariants<RCV>> = {
    [K in keyof V]?: {
        [K2 in keyof V[K]]?: SlotsClassValue<RCV>;
    };
} | DefaultVariants<RCV>;
/**
 * Reusable type for compound styles that apply based on multiple variant combinations.
 *
 * @template RCV - The type of record class values.
 * @template V - The type of variants.
 * @example
 * ```ts
 * type ButtonCompound = CompoundBase<
 *   { root: string; item: string },
 *   { size: { small: { root: string }; medium: { root: string } } }
 * >;
 * // ButtonCompound = { size?: "small" | "medium" | ("small" | "medium")[] };
 * ```
 */
type CompoundBase<RCV extends RecordClassValue, V extends Variants<RCV>> = {
    [K in keyof V]?: StringToBoolean<keyof V[K]> | StringToBoolean<keyof V[K]>[];
};
/**
 * Represents the props for a component with variants and slots.
 *
 * @template RCV - The type of record class values.
 * @template V - The type of variants.
 * @example
 * ```ts
 * type ButtonProps = SVAVariants<
 *   { root: string; item: string },
 *   { size: { small: { root: string }; medium: { root: string } } }
 * >;
 * // ButtonProps = { size?: "small" | "medium" };
 * ```
 */
type SVAVariants<RCV extends RecordClassValue, V extends Variants<RCV>> = {
    [K in keyof V]?: StringToBoolean<keyof V[K]>;
};
/**
 * Represents the configuration object for the `sva` function.
 *
 * @template RCV - The type of record class values.
 * @template V - The type of variants.
 * @property {string=} name - Optional component name.
 * @property {S=} slots - Slots allow you to separate a component into multiple parts.
 * @property {V=} variants - Variants allow you to create multiple versions of the same component.
 * @property {Array<CompoundBase<RCV, V> & ( { class?: SlotsClassValue<RCV>; className?: never; } | { class?: never; className?: SlotsClassValue<RCV>; } )>=} compoundVariants - Compound variants allow you to apply classes to multiple variants at once.
 * @property {Array<{ slots: Array<keyof S> } & CompoundBase<RCV, V> & ClassProp>=} compoundSlots - Compound slots allow you to apply classes to multiple slots at once.
 * @property {SVAVariants<RCV, V>=} defaultVariants - Default variants allow you to set default variants for a component.
 *
 * @example
 * ```ts
 * const buttonConfig: SVAConfig<
 *   { root: string; item: string },
 *   { size: { small: { root: string }; medium: { root: string } } }
 * > = {
 *   slots: {
 *     root: "flex",
 *     item: "px-2 py-1"
 *   },
 *   variants: {
 *     size: {
 *       small: {
 *         root: "text-sm"
 *       },
 *       medium: {
 *         root: "text-base"
 *       }
 *     }
 *   },
 *   compoundVariants: [{ size: "small", class: { root: "font-bold" } }],
 *   compoundSlots: [{ slots: ["root", "item"], class: "rounded" }],
 *   defaultVariants: {
 *     size: "medium"
 *   }
 * };
 * ```
 */
type SVAConfig<RCV extends RecordClassValue, V extends Variants<RCV>> = {
    /**
     * The name of the sva component.
     */
    name?: string;
    /**
     * Slots allow you to separate a component into multiple parts.
     */
    slots?: RCV;
    /**
     * Variants allow you to create multiple versions of the same component.
     */
    variants?: V;
    /**
     * Compound variants allow you to apply classes to multiple variants at once.
     */
    compoundVariants?: Array<CompoundBase<RCV, V> & ({
        class?: SlotsClassValue<RCV>;
        className?: never;
    } | {
        class?: never;
        className?: SlotsClassValue<RCV>;
    })>;
    /**
     * Compound slots allow you to apply classes to multiple slots at once.
     */
    compoundSlots?: Array<{
        slots: Array<keyof RCV>;
    } & CompoundBase<RCV, V> & ClassProp>;
    /**
     * Default variants allow you to set default variants for a component.
     */
    defaultVariants?: SVAVariants<RCV, V>;
};

type CVA = CVAConfig<any>;
type Options = {
    /**
     * The relative path to the main CSS/Tailwind file where the generated `@apply`
     * directives will be written. This file should typically reside in a
     * dedicated styling directory (e.g., `css`, `styles`).
     *
     * Example: `./styles/components.css`
     */
    entry?: string;
    /**
     * An object containing arrays of your `jade-garden` CVA and SVA configurations.
     * The plugin will process these configurations to generate the corresponding CSS.
     */
    components?: {
        cva?: CVA[];
        sva?: SVA[];
    };
    /**
     * An optional custom class merging function. If not provided, the plugin
     * will use `jade-garden`'s default `cx` utility for merging generated class names.
     * You might provide this if you are using `tailwind-merge` or a similar utility
     * to handle class conflicts.
     */
    mergeFn?: MergeClassFn;
};
type PluginInstance<T> = (options?: Options | undefined) => T;
type SVA = SVAConfig<any, any>;

export type { PluginInstance as P };
