import {
  BaseComponentGenerator
} from "../shared/base-generator.js";
import { getSyntaxPattern } from "../shared/syntax-mapper.js";
import { extractComponentTypes } from "../shared/base-generator.js";
class ReactComponentGenerator extends BaseComponentGenerator {
  reactConfig;
  constructor(adapter, config) {
    super(adapter, config);
    this.reactConfig = config;
  }
  // ============================================================================
  // Abstract Method Implementations
  // ============================================================================
  /**
   * Generate React imports
   */
  generateImports(viewSpec) {
    const imports = [];
    const reactImports = this.getReactCoreImports(viewSpec);
    if (reactImports) {
      imports.push(reactImports);
    }
    const componentTypes = extractComponentTypes(viewSpec.components);
    const componentImports = this.getComponentImports(componentTypes);
    imports.push(...componentImports);
    return imports.join("\n");
  }
  /**
   * Generate complete React component
   */
  generateComponent(parts) {
    const lines = [];
    if (this.reactConfig.includeComments) {
      lines.push(`/**`);
      lines.push(` * ${parts.name} Component`);
      lines.push(` * Generated by SpecVerse`);
      lines.push(` */`);
      lines.push("");
    }
    lines.push(parts.imports);
    lines.push("");
    const propsInterface = this.generatePropsInterface(parts.name);
    if (propsInterface) {
      lines.push(propsInterface);
      lines.push("");
    }
    lines.push(this.generateComponentFunction(parts));
    return lines.join("\n");
  }
  /**
   * Generate state declarations using React hooks
   */
  generateState(state) {
    const stateDeclarations = [];
    for (const [name, def] of Object.entries(state)) {
      const declaration = getSyntaxPattern("stateDeclaration", "react", {
        name,
        Name: this.capitalize(name),
        type: def.type,
        initial: JSON.stringify(def.initial)
      });
      if (this.reactConfig.includeComments && def.description) {
        stateDeclarations.push(`  // ${def.description}`);
      }
      stateDeclarations.push(`  ${declaration}`);
    }
    return stateDeclarations.join("\n");
  }
  /**
   * Generate event handlers
   */
  generateEvents(events) {
    const eventHandlers = [];
    for (const [name, def] of Object.entries(events)) {
      const handler = getSyntaxPattern("eventHandler", "react", {
        Name: this.capitalize(name),
        params: def.params || "",
        body: def.body
      });
      if (this.reactConfig.includeComments && def.description) {
        eventHandlers.push(`  // ${def.description}`);
      }
      eventHandlers.push(`  ${handler}`);
    }
    return eventHandlers.join("\n\n");
  }
  /**
   * Get file extension (.tsx for React/TypeScript)
   */
  getFileExtension() {
    return this.reactConfig.typescript ? ".tsx" : ".jsx";
  }
  /**
   * Get additional files (styles, types, etc.)
   */
  getAdditionalFiles(viewSpec) {
    const files = {};
    if (this.reactConfig.typescript && this.reactConfig.strictMode) {
      files[`${viewSpec.name}.types.ts`] = this.generateTypesFile(viewSpec);
    }
    return files;
  }
  // ============================================================================
  // React-Specific Helper Methods
  // ============================================================================
  /**
   * Get React core imports (useState, useEffect, etc.)
   */
  getReactCoreImports(viewSpec) {
    const hooks = [];
    if (viewSpec.state && Object.keys(viewSpec.state).length > 0) {
      hooks.push("useState");
    }
    if (this.needsUseEffect(viewSpec)) {
      hooks.push("useEffect");
    }
    if (hooks.length > 0) {
      return `import React, { ${hooks.join(", ")} } from 'react';`;
    }
    return `import React from 'react';`;
  }
  /**
   * Get component library imports
   */
  getComponentImports(componentTypes) {
    const imports = [];
    const importMap = /* @__PURE__ */ new Map();
    for (const type of componentTypes) {
      const adapterComponent = this.adapter.components[type];
      if (adapterComponent && adapterComponent.import) {
        const importMatch = adapterComponent.import.match(/from ['"](.+)['"]/);
        if (importMatch) {
          const source = importMatch[1];
          const componentMatch = adapterComponent.import.match(/import \{ (.+) \}/);
          if (componentMatch) {
            const componentName = componentMatch[1];
            if (!importMap.has(source)) {
              importMap.set(source, []);
            }
            importMap.get(source).push(componentName);
          }
        }
      }
    }
    for (const [source, components] of importMap) {
      imports.push(getSyntaxPattern("libraryImport", "react", {
        exports: components.join(", "),
        library: source
      }));
    }
    return imports;
  }
  /**
   * Generate props interface for TypeScript
   */
  generatePropsInterface(componentName) {
    if (!this.reactConfig.typescript) {
      return null;
    }
    const lines = [];
    if (this.reactConfig.includeComments) {
      lines.push(`/**`);
      lines.push(` * Props for ${componentName} component`);
      lines.push(` */`);
    }
    lines.push(`interface ${componentName}Props {`);
    lines.push(`  // Component props will be added here`);
    lines.push(`}`);
    return lines.join("\n");
  }
  /**
   * Generate main component function
   */
  generateComponentFunction(parts) {
    const lines = [];
    const propsParam = this.reactConfig.typescript ? `props: ${parts.name}Props` : "props";
    lines.push(`export function ${parts.name}(${propsParam}) {`);
    if (parts.state) {
      lines.push(parts.state);
      lines.push("");
    }
    if (parts.events) {
      lines.push(parts.events);
      lines.push("");
    }
    lines.push("  return (");
    lines.push('    <div className="specverse-view">');
    const indentedComponents = parts.components.split("\n").map((line) => line ? `      ${line}` : "").join("\n");
    lines.push(indentedComponents);
    lines.push("    </div>");
    lines.push("  );");
    lines.push("}");
    return lines.join("\n");
  }
  /**
   * Generate separate types file
   */
  generateTypesFile(viewSpec) {
    const lines = [];
    lines.push(`/**`);
    lines.push(` * Type definitions for ${viewSpec.name}`);
    lines.push(` * Generated by SpecVerse`);
    lines.push(` */`);
    lines.push("");
    if (viewSpec.state) {
      lines.push(`export interface ${viewSpec.name}State {`);
      for (const [name, def] of Object.entries(viewSpec.state)) {
        if (def.description) {
          lines.push(`  /** ${def.description} */`);
        }
        lines.push(`  ${name}: ${def.type};`);
      }
      lines.push(`}`);
      lines.push("");
    }
    if (viewSpec.events) {
      for (const [name, def] of Object.entries(viewSpec.events)) {
        const handlerName = `${this.capitalize(name)}Handler`;
        const params = def.params || "";
        if (def.description) {
          lines.push(`/** ${def.description} */`);
        }
        lines.push(`export type ${handlerName} = (${params}) => void;`);
        lines.push("");
      }
    }
    return lines.join("\n");
  }
  /**
   * Check if component needs useEffect hook
   */
  needsUseEffect(viewSpec) {
    if (viewSpec.events) {
      const eventNames = Object.keys(viewSpec.events).map((e) => e.toLowerCase());
      return eventNames.some(
        (name) => name.includes("mount") || name.includes("init") || name.includes("load")
      );
    }
    return false;
  }
  /**
   * Capitalize first letter of string
   */
  capitalize(str) {
    return str.charAt(0).toUpperCase() + str.slice(1);
  }
  // ============================================================================
  // React-Specific Component Rendering
  // ============================================================================
  /**
   * Override to add React-specific rendering hints
   */
  renderAdapterComponent(type, properties, children, context) {
    if (!properties.className && type !== "container") {
      properties.className = `specverse-${type}`;
    }
    return super.renderAdapterComponent(type, properties, children, context);
  }
}
function createReactGenerator(adapter, config) {
  const defaultConfig = {
    framework: "react",
    target: "shadcn",
    typescript: true,
    strictMode: false,
    includeComments: true,
    maxDepth: 3,
    enableWarnings: true
  };
  const finalConfig = { ...defaultConfig, ...config };
  return new ReactComponentGenerator(adapter, finalConfig);
}
function generateReactComponent(viewSpec, adapter, options) {
  const generator = createReactGenerator(adapter, options);
  const result = generator.generate(viewSpec);
  if (result.warnings.length > 0) {
    console.warn("Generation warnings:", result.warnings);
  }
  return result.code;
}
function generateReactComponentFiles(viewSpec, adapter, options) {
  const generator = createReactGenerator(adapter, options);
  const result = generator.generate(viewSpec);
  const files = /* @__PURE__ */ new Map();
  const ext = generator.getFileExtension();
  files.set(`${viewSpec.name}${ext}`, result.code);
  const additionalFiles = generator.getAdditionalFiles(viewSpec);
  for (const [filename, content] of Object.entries(additionalFiles)) {
    files.set(filename, content);
  }
  return files;
}
export {
  ReactComponentGenerator,
  createReactGenerator,
  generateReactComponent,
  generateReactComponentFiles
};
