# Dynamic Config Form System

## Overview
The Dynamic Config Form system is a schema-driven UI component designed to automatically generate configuration forms based on backend Pydantic models. It supports rich metadata for UI customization and a flexible Hook system for complex fields.

### Core Components
- **DynamicConfigForm**: The main component that takes a `ConfigSchema` and renders the entire form.
- **DynamicField**: A lower-level component that renders individual fields based on their type and UI metadata.
- **FieldHookRegistry**: A registry for custom React components that can replace or wrap default field rendering.

## Quick Start
To use the dynamic form in your page:

```typescript
import { DynamicConfigForm } from '@/components/dynamic-form'
import { fieldHooks } from '@/lib/field-hooks'

// Example usage in a component
export function ConfigPage() {
  const [config, setConfig] = useState({})
  const schema = useConfigSchema() // Fetch from API

  const handleChange = (fieldPath: string, value: unknown) => {
    // fieldPath can be nested, e.g., 'section.subfield'
    updateConfigAt(fieldPath, value)
  }

  return (
    <DynamicConfigForm
      schema={schema}
      values={config}
      onChange={handleChange}
      hooks={fieldHooks}
    />
  )
}
```

## Adding UI Metadata (Backend)
You can customize how fields are rendered by adding `json_schema_extra` to your Pydantic `Field` definitions.

### Supported Metadata
- `x-widget`: Specifies the UI component to use.
  - `slider`: A range slider (requires `ge`, `le`, and `step`).
  - `switch`: A toggle switch (for booleans).
  - `textarea`: A multi-line text input.
  - `select`: A dropdown menu (for `Literal` or enum types).
  - `custom`: Indicates that this field requires a Hook for rendering.
- `x-icon`: A Lucide icon name (e.g., `MessageSquare`, `Settings`).
- `step`: Incremental step for sliders or number inputs.

### Example
```python
class ChatConfig(ConfigBase):
    talk_value: float = Field(
        default=0.5,
        ge=0.0,
        le=1.0,
        json_schema_extra={
            "x-widget": "slider",
            "x-icon": "MessageSquare",
            "step": 0.1
        }
    )
```

## Creating Hook Components
Hooks allow you to provide custom UI for complex configuration sections or fields.

### FieldHookComponent Interface
A Hook component receives the following props:
- `fieldPath`: The full path to the field.
- `value`: The current value of the field/section.
- `onChange`: Callback to update the value.
- `children`: (Only for `wrapper` hooks) The default field renderer.

### Implementation Example
```typescript
import type { FieldHookComponent } from '@/lib/field-hooks'

export const CustomSectionHook: FieldHookComponent = ({
  fieldPath,
  value,
  onChange
}) => {
  return (
    <div className="custom-section">
      <h3>Custom UI</h3>
      <input 
        value={value.some_prop} 
        onChange={(e) => onChange({ ...value, some_prop: e.target.value })}
      />
    </div>
  )
}
```

### Registering Hooks
Register hooks in your component's lifecycle:
```typescript
useEffect(() => {
  fieldHooks.register('chat', ChatSectionHook, 'replace')
  return () => fieldHooks.unregister('chat')
}, [])
```

## API Reference

### DynamicConfigForm
| Prop | Type | Description |
|------|------|-------------|
| `schema` | `ConfigSchema` | The schema generated by the backend. |
| `values` | `Record<string, any>` | Current configuration values. |
| `onChange` | `(field: string, value: any) => void` | Change handler. |
| `hooks` | `FieldHookRegistry` | Optional custom hook registry. |

### FieldHookRegistry
- `register(path, component, type)`: Register a hook.
- `get(path)`: Retrieve a registered hook.
- `has(path)`: Check if a hook exists.
- `unregister(path)`: Remove a hook.

## Troubleshooting
- **Hook not rendering**: Ensure the registration path matches the schema field name exactly (e.g., `chat` vs `Chat`).
- **Field missing**: Check if the field is present in the `ConfigSchema` returned by the backend.
- **TypeScript errors**: Ensure your Hook implements the `FieldHookComponent` type.
