import { L as LLMClient } from "./llm-client-E5_0H-oG.js";
import { C as CodeCleaner, P as PromptBuilder } from "./prompt-builder-D85sbj4C.js";
import { discoverAllComponents, getComponentInfo } from "./cli/component-discovery.js";
import { D as DEFAULT_MODEL } from "./models-DXdD4jTK.js";
class CommandExecutor {
  llmClient;
  codeCleaner;
  promptBuilder;
  defaultLLMOptions;
  constructor(options = {}) {
    this.llmClient = new LLMClient();
    this.codeCleaner = new CodeCleaner();
    this.promptBuilder = new PromptBuilder();
    this.defaultLLMOptions = options.llm || {};
  }
  /**
   * Main execution method - Template Method pattern
   *
   * Defines the algorithm structure, calling abstract methods
   * that subclasses must implement.
   */
  async execute(input, options = {}) {
    await this.llmClient.initialize();
    this.validateInput(input);
    const context = await this.prepareContext(input);
    const mergedOptions = { ...this.defaultLLMOptions, ...options };
    const rawResult = await this.llmClient.generate(context, mergedOptions);
    const processed = await this.processResult(rawResult, input);
    return processed;
  }
}
class ScreenExecutor extends CommandExecutor {
  constructor() {
    super({
      llm: {
        model: "claude-haiku-4-5"
      }
    });
  }
  validateInput(input) {
    if (!input.prompt || typeof input.prompt !== "string") {
      throw new Error("Screen prompt is required and must be a string");
    }
    if (input.prompt.trim().length === 0) {
      throw new Error("Screen prompt cannot be empty");
    }
  }
  async prepareContext(input) {
    const planResult = await this.generatePlan(input);
    const componentInfo = this.loadSelectedComponentInfo(
      planResult.componentNames
    );
    return this.buildContextWithPlan(input, planResult, componentInfo);
  }
  async processResult(rawResult, input) {
    const code = this.codeCleaner.clean(rawResult);
    const planResult = await this.generatePlan(input);
    return {
      code,
      plan: planResult.plan,
      componentNames: planResult.componentNames,
      schema: input.schema
    };
  }
  getCacheKey(input) {
    return `${input.prompt}:${input.schema || "no-schema"}:${input.model || "default"}`;
  }
  async generatePlan(input) {
    const allComponents = discoverAllComponents();
    const componentList = allComponents.map((c) => {
      const lines = [`- ${c.name} (${c.category})`, `  Import: ${c.import}`];
      if (c.description) lines.push(`  Description: ${c.description}`);
      return lines.join("\n");
    }).join("\n");
    const designEngineerPrompt = this.promptBuilder.getDesignEngineerPrompt();
    const planPromptParts = [
      `You are a design engineer planning a React screen using the Glide UI component library.`,
      "",
      designEngineerPrompt,
      "",
      "---",
      "",
      `USER REQUEST: Create a screen for: ${input.prompt}`,
      ""
    ];
    if (input.schema) {
      planPromptParts.push(
        "---",
        "",
        "DATA SCHEMA:",
        "",
        "The screen will work with data matching this TypeScript interface:",
        "",
        input.schema,
        "",
        "When selecting components, consider this schema:",
        "- Use form components for input/editing scenarios",
        "- Use data display components (tables, lists, cards) for showing collections",
        "- Use detail view patterns for single object displays",
        "- Consider the data structure when choosing layout components",
        ""
      );
    }
    planPromptParts.push(
      "---",
      "",
      "AVAILABLE COMPONENTS:",
      "",
      componentList,
      "",
      "---",
      "",
      "TASK: Create a detailed plan for this screen that includes:",
      "1. A structured description of the screen layout and functionality",
      "2. A list of component names that will be needed to build this screen",
      "3. How these components will be arranged and interact",
      "",
      "Respond in the following JSON format:",
      "{",
      '  "plan": "Detailed description...",',
      '  "components": ["component-name-1", "component-name-2"]',
      "}",
      "",
      "Return ONLY valid JSON, no markdown."
    );
    const planPrompt = planPromptParts.join("\n");
    const rawPlan = await this.llmClient.generate(
      { prompt: planPrompt },
      {
        model: input.model ?? DEFAULT_MODEL["anthropic"],
        maxTokens: 2e3
      }
    );
    return this.extractPlanFromResponse(rawPlan, allComponents);
  }
  /**
   * Parse JSON from LLM or heuristically recover component names
   */
  extractPlanFromResponse(response, allComponents) {
    const cleaned = response.trim();
    const jsonSlice = (() => {
      const m = cleaned.match(/\{[\s\S]*\}/);
      return m ? m[0] : cleaned;
    })();
    try {
      const parsed = JSON.parse(jsonSlice);
      const names = Array.isArray(parsed.components) ? parsed.components : [];
      return { plan: String(parsed.plan ?? ""), componentNames: names };
    } catch {
      const set = /* @__PURE__ */ new Set();
      const byLower = new Map(
        allComponents.map((c) => [c.name.toLowerCase(), c.name])
      );
      const hay = cleaned.toLowerCase();
      for (const [k, original] of byLower.entries()) {
        const re = new RegExp(`\\b${escapeRegex(k)}\\b`, "i");
        if (re.test(hay)) set.add(original);
      }
      return { plan: cleaned, componentNames: [...set] };
    }
  }
  /**
   * Load verbose docs for only the selected components
   */
  loadSelectedComponentInfo(componentNames) {
    const unique = [...new Set(componentNames)];
    return unique.map((name) => getComponentInfo(name, { verbose: true })).filter(Boolean);
  }
  /**
   * Build final generation context using the plan + selected component docs
   */
  buildContextWithPlan(input, planResult, componentInfo) {
    const componentDocs = this.promptBuilder.formatComponentDocs(componentInfo);
    const designEngineerPrompt = this.promptBuilder.getDesignEngineerPrompt();
    const promptParts = [
      `You are a design engineer creating a complete React screen component using the Glide UI component library.`,
      "",
      designEngineerPrompt,
      "",
      "---",
      "",
      `USER REQUEST: Create a screen for: ${input.prompt}`,
      ""
    ];
    if (input.schema) {
      promptParts.push(
        "---",
        "",
        "DATA SCHEMA:",
        "",
        "The screen should work with data matching this TypeScript interface:",
        "",
        input.schema,
        "",
        "Please:",
        "1. Include this interface in the generated code",
        "2. Generate mock data that matches this schema structure in the loader function",
        "3. Use the schema to inform the component structure and data display",
        ""
      );
    }
    promptParts.push(
      "---",
      "",
      "SCREEN PLAN:",
      "",
      planResult.plan,
      "",
      "---",
      "",
      "COMPONENT DOCUMENTATION:",
      "",
      componentDocs,
      "",
      "---",
      "",
      "SCREEN GENERATION REQUIREMENTS:"
    );
    const prompt = [
      ...promptParts,
      "",
      // Critical React Router structure requirements (kept from original)
      `CRITICAL - CORRECT CODE STRUCTURE:
Your code MUST follow this exact import pattern - these imports are REQUIRED and MUST be first:

// STEP 1: React Router imports - REQUIRED, MUST BE FIRST, MUST BE BOTH
// These TWO imports MUST be the VERY FIRST lines of your file, before ANY other imports:
import { useLoaderData } from "react-router";
import type { LoaderFunctionArgs } from "react-router";
// NOTE: You MUST have BOTH of these imports. Do NOT skip either one.
// NOTE: Use "import type { ... }" NOT "import { type ... }" for the type import

// STEP 2: React imports (after React Router imports)
import React, { useState, useMemo } from "react";

// STEP 3: @glide/glide-ui component imports (after React Router and React imports)
import { ScreenWrapper } from "@glide/glide-ui/chrome";
// ... other @glide/glide-ui imports

CRITICAL WARNINGS:
- BOTH React Router imports are REQUIRED - do NOT skip either one
- These MUST be the FIRST two lines of your file
- Use "import type { LoaderFunctionArgs }" NOT "import { type LoaderFunctionArgs }"
- Do NOT put these imports after @glide/glide-ui imports

interface ScreenData {
  // your data structure - use proper types, NEVER use 'any'
}

export async function loader(args: LoaderFunctionArgs): Promise<ScreenData> {
  // loader implementation - return actual data (will be wrapped in Promise automatically)
  // NOTE: loader is a NAMED export, NOT default export
  return {
    // actual data structure matching ScreenData interface
  };
}

export default function YourScreen() {
  // NOTE: This is the ONLY default export in the file
  const data = useLoaderData<typeof loader>();
  // For colors, use Tailwind classes or regular strings, NOT template literals with var()
  return (
    <ScreenWrapper>
      {/* actual screen content */}
    </ScreenWrapper>
  );
}

CRITICAL MISTAKES TO AVOID:
- NEVER use arrow function: export const loader = ...
- MUST use function declaration: export async function loader(...)
- NEVER export loader as default
- ONLY the component should be default export
- EXACTLY one default export
- NEVER manually call loader()
- MUST use useLoaderData<typeof loader>()
- NEVER re-implement React Router hooks
- NEVER use 'any'
- Wrap content in <ScreenWrapper />
- Use Tailwind / component props for colors (no template-literal CSS vars)

CRITICAL - IMPORT REQUIREMENTS (MUST FOLLOW EXACTLY):
- Line 1: import { useLoaderData } from "react-router";
- Line 2: import type { LoaderFunctionArgs } from "react-router";
- Then React
- Then @glide/glide-ui imports
- Use "import type" for type-only imports
- All imports must be at the very top

GENERATION REQUIREMENTS:
- Output ONLY valid TypeScript/TSX code, no markdown
- Start with imports, end with component code
- No explanations or comments outside of code
- Generate the complete screen now.`
    ].join("\n");
    return { prompt };
  }
}
function escapeRegex(s) {
  return s.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
const SUPPORTED_MODELS = [
  "claude-haiku-4-5",
  "claude-sonnet-4-5",
  "claude-opus-4-1"
];
function isSupportedModel(m) {
  return SUPPORTED_MODELS.includes(m);
}
class ScreenComposer {
  executor;
  constructor() {
    this.executor = new ScreenExecutor();
  }
  async compose(prompt, options = {}) {
    const model = options.model ?? "claude-haiku-4-5";
    if (!isSupportedModel(model)) {
      throw new Error(
        `Unsupported model: ${model}. Supported models: ${SUPPORTED_MODELS.join(", ")}`
      );
    }
    const result = await this.executor.execute(
      { prompt, model, maxTokens: options.maxTokens },
      { model }
    );
    return { code: result.code };
  }
}
export {
  CommandExecutor as C,
  ScreenExecutor as S,
  ScreenComposer as a
};
