import { describe, it, expect } from "vitest";
// Test the React prop extraction patterns directly
describe("React Parser - extractConstArrays", () => {
    function extractConstArrays(content) {
        const constArrays = new Map();
        const constRegex = /const\s+(\w+)\s*=\s*\[([^\]]+)\]\s*as\s+const/g;
        let match;
        while ((match = constRegex.exec(content)) !== null) {
            const name = match[1];
            const values = match[2]
                .split(",")
                .map((s) => s.trim().replace(/['"]/g, ""))
                .filter((s) => s.length > 0);
            constArrays.set(name, values);
        }
        return constArrays;
    }
    it("should extract const arrays", () => {
        const content = `
export const sizes = ['s', 'm', 'l'] as const;
export const themes = ['primary', 'secondary', 'danger'] as const;
`;
        const arrays = extractConstArrays(content);
        expect(arrays.get("sizes")).toEqual(["s", "m", "l"]);
        expect(arrays.get("themes")).toEqual(["primary", "secondary", "danger"]);
    });
    it("should handle double quotes", () => {
        const content = `export const variants = ["solid", "bordered", "ghost"] as const;`;
        const arrays = extractConstArrays(content);
        expect(arrays.get("variants")).toEqual(["solid", "bordered", "ghost"]);
    });
});
describe("React Parser - extractPropsFromInterface", () => {
    function extractPropsFromInterface(content, interfaceName, constArrays) {
        const props = [];
        const seenProps = new Set();
        const interfaceRegex = new RegExp(`interface\\s+${interfaceName}\\s*(?:extends\\s+([^{]+))?\\s*\\{([\\s\\S]*?)\\}`, "g");
        const match = interfaceRegex.exec(content);
        if (!match)
            return props;
        const extendsClause = match[1];
        const interfaceBody = match[2];
        // Recursively get props from extended interfaces
        if (extendsClause) {
            const extendedInterfaces = extendsClause
                .split(",")
                .map((s) => s.trim().replace(/<[^>]+>/, ""))
                .filter((s) => s.length > 0 && !s.startsWith("Omit") && !s.includes("HTMLAttributes"));
            for (const extInterface of extendedInterfaces) {
                const extProps = extractPropsFromInterface(content, extInterface, constArrays);
                for (const prop of extProps) {
                    if (!seenProps.has(prop.name)) {
                        seenProps.add(prop.name);
                        props.push(prop);
                    }
                }
            }
        }
        const propRegex = /(\w+)(\?)?:\s*([^;\n]+)/g;
        let propMatch;
        while ((propMatch = propRegex.exec(interfaceBody)) !== null) {
            const propName = propMatch[1];
            const isOptional = !!propMatch[2];
            const propType = propMatch[3].trim();
            if (seenProps.has(propName))
                continue;
            if (propType.includes("=>") || propName.startsWith("on"))
                continue;
            if (propName === "children" || propName === "className")
                continue;
            seenProps.add(propName);
            let options;
            const typeRefMatch = propType.match(/^T(\w+)$/);
            if (typeRefMatch) {
                const typeName = typeRefMatch[1].toLowerCase();
                for (const [constName, values] of constArrays) {
                    const constNameLower = constName.toLowerCase();
                    // Match if type contains const name or const name contains type suffix
                    // e.g., "buttonvariant" should match "variant" or "variants"
                    if (typeName.includes(constNameLower) ||
                        typeName.includes(constNameLower.replace(/s$/, ""))) {
                        options = values;
                        break;
                    }
                }
            }
            if (propType.includes("|") && propType.includes("'")) {
                options = propType
                    .split("|")
                    .map((s) => s.trim().replace(/['"]/g, ""))
                    .filter((s) => s && s !== "undefined");
            }
            props.push({
                name: propName,
                type: propType,
                required: !isOptional,
                options: options && options.length > 1 ? options : undefined,
            });
        }
        return props;
    }
    it("should extract props from simple interface", () => {
        const content = `
interface IButtonProps {
  variant?: TButtonVariant;
  size?: TButtonSize;
  isDisabled?: boolean;
}
`;
        const constArrays = new Map();
        constArrays.set("variants", ["solid", "bordered"]);
        constArrays.set("sizes", ["s", "m", "l"]);
        const props = extractPropsFromInterface(content, "IButtonProps", constArrays);
        expect(props).toHaveLength(3);
        expect(props[0].name).toBe("variant");
        expect(props[0].options).toEqual(["solid", "bordered"]);
        expect(props[1].name).toBe("size");
        expect(props[1].options).toEqual(["s", "m", "l"]);
        expect(props[2].name).toBe("isDisabled");
        expect(props[2].type).toBe("boolean");
    });
    it("should handle interface inheritance", () => {
        const content = `
interface IBaseProps {
  id?: string;
  testId?: string;
}

interface IButtonProps extends IBaseProps {
  variant?: string;
  size?: string;
}
`;
        const props = extractPropsFromInterface(content, "IButtonProps", new Map());
        expect(props).toHaveLength(4);
        expect(props.map((p) => p.name)).toContain("id");
        expect(props.map((p) => p.name)).toContain("testId");
        expect(props.map((p) => p.name)).toContain("variant");
        expect(props.map((p) => p.name)).toContain("size");
    });
    it("should extract inline union types as options", () => {
        const content = `
interface IButtonProps {
  theme?: 'primary' | 'secondary' | 'danger';
  size?: 's' | 'm' | 'l';
}
`;
        const props = extractPropsFromInterface(content, "IButtonProps", new Map());
        expect(props[0].options).toEqual(["primary", "secondary", "danger"]);
        expect(props[1].options).toEqual(["s", "m", "l"]);
    });
    it("should skip callback props and children", () => {
        const content = `
interface IButtonProps {
  onClick?: () => void;
  onHover?: (event: MouseEvent) => void;
  children?: ReactNode;
  className?: string;
  label?: string;
}
`;
        const props = extractPropsFromInterface(content, "IButtonProps", new Map());
        expect(props).toHaveLength(1);
        expect(props[0].name).toBe("label");
    });
});
describe("React Parser - extractCallbacks", () => {
    function extractCallbacks(content) {
        const events = [];
        const seenEvents = new Set();
        const callbackPatterns = [
            /(\bon[A-Z]\w*)\??:\s*\([^)]*\)\s*=>\s*\w+/g,
            /(\bon[A-Z]\w*)\??:\s*\w*EventHandler/g,
        ];
        for (const pattern of callbackPatterns) {
            let match;
            while ((match = pattern.exec(content)) !== null) {
                const eventName = match[1];
                if (!seenEvents.has(eventName)) {
                    seenEvents.add(eventName);
                    events.push({
                        name: eventName,
                        description: `${eventName.replace(/^on/, "")} event callback`,
                    });
                }
            }
        }
        return events;
    }
    it("should extract callback props", () => {
        const content = `
interface IButtonProps {
  onClick?: () => void;
  onHover?: (event: MouseEvent) => void;
  onChange?: (value: string) => void;
}
`;
        const callbacks = extractCallbacks(content);
        expect(callbacks).toHaveLength(3);
        expect(callbacks.map((c) => c.name)).toContain("onClick");
        expect(callbacks.map((c) => c.name)).toContain("onHover");
        expect(callbacks.map((c) => c.name)).toContain("onChange");
    });
    it("should extract EventHandler types", () => {
        const content = `
interface IInputProps {
  onFocus?: FocusEventHandler;
  onBlur?: FocusEventHandler;
}
`;
        const callbacks = extractCallbacks(content);
        expect(callbacks).toHaveLength(2);
        expect(callbacks.map((c) => c.name)).toContain("onFocus");
        expect(callbacks.map((c) => c.name)).toContain("onBlur");
    });
});
describe("React Parser - hasChildrenProp", () => {
    function hasChildrenProp(content) {
        return (content.includes("children") ||
            content.includes("PropsWithChildren") ||
            content.includes("ReactNode"));
    }
    it("should detect children prop", () => {
        expect(hasChildrenProp("interface Props { children: ReactNode }")).toBe(true);
        expect(hasChildrenProp("type Props = PropsWithChildren<{}>")).toBe(true);
        expect(hasChildrenProp("interface Props { label: string }")).toBe(false);
    });
});
describe("React Parser - inferCategory", () => {
    function inferCategory(componentName) {
        const name = componentName.toLowerCase();
        if (["button", "link", "optionbutton"].some((n) => name.includes(n)))
            return "action";
        if (["input", "select", "checkbox", "radio", "toggle", "textarea", "field"].some((n) => name.includes(n)))
            return "form";
        if (["accordion", "breadcrumb", "menu", "pagination", "tabs"].some((n) => name.includes(n)))
            return "navigation";
        if (["badge", "flag", "loader", "modal", "notification", "progress", "tooltip"].some((n) => name.includes(n)))
            return "feedback";
        if (["card", "divider", "layer"].some((n) => name.includes(n)))
            return "layout";
        if (["table", "heading", "hero", "listbox", "rating", "tag"].some((n) => name.includes(n)))
            return "data-display";
        return "other";
    }
    it("should categorize action components", () => {
        expect(inferCategory("Button")).toBe("action");
        expect(inferCategory("Link")).toBe("action");
        expect(inferCategory("OptionButton")).toBe("action");
    });
    it("should categorize form components", () => {
        expect(inferCategory("Input")).toBe("form");
        expect(inferCategory("TextInput")).toBe("form");
        expect(inferCategory("Checkbox")).toBe("form");
        expect(inferCategory("Select")).toBe("form");
        expect(inferCategory("TextField")).toBe("form");
    });
    it("should categorize navigation components", () => {
        expect(inferCategory("Breadcrumb")).toBe("navigation");
        expect(inferCategory("Menu")).toBe("navigation");
        expect(inferCategory("Tabs")).toBe("navigation");
    });
    it("should categorize feedback components", () => {
        expect(inferCategory("Modal")).toBe("feedback");
        expect(inferCategory("Notification")).toBe("feedback");
        expect(inferCategory("Loader")).toBe("feedback");
        expect(inferCategory("ProgressBar")).toBe("feedback");
    });
    it("should return other for unknown components", () => {
        expect(inferCategory("CustomComponent")).toBe("other");
        expect(inferCategory("MyWidget")).toBe("other");
    });
});
//# sourceMappingURL=react-parser.test.js.map