"""
Code generation utilities for HLA-Compass modules

Generates Python code, TypeScript components, and configuration files.
"""

import json
import logging
import shutil
from typing import Dict, Any, List, Optional
from pathlib import Path
from jinja2 import Environment, BaseLoader
from string import Template as StrTemplate

logger = logging.getLogger(__name__)


class CodeGenerator:
    """Generate module code from configuration"""
    
    def __init__(self):
        self.env = Environment(loader=BaseLoader())
        
    def generate_module(self, config: Dict[str, Any], output_dir: Path) -> bool:
        """
        Generate complete module from configuration
        
        Args:
            config: Module configuration from wizard
            output_dir: Directory to generate module in
            
        Returns:
            True if successful
        """
        try:
            # Create directory structure
            output_dir.mkdir(parents=True, exist_ok=True)
            backend_dir = output_dir / "backend"
            backend_dir.mkdir(exist_ok=True)
            examples_dir = output_dir / "examples"
            examples_dir.mkdir(exist_ok=True)
            
            # Generate manifest
            self._generate_manifest(config, output_dir)
            
            # Generate backend code
            self._generate_backend(config, backend_dir)
            
            # Generate requirements
            self._generate_requirements(config, backend_dir)
            
            # Generate sample input
            self._generate_sample_input(config, examples_dir)
            
            # Generate UI if needed
            if config.get('has_ui'):
                frontend_dir = output_dir / "frontend"
                frontend_dir.mkdir(exist_ok=True)

                # Populate full UI scaffold from packaged template (webpack, tsconfig, tailwind, etc.)
                try:
                    pkg_ui_scaffold = Path(__file__).parent / "templates" / "ui-template" / "frontend"
                    if pkg_ui_scaffold.exists():
                        shutil.copytree(pkg_ui_scaffold, frontend_dir, dirs_exist_ok=True)
                except Exception as scaffold_err:
                    # Non-fatal: continue with generated files even if scaffold copy fails
                    logger.warning(f"Could not copy UI scaffold: {scaffold_err}")

                # Optional: overwrite with wizard-generated UI entry and package.json tailored to config
                # Keep the scaffolded index.tsx from the template to avoid templating conflicts
                try:
                    self._generate_package_json(config, frontend_dir)
                except Exception as ui_pkg_err:
                    logger.warning(f"Could not write frontend package.json: {ui_pkg_err}")
            
            # Generate README
            self._generate_readme(config, output_dir)
            
            return True
            
        except Exception as e:
            logger.error(f"Error generating module: {e}")
            return False
    
    def _generate_manifest(self, config: Dict[str, Any], output_dir: Path):
        """Generate manifest.json"""
        manifest = {
            "name": config['name'],
            "version": "1.0.0",
            "type": "with-ui" if config.get('has_ui') else "no-ui",
            "computeType": "docker",
            "description": config.get('description', ''),
            "author": config.get('author', {}),
            "runtime": {
                "language": "python",
                "version": "3.11"
            },
            "inputs": config.get('inputs', {}),
            "outputs": config.get('outputs', {}),
            "resources": {
                "memory": 512,
                "timeout": 300
            },
            "dependencies": {
                "peptides": True,
                "storage": True,
                "api": True
            }
        }
        manifest["entrypoint"] = f"backend.main:{self._to_class_name(config['name'])}"
        
        if config.get('has_ui'):
            manifest['ui'] = {
                "framework": "react",
                "buildCommand": "npm run build",
                "distPath": "frontend/dist"
            }
        
        with open(output_dir / "manifest.json", "w") as f:
            json.dump(manifest, f, indent=2)
    
    def _generate_backend(self, config: Dict[str, Any], backend_dir: Path):
        """Generate backend/main.py"""
        
        template_str = '''"""
{{ description }}

Generated by HLA-Compass Module Wizard
"""

from hla_compass import Module
from typing import Dict, Any, List, Optional
from datetime import datetime
import logging
# Runtime: the platform's container runner (`module-runner`) instantiates this
# Module directly, so no additional handler function is required.
{% for dep in imports %}
import {{ dep }}
{% endfor %}

logger = logging.getLogger(__name__)


class {{ class_name }}(Module):
    """
    {{ description }}
    
    This module {{ processing_desc }}
    """
    
    def __init__(self):
        """Initialize the module"""
        super().__init__()
        self.logger.info("{{ name }} module initialized")
        {% if needs_model %}
        
        # Initialize your model or processing components here
        # self.model = self._load_model()
        {% endif %}
    
    def execute(
        self, 
        input_data: Dict[str, Any], 
        context: Dict[str, Any]
    ) -> Dict[str, Any]:
        """
        Main execution function
        
        Args:
            input_data: {{ input_desc }}
            context: Execution context with metadata
            
        Returns:
            Dict with {{ output_desc }}
        """
        try:
            job_id = context.get('job_id', 'unknown')
            self.logger.info(f"Starting execution for job {job_id}")
            
            # Validate input
            validation_result = self._validate_input(input_data)
            if not validation_result['valid']:
                return self.error(validation_result['message'])
            
            # Extract parameters
            {% for param, spec in inputs.items() %}
            {% if spec.default is defined %}
            {{ param }} = input_data.get('{{ param }}', {{ spec.default|tojson }})
            {% else %}
            {{ param }} = input_data.get('{{ param }}')
            {% endif %}
            {% endfor %}
            
            # Main processing
            self.logger.info("Processing data...")
            results = self._process_data(
                {% for param in inputs.keys() %}
                {{ param }}={{ param }}{{ ',' if not loop.last }}
                {% endfor %}
            )
            
            # Format output
            {{ output_formatting }}
            
            # Return success response
            return self.success(
                {{ success_return }}
            )
            
        except Exception as e:
            self.logger.error(f"Execution failed: {str(e)}", exc_info=True)
            return self.error(f"Processing failed: {str(e)}")
    
    def _validate_input(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
        """Validate input parameters"""
        {% for param, spec in inputs.items() %}
        {% if spec.required %}
        if '{{ param }}' not in input_data:
            return {'valid': False, 'message': 'Missing required parameter: {{ param }}'}
        {% endif %}
        {% endfor %}
        
        # Add type validation as needed
        
        return {'valid': True}
    
    def _process_data(self, {% for param in inputs.keys() %}{{ param }}: Any{{ ', ' if not loop.last }}{% endfor %}) -> Any:
        """
        Core processing logic
        
        TODO: Implement your processing here
        """
        {{ processing_logic }}
        
        return results
    {% if needs_formatting %}
    
    def _format_results(self, results: Any) -> Dict[str, Any]:
        """Format results for output"""
        # TODO: Format your results appropriately
        return {
            'data': results,
            'count': len(results) if hasattr(results, '__len__') else 1
        }
    {% endif %}

{{ helper_methods }}
'''
        
        # Prepare template variables
        class_name = self._to_class_name(config['name'])
        
        # Determine imports based on dependencies
        imports = []
        if 'numpy' in config.get('dependencies', []):
            imports.append('numpy as np')
        if 'pandas' in config.get('dependencies', []):
            imports.append('pandas as pd')
        if 'scikit-learn' in config.get('dependencies', []):
            imports.append('sklearn')
        
        # Generate processing logic based on type
        processing_logic = self._generate_processing_logic(config)
        helper_methods = self._generate_helper_methods(config)
        
        # Generate output formatting
        output_formatting = self._generate_output_formatting(config)
        
        # Generate success return
        success_return = self._generate_success_return(config)
        
        # Render template
        template = self.env.from_string(template_str)
        code = template.render(
            name=config['name'],
            description=config.get('description', 'HLA-Compass module'),
            class_name=class_name,
            imports=imports,
            inputs=config.get('inputs', {}),
            input_desc=self._describe_inputs(config),
            output_desc=self._describe_outputs(config),
            processing_desc=self._describe_processing(config),
            processing_logic=processing_logic,
            output_formatting=output_formatting,
            success_return=success_return,
            needs_model='Machine learning' in config.get('processing_type', ''),
            needs_formatting=True,
            helper_methods=helper_methods
        )
        
        with open(backend_dir / "main.py", "w") as f:
            f.write(code)
    
    def _generate_requirements(self, config: Dict[str, Any], backend_dir: Path):
        """Generate requirements.txt"""
        requirements = ["hla-compass>=0.1.0"]
        
        # Add dependencies from config
        dep_versions = {
            'numpy': '>=1.24.0',
            'pandas': '>=2.0.0',
            'scikit-learn': '>=1.3.0',
            'biopython': '>=1.81',
            'matplotlib': '>=3.7.0',
            'seaborn': '>=0.12.0',
            'scipy': '>=1.11.0',
            'torch': '>=2.0.0',
            'requests': '>=2.31.0',
            'xlsxwriter': '>=3.1.0'
        }
        
        for dep in config.get('dependencies', []):
            if dep in dep_versions:
                requirements.append(f"{dep}{dep_versions[dep]}")
            else:
                requirements.append(dep)
        
        with open(backend_dir / "requirements.txt", "w") as f:
            f.write("\n".join(requirements))
    
    def _generate_sample_input(self, config: Dict[str, Any], examples_dir: Path):
        """Generate sample_input.json"""
        sample_input = {}
        
        for param, spec in config.get('inputs', {}).items():
            if spec['type'] == 'string':
                sample_input[param] = spec.get('default', 'example_value')
            elif spec['type'] == 'number':
                sample_input[param] = spec.get('default', 10)
            elif spec['type'] == 'boolean':
                sample_input[param] = spec.get('default', False)
            elif spec['type'] == 'array':
                if param == 'peptide_sequences':
                    sample_input[param] = [
                        "SIINFEKL",
                        "GILGFVFTL",
                        "YLQPRTFLL"
                    ]
                else:
                    sample_input[param] = spec.get('default', [])
            elif spec['type'] == 'object':
                sample_input[param] = spec.get('default', {})
        
        with open(examples_dir / "sample_input.json", "w") as f:
            json.dump(sample_input, f, indent=2)
    
    def _generate_frontend(self, config: Dict[str, Any], frontend_dir: Path):
        """Generate frontend/index.tsx for UI modules"""
        
        template_str = '''/**
 * {{ description }}
 * 
 * Generated by HLA-Compass Module Wizard
 */

import React, { useState, useCallback } from 'react';
import { 
  Button, 
  Input, 
  Card, 
  Alert, 
  Space, 
  Typography, 
  Spin, 
  Table,
  Form,
  Row,
  Col,
  message 
} from 'antd';
import { SearchOutlined, ClearOutlined } from '@ant-design/icons';

const { Title, Text, Paragraph } = Typography;

interface ModuleProps {
  onExecute: (params: any) => Promise<any>;
  initialParams?: any;
}

const {{ component_name }}: React.FC<ModuleProps> = ({ onExecute, initialParams }) => {
  const [form] = Form.useForm();
  const [loading, setLoading] = useState<boolean>(false);
  const [results, setResults] = useState<any>(null);
  const [error, setError] = useState<string | null>(null);

  const handleSubmit = useCallback(async (values: any) => {
    setError(null);
    setResults(null);
    setLoading(true);

    try {
      const result = await onExecute(values);
      
      if (result.status === 'success') {
        setResults(result);
        message.success('Processing completed successfully');
      } else {
        setError(result.error?.message || 'Processing failed');
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'An unexpected error occurred');
    } finally {
      setLoading(false);
    }
  }, [onExecute]);

  const handleClear = useCallback(() => {
    form.resetFields();
    setResults(null);
    setError(null);
  }, [form]);

  return (
    <div style={{ padding: '20px', maxWidth: '1200px', margin: '0 auto' }}>
      <Card>
        <Title level={3}>{{ name }}</Title>
        <Paragraph>{{ description }}</Paragraph>
      </Card>

      <Card style={{ marginTop: '20px' }}>
        <Form
          form={form}
          layout="vertical"
          onFinish={handleSubmit}
          initialValues={initialParams}
        >
          {{ form_fields }}
          
          <Space>
            <Button
              type="primary"
              icon={<SearchOutlined />}
              htmlType="submit"
              loading={loading}
              size="large"
            >
              Process
            </Button>
            <Button
              icon={<ClearOutlined />}
              onClick={handleClear}
              disabled={loading}
              size="large"
            >
              Clear
            </Button>
          </Space>
        </Form>
      </Card>

      {error && (
        <Alert
          message="Error"
          description={error}
          type="error"
          showIcon
          closable
          onClose={() => setError(null)}
          style={{ marginTop: '20px' }}
        />
      )}

      {loading && (
        <Card style={{ marginTop: '20px', textAlign: 'center' }}>
          <Spin size="large" />
          <div style={{ marginTop: '10px' }}>
            <Text>Processing your request...</Text>
          </div>
        </Card>
      )}

      {results && !loading && (
        <Card style={{ marginTop: '20px' }}>
          <Title level={4}>Results</Title>
          {{ results_display }}
        </Card>
      )}
    </div>
  );
};

export default {{ component_name }};
'''
        
        component_name = self._to_class_name(config['name']) + 'UI'
        form_fields = self._generate_form_fields(config)
        results_display = self._generate_results_display(config)
        
        template = self.env.from_string(template_str)
        code = template.render(
            name=config['name'],
            description=config.get('description', ''),
            component_name=component_name,
            form_fields=form_fields,
            results_display=results_display
        )
        
        with open(frontend_dir / "index.tsx", "w") as f:
            f.write(code)
    
    def _generate_package_json(self, config: Dict[str, Any], frontend_dir: Path):
        """Generate or merge package.json for frontend with Tailwind v4 PostCSS config"""
        pkg_path = frontend_dir / "package.json"
        base_pkg = {
            "name": f"{config['name']}-ui",
            "version": "1.0.0",
            "description": f"UI for {config['name']}",
            "main": "index.tsx",
            "scripts": {
                "build": "webpack --mode production",
                "dev": "webpack-dev-server --mode development",
                "test": "jest"
            },
            "dependencies": {
                "react": "^18.2.0",
                "react-dom": "^18.2.0",
                "antd": "^5.10.0",
                "@ant-design/icons": "^5.2.0"
            },
            "devDependencies": {
                "@types/react": "^18.2.0",
                "@types/react-dom": "^18.2.0",
                "typescript": "^5.2.0",
                "webpack": "^5.88.0",
                "webpack-cli": "^5.1.0",
                "webpack-dev-server": "^4.15.0",
                "ts-loader": "^9.4.0",
                "css-loader": "^6.8.0",
                "style-loader": "^3.3.0",
                "tailwindcss": "^4.1.13",
                "@tailwindcss/postcss": "^4.1.13",
                "autoprefixer": "^10.4.20",
                "postcss": "^8.5.1",
                "postcss-loader": "^8.1.0"
            }
        }

        if pkg_path.exists():
            try:
                with open(pkg_path, "r") as f:
                    existing = json.load(f)
            except Exception:
                existing = {}
            # Merge: preserve existing dependencies/devDependencies, override name/description/scripts minimally
            pkg = existing or {}
            pkg.setdefault("name", base_pkg["name"])  # don't force rename if user edited
            pkg.setdefault("version", base_pkg["version"])
            pkg.setdefault("description", base_pkg["description"])
            scripts = pkg.get("scripts", {})
            scripts.setdefault("build", base_pkg["scripts"]["build"])
            scripts.setdefault("dev", base_pkg["scripts"]["dev"])
            scripts.setdefault("test", base_pkg["scripts"]["test"])
            pkg["scripts"] = scripts
            deps = pkg.get("dependencies", {})
            deps.setdefault("react", base_pkg["dependencies"]["react"])
            deps.setdefault("react-dom", base_pkg["dependencies"]["react-dom"])
            deps.setdefault("antd", base_pkg["dependencies"]["antd"])
            deps.setdefault("@ant-design/icons", base_pkg["dependencies"]["@ant-design/icons"])
            pkg["dependencies"] = deps
            dev_deps = pkg.get("devDependencies", {})
            for k, v in base_pkg["devDependencies"].items():
                dev_deps.setdefault(k, v)
            pkg["devDependencies"] = dev_deps
        else:
            pkg = base_pkg

        with open(pkg_path, "w") as f:
            json.dump(pkg, f, indent=2)
    
    def _generate_readme(self, config: Dict[str, Any], output_dir: Path):
        """Generate README.md"""
        readme_template = """# $module_name

$description

A tutorial-style guide to develop, test, and publish this module on the HLA-Compass platform.

---

## 1) Prerequisites

- Python 3.11+
- Node.js 18+ (for UI modules)
- HLA-Compass SDK installed or available in this repository

Install Python deps:

```bash
pip install -r backend/requirements.txt
```

For UI modules, install frontend deps:

```bash
cd frontend
npm install
```

---

## 2) Start the Dev Server (single origin)

The dev server provides:
- / → backend testing UI
- /api/* → module dev endpoints (execute, status, manifest)
- /dev/* → local-only endpoints (local data listing/streaming)
- /ui → frontend dev server proxy (when enabled)

Offline (all local):

```bash
hla-compass dev
```

Online selective (use real /auth and /data APIs; read-only):

```bash
hla-compass dev \
  --online --env dev \
  --proxy-routes=auth,data \
  --frontend-proxy --frontend-port 3000 \
  --ca-bundle /etc/ssl/cert.pem
```

Notes:
- Use `hla-compass auth login --env dev` before online mode.
- `--ca-bundle` points to a PEM bundle if your local trust store needs it.

---

## 3) Execute Locally (backend)

From a second terminal (or via the dev UI at /):

```bash
# Quick local run using example input
hla-compass test --input examples/sample_input.json

# Or via HTTP against the dev server
curl -s -X POST -H 'Content-Type: application/json' \
  -d @examples/sample_input.json \
  http://localhost:8080/api/execute | jq
```

### Input Parameters

$inputs_doc

### Output Format

$outputs_doc

---

## 4) Frontend (UI modules)

Open the dev UI: http://localhost:8080/ui

The frontend template includes a tiny API client `frontend/api.ts`:

```ts
import { apiGet, devPost } from './api';

// Execute the module locally through the dev server
const result = await devPost('/execute', { input: { /* params */ } });

// Fetch real API data (works when dev server runs with --online)
const samples = await apiGet('/data/alithea-bio/immunopeptidomics/samples?page=1&limit=5&data_source=alithea-hla-db');
```

### Local Data Browser

UI includes a Local Data Browser that uses:
- `GET /dev/data/roots` → list configured roots
- `GET /dev/data/list?root=...&subdir=...` → list files/dirs
- `GET /dev/data/file?root=...&path=...` → stream a file

Configure roots in `.hla-compass-dev.json` (created at module root).

---

## 5) Validate, Build, and Publish

Validate structure and manifest:

```bash
hla-compass validate
```

Build and sign package:

```bash
hla-compass build
```

Publish (uploads package and registers metadata):

```bash
hla-compass publish --env dev
```

List modules in your account:

```bash
hla-compass list --env dev
```

---

## 6) Accessing Platform Data and SQL

For data access patterns and SQL guidance, see the platform guide:
- `docs/SQL_ACCESS_DEVELOPER_GUIDE.md`

Typical patterns:

- Prefer API data clients exposed via the SDK for read access ({'peptides' if True else ''}):

```python
from hla_compass import Module

class MyModule(Module):
    def execute(self, input_data, context):
        # API client is initialized by the SDK; helpers available if configured
        samples = getattr(self, 'samples', None)
        if samples:
            # Example usage: fetch by filters (pseudo-code)
            # results = samples.search(provider='alithea-bio', catalog='immunopeptidomics', ...)
            pass
        return self.success([])
```

- RDS Data API / direct SQL (where allowed): see SQL guide. In Lambda, SDK may expose `self.db` (ScientificQuery) when configured:

```python
# Pseudo-code; see SQL_ACCESS_DEVELOPER_GUIDE.md for exact usage
q = getattr(self, 'db', None)
if q:
    rows = q.query('SELECT * FROM my_table WHERE id = :id', params={'id': '123'})
```

Important:
- Keep SQL read-only in dev unless explicitly allowed.
- Use parameterized queries; never interpolate user inputs.

---

## 7) Troubleshooting

- 401 from /api/data/* → Run `hla-compass auth login --env dev` to refresh token.
- TLS verify failures → start dev server with `--ca-bundle /path/to/ca.pem`.
- Frontend not at /ui → ensure `--frontend-proxy` is enabled and the UI dev server started.
- Writes blocked → proxy is read-only by default; enable writes only if approved.

---

## Author

$author_name <$author_email>

---
Generated by HLA-Compass Module Wizard
"""
        
        mapping = {
            'module_name': config['name'],
            'description': config.get('description', 'HLA-Compass module'),
            'inputs_doc': self._document_inputs(config),
            'outputs_doc': self._document_outputs(config),
            'author_name': config.get('author', {}).get('name', 'Developer'),
            'author_email': config.get('author', {}).get('email', 'developer@example.com'),
        }
        readme = StrTemplate(readme_template).safe_substitute(mapping)
        
        with open(output_dir / "README.md", "w") as f:
            f.write(readme)
    
    # Helper methods
    
    def _to_class_name(self, name: str) -> str:
        """Convert module name to class name"""
        parts = name.replace('-', '_').replace(' ', '_').split('_')
        return ''.join(p.capitalize() for p in parts) + 'Module'
    
    def _describe_inputs(self, config: Dict[str, Any]) -> str:
        """Generate input description"""
        inputs = config.get('inputs', {})
        if not inputs:
            return "No input parameters"
        
        descriptions = []
        for param, spec in inputs.items():
            desc = f"{param} ({spec['type']})"
            if spec.get('description'):
                desc += f" - {spec['description']}"
            descriptions.append(desc)
        
        return "Input parameters: " + ", ".join(descriptions)
    
    def _describe_outputs(self, config: Dict[str, Any]) -> str:
        """Generate output description"""
        outputs = config.get('outputs', {})
        if 'results' in outputs:
            return "processing results and summary"
        elif 'table' in outputs:
            return "tabular data"
        elif 'report' in outputs:
            return "formatted report"
        else:
            return "processed data"
    
    def _describe_processing(self, config: Dict[str, Any]) -> str:
        """Generate processing description"""
        proc_type = config.get('processing_type', 'processes data')
        if 'Sequence analysis' in proc_type:
            return "analyzes peptide sequences"
        elif 'Statistical analysis' in proc_type:
            return "performs statistical analysis"
        elif 'Machine learning' in proc_type:
            return "applies machine learning algorithms"
        else:
            return "processes input data"
    
    def _generate_processing_logic(self, config: Dict[str, Any]) -> str:
        """Generate processing logic code"""
        proc_type = config.get('processing_type', '')
        
        if 'Sequence analysis' in proc_type:
            return """
        # Example: Analyze peptide sequences
        if not peptide_sequences:
            return []

        results = []
        for seq in peptide_sequences:
            if not seq:
                continue

            sequence = str(seq).strip()
            if not sequence:
                continue

            # Calculate properties
            length = len(sequence)
            hydrophobicity = self._calculate_hydrophobicity(sequence)
            
            results.append({
                'sequence': sequence,
                'length': length,
                'hydrophobicity': hydrophobicity
            })
        """
        elif 'Machine learning' in proc_type:
            return """
        # Example: Apply ML model
        # features = self._extract_features(input_data)
        # predictions = self.model.predict(features)
        
        results = {
            'predictions': [],
            'confidence': []
        }
        """
        else:
            return """
        # TODO: Implement your processing logic here
        # Minimal placeholder to demonstrate structure
        results = [
            {
                'id': 'example-1',
                'value': 'OK',
                'processed': True
            }
        ]
        """

    def _generate_helper_methods(self, config: Dict[str, Any]) -> str:
        """Generate additional helper methods based on processing type."""
        proc_type = config.get('processing_type', '')

        if 'Sequence analysis' in proc_type:
            return """
    def _calculate_hydrophobicity(self, sequence: str) -> float:
        \"\"\"Calculate average hydrophobicity using the Kyte-Doolittle scale.\"\"\"
        if not sequence:
            return 0.0

        scale = {
            'A': 1.8,
            'R': -4.5,
            'N': -3.5,
            'D': -3.5,
            'C': 2.5,
            'Q': -3.5,
            'E': -3.5,
            'G': -0.4,
            'H': -3.2,
            'I': 4.5,
            'L': 3.8,
            'K': -3.9,
            'M': 1.9,
            'F': 2.8,
            'P': -1.6,
            'S': -0.8,
            'T': -0.7,
            'W': -0.9,
            'Y': -1.3,
            'V': 4.2,
        }

        total = 0.0
        counted = 0
        for residue in sequence.upper():
            value = scale.get(residue)
            if value is None:
                continue
            total += value
            counted += 1

        if counted == 0:
            return 0.0

        return total / counted
"""

        return ""
    
    def _generate_output_formatting(self, config: Dict[str, Any]) -> str:
        """Generate output formatting code"""
        outputs = config.get('outputs', {})
        
        if 'summary' in outputs:
            return """
            # Generate summary
            summary = {
                'total': len(results),
                'processed': len([r for r in results if r.get('processed')]),
                'timestamp': datetime.now().isoformat()
            }"""
        else:
            return "# Format output as needed"
    
    def _generate_success_return(self, config: Dict[str, Any]) -> str:
        """Generate success return statement"""
        outputs = config.get('outputs', {})
        
        if 'results' in outputs and 'summary' in outputs:
            return "results=results,\n                summary=summary"
        elif 'table' in outputs:
            return "table=results,\n                columns=list(results[0].keys()) if results else []"
        else:
            return "results=results"
    
    def _generate_form_fields(self, config: Dict[str, Any]) -> str:
        """Generate form fields for React component"""
        fields = []
        
        for param, spec in config.get('inputs', {}).items():
            if spec['type'] == 'string':
                if 'sequences' in param:
                    field = f'''
          <Form.Item
            label="{param.replace('_', ' ').title()}"
            name="{param}"
            rules={{[{{ required: {str(spec.get('required', False)).lower()}, message: 'This field is required' }}]}}
          >
            <Input.TextArea 
              rows={{4}}
              placeholder="Enter sequences (one per line)"
            />
          </Form.Item>'''
                else:
                    field = f'''
          <Form.Item
            label="{param.replace('_', ' ').title()}"
            name="{param}"
            rules={{[{{ required: {str(spec.get('required', False)).lower()}, message: 'This field is required' }}]}}
          >
            <Input placeholder="Enter {param.replace('_', ' ')}" />
          </Form.Item>'''
            elif spec['type'] == 'number':
                field = f'''
          <Form.Item
            label="{param.replace('_', ' ').title()}"
            name="{param}"
            rules={{[{{ required: {str(spec.get('required', False)).lower()}, message: 'This field is required' }}]}}
          >
            <InputNumber min={{0}} placeholder="Enter value" />
          </Form.Item>'''
            else:
                continue
            
            fields.append(field)
        
        return '\n'.join(fields)
    
    def _generate_results_display(self, config: Dict[str, Any]) -> str:
        """Generate results display for React component"""
        outputs = config.get('outputs', {})
        
        if 'table' in outputs:
            return '''
          <Table
            dataSource={results.table}
            columns={results.columns?.map((col: string) => ({
              title: col,
              dataIndex: col,
              key: col
            }))}
            pagination={{ pageSize: 10 }}
          />'''
        else:
            return '''
          <pre style={{ background: '#f5f5f5', padding: '10px', borderRadius: '4px' }}>
            {JSON.stringify(results, null, 2)}
          </pre>'''
    
    def _document_inputs(self, config: Dict[str, Any]) -> str:
        """Document input parameters for README"""
        inputs = config.get('inputs', {})
        if not inputs:
            return "No input parameters required."
        
        lines = []
        for param, spec in inputs.items():
            line = f"- **{param}** ({spec['type']})"
            if spec.get('required'):
                line += " [Required]"
            if spec.get('description'):
                line += f": {spec['description']}"
            lines.append(line)
        
        return '\n'.join(lines)
    
    def _document_outputs(self, config: Dict[str, Any]) -> str:
        """Document output format for README"""
        outputs = config.get('outputs', {})
        if not outputs:
            return "No specific output format."
        
        lines = []
        for field, spec in outputs.items():
            line = f"- **{field}** ({spec['type']})"
            if spec.get('description'):
                line += f": {spec['description']}"
            lines.append(line)
        
        return '\n'.join(lines)
