import { discoverAllComponents, getComponentInfo } from "./component-discovery.js";
import { L as LLMClient } from "../llm-client-E5_0H-oG.js";
import { C as CodeCleaner, P as PromptBuilder } from "../prompt-builder-D85sbj4C.js";
import { D as DEFAULT_MODEL } from "../models-DXdD4jTK.js";
class ComponentComposer {
  llmClient;
  codeCleaner;
  promptBuilder;
  constructor() {
    this.llmClient = new LLMClient();
    this.codeCleaner = new CodeCleaner();
    this.promptBuilder = new PromptBuilder();
  }
  async compose(prompt, options = {}) {
    await this.llmClient.initialize();
    const allComponents = discoverAllComponents();
    const selectedComponents = await this.selectComponents(
      prompt,
      allComponents,
      options
    );
    const componentInfo = this.gatherComponentInfo(selectedComponents);
    const context = this.buildContext(prompt, componentInfo);
    const code = await this.callLLM(context, options);
    const result = this.formatResult(code, prompt, selectedComponents);
    return result;
  }
  async selectComponents(prompt, allComponents, options = {}) {
    const keywordMatches = this.findRelevantComponents(prompt, allComponents);
    const combined = new Set(keywordMatches);
    if (options.smartSelection) {
      const componentList = allComponents.filter((c) => c.category !== "chrome" && !c.name.includes("chrome/")).map((c) => ({
        name: c.name,
        category: c.category,
        description: c.description?.substring(0, 100) || ""
      }));
      const llmSelected = await this.askLLMForComponentSelection(
        prompt,
        componentList
      );
      llmSelected.forEach((comp) => combined.add(comp));
    }
    combined.add("grid");
    combined.add("text");
    const sorted = Array.from(combined).slice(0, 20);
    return sorted;
  }
  findRelevantComponents(prompt, allComponents) {
    const lowerPrompt = prompt.toLowerCase();
    const matches = /* @__PURE__ */ new Map();
    const promptWords = lowerPrompt.split(/\s+/).filter((w) => w.length > 2);
    for (const component of allComponents) {
      if (component.category === "chrome" || component.name.includes("chrome/")) {
        continue;
      }
      const searchableText = [
        component.name,
        component.componentName,
        component.category,
        component.description || ""
      ].join(" ").toLowerCase().replaceAll(/[-/_]/g, " ");
      let score = 0;
      if (lowerPrompt.includes(
        component.name.toLowerCase().replaceAll(/[-/_]/g, " ")
      )) {
        score += 10;
      }
      if (lowerPrompt.includes(component.category)) {
        score += 5;
      }
      for (const word of promptWords) {
        if (searchableText.includes(word)) {
          score += 1;
        }
      }
      if (score > 0) {
        matches.set(component.name, score);
      }
    }
    return Array.from(matches.entries()).sort((a, b) => b[1] - a[1]).slice(0, 15).map(([name]) => name);
  }
  async askLLMForComponentSelection(prompt, components) {
    const context = `Select ONLY the relevant UI components for this request: "${prompt}"

Available components:
${components.map((c) => `${c.name} (${c.category}): ${c.description}`).join("\n")}

Return a JSON array of component names that are needed. Be selective - only include what's necessary.
Example response: ["button", "form", "input"]`;
    try {
      const response = await this.callLLM(context, {
        maxTokens: 500,
        model: DEFAULT_MODEL["anthropic"]
      });
      let jsonStr = response.trim();
      if (jsonStr.startsWith("```")) {
        jsonStr = jsonStr.replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "");
      }
      const arrayMatch = jsonStr.match(/\[[\s\S]*\]/);
      if (arrayMatch) {
        jsonStr = arrayMatch[0];
      }
      const parsed = JSON.parse(jsonStr);
      return Array.isArray(parsed) ? parsed : [];
    } catch {
      if (process.env.NODE_ENV !== "production") {
        console.warn(
          "LLM component selection failed, using keyword matches only"
        );
      }
      return [];
    }
  }
  gatherComponentInfo(componentNames) {
    const results = [];
    for (const name of componentNames) {
      const info = getComponentInfo(name, { verbose: false });
      if (info) {
        results.push(info);
      }
    }
    return results;
  }
  buildContext(prompt, componentInfo) {
    const importMap = this.promptBuilder.buildComponentImportMap(componentInfo);
    return `Generate a production-ready React component using Glide UI components.

USER REQUEST: ${prompt}

AVAILABLE COMPONENTS:
${importMap}

REQUIREMENTS:
1. Use ONLY the components listed above with their EXACT import statements
2. Each component must use its specific import path shown above
3. Generate clean TypeScript with proper interfaces for all props
4. NEVER use 'any' type - always provide proper TypeScript types
5. Use specific types like Record<string, string>, unknown, or proper interfaces instead of 'any'
6. Use React hooks appropriately (useState, useMemo, useCallback)
7. Make the component reusable and properly typed
8. Do not add decorative comments or section dividers
9. Use className for styling, not inline styles
10. For event handlers, use proper React event types (e.g., React.MouseEvent, React.ChangeEvent)

Generate the complete component now:`;
  }
  async callLLM(context, options) {
    return this.llmClient.generate(
      { prompt: context },
      {
        model: options.model,
        maxTokens: options.maxTokens || 2e3,
        temperature: 0.3
      }
    );
  }
  formatResult(code, prompt, components) {
    const imports = this.codeCleaner.extractImports(code);
    const types = this.codeCleaner.extractTypes(code);
    return {
      code,
      components,
      imports,
      types,
      prompt,
      timestamp: (/* @__PURE__ */ new Date()).toISOString()
    };
  }
}
export {
  ComponentComposer
};
