(function attachRecipeStepEditor(global) {
  const React = global.React;
  if (!React) return;

  function RecipeStepEditor({ step, index, stepTypes, onChange, onMove, onRemove }) {
    const current = step || {};
    const types = stepTypes || [];
    function update(patch) { onChange && onChange(Object.assign({}, current, patch)); }
    function updateConfig(value) {
      try { update({ config: JSON.parse(value || '{}') }); }
      catch (error) { update({ configText: value }); }
    }
    const configText = current.configText !== undefined ? current.configText : JSON.stringify(current.config || {}, null, 2);
    return <article className="mini-card recipe-step-editor">
      <div className="row between"><h3>Step {index + 1}</h3><div className="row gap small"><button type="button" className="button ghost" onClick={() => onMove && onMove(-1)}>Up</button><button type="button" className="button ghost" onClick={() => onMove && onMove(1)}>Down</button><button type="button" className="button danger" onClick={onRemove}>Remove</button></div></div>
      <div className="grid two">
        <label>ID<input value={current.id || ''} onChange={(e) => update({ id: e.target.value })} /></label>
        <label>Type<select value={current.type || ''} onChange={(e) => update({ type: e.target.value })}>{types.map((type) => <option key={type.type} value={type.type}>{type.label || type.type}</option>)}</select></label>
        <label>Name<input value={current.name || ''} onChange={(e) => update({ name: e.target.value })} /></label>
        <label>Depends on, comma separated<input value={(current.dependsOn || []).join(', ')} onChange={(e) => update({ dependsOn: e.target.value.split(',').map((item) => item.trim()).filter(Boolean) })} /></label>
      </div>
      <label>Config JSON<textarea rows="5" value={configText} onChange={(e) => updateConfig(e.target.value)} /></label>
    </article>;
  }

  global.RecipeStepEditor = RecipeStepEditor;
})(window);
