/**
 * Dedicated settings screen for providers, task model bindings, and catalog controls.
 */
import { useCallback, useEffect, useMemo, useState } from 'react';

import PathInput from './PathInput';
import TagInput from './TagInput';
import type {
  AppSettings,
  AppSettingsUpdate,
  DisplaySettings,
  HandwritingStyleClusteringSettings,
  OcrTaskSettings,
  PredefinedPathEntry,
  PredefinedTagEntry,
  ProviderSettings,
  RoutingTaskSettings,
  SummaryTaskSettings,
  UploadDefaultsSettings,
} from '../types';

interface EditableProvider extends ProviderSettings {
  row_id: string;
  api_key: string;
  clear_api_key: boolean;
}

interface SettingsScreenProps {
  settings: AppSettings | null;
  isSaving: boolean;
  knownTags: string[];
  knownPaths: string[];
  onSave: (payload: AppSettingsUpdate) => Promise<void>;
  onRegisterSaveAction?: (action: (() => Promise<void>) | null) => void;
}

function clampCardsPerPage(value: number): number {
  return Math.max(1, Math.min(200, value));
}

function parseCardsPerPageInput(input: string, fallback: number): number {
  const parsed = Number.parseInt(input, 10);
  if (Number.isNaN(parsed)) {
    return clampCardsPerPage(fallback);
  }
  return clampCardsPerPage(parsed);
}

/**
 * Renders compact human-oriented settings controls.
 */
export default function SettingsScreen({
  settings,
  isSaving,
  knownTags,
  knownPaths,
  onSave,
  onRegisterSaveAction,
}: SettingsScreenProps): JSX.Element {
  const [providers, setProviders] = useState<EditableProvider[]>([]);
  const [ocrTask, setOcrTask] = useState<OcrTaskSettings | null>(null);
  const [summaryTask, setSummaryTask] = useState<SummaryTaskSettings | null>(null);
  const [routingTask, setRoutingTask] = useState<RoutingTaskSettings | null>(null);
  const [handwritingStyle, setHandwritingStyle] = useState<HandwritingStyleClusteringSettings | null>(null);
  const [predefinedPaths, setPredefinedPaths] = useState<PredefinedPathEntry[]>([]);
  const [predefinedTags, setPredefinedTags] = useState<PredefinedTagEntry[]>([]);
  const [newPredefinedPath, setNewPredefinedPath] = useState<string>('');
  const [newPredefinedTag, setNewPredefinedTag] = useState<string>('');
  const [uploadDefaults, setUploadDefaults] = useState<UploadDefaultsSettings | null>(null);
  const [displaySettings, setDisplaySettings] = useState<DisplaySettings | null>(null);
  const [cardsPerPageInput, setCardsPerPageInput] = useState<string>('12');
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!settings) {
      return;
    }
    setProviders(
      settings.providers.map((provider) => ({
        ...provider,
        row_id: `${provider.id}-${Math.random().toString(36).slice(2, 9)}`,
        api_key: '',
        clear_api_key: false,
      })),
    );
    setOcrTask(settings.tasks.ocr_handwriting);
    setSummaryTask(settings.tasks.summary_generation);
    setRoutingTask(settings.tasks.routing_classification);
    setHandwritingStyle(settings.handwriting_style_clustering);
    setPredefinedPaths(settings.predefined_paths);
    setPredefinedTags(settings.predefined_tags);
    setUploadDefaults(settings.upload_defaults);
    setDisplaySettings(settings.display);
    setCardsPerPageInput(String(settings.display.cards_per_page));
    setError(null);
  }, [settings]);

  const fallbackProviderId = useMemo(() => providers[0]?.id ?? '', [providers]);

  const addProvider = (): void => {
    const sequence = providers.length + 1;
    setProviders((current) => [
      ...current,
      {
        row_id: `provider-row-${Date.now()}-${sequence}`,
        id: `provider-${sequence}`,
        label: `Provider ${sequence}`,
        provider_type: 'openai_compatible',
        base_url: 'http://localhost:11434/v1',
        timeout_seconds: 45,
        api_key_set: false,
        api_key_masked: '',
        api_key: '',
        clear_api_key: false,
      },
    ]);
  };

  const removeProvider = (rowId: string): void => {
    const target = providers.find((provider) => provider.row_id === rowId);
    if (!target || providers.length <= 1) {
      return;
    }
    const remaining = providers.filter((provider) => provider.row_id !== rowId);
    const fallback = remaining[0]?.id ?? '';
    setProviders(remaining);
    if (ocrTask?.provider_id === target.id && fallback) {
      setOcrTask({ ...ocrTask, provider_id: fallback });
    }
    if (summaryTask?.provider_id === target.id && fallback) {
      setSummaryTask({ ...summaryTask, provider_id: fallback });
    }
    if (routingTask?.provider_id === target.id && fallback) {
      setRoutingTask({ ...routingTask, provider_id: fallback });
    }
  };

  const addPredefinedPath = (): void => {
    const value = newPredefinedPath.trim().replace(/^\/+|\/+$/g, '');
    if (!value) {
      return;
    }
    if (predefinedPaths.some((entry) => entry.value.toLowerCase() === value.toLowerCase())) {
      setNewPredefinedPath('');
      return;
    }
    setPredefinedPaths([...predefinedPaths, { value, global_shared: false }]);
    setNewPredefinedPath('');
  };

  const addPredefinedTag = (): void => {
    const value = newPredefinedTag.trim();
    if (!value) {
      return;
    }
    if (predefinedTags.some((entry) => entry.value.toLowerCase() === value.toLowerCase())) {
      setNewPredefinedTag('');
      return;
    }
    setPredefinedTags([...predefinedTags, { value, global_shared: false }]);
    setNewPredefinedTag('');
  };

  const handleSave = useCallback(async (): Promise<void> => {
    if (!ocrTask || !summaryTask || !routingTask || !handwritingStyle || !uploadDefaults || !displaySettings) {
      setError('Settings are not fully loaded yet');
      return;
    }
    if (providers.length === 0) {
      setError('At least one provider is required');
      return;
    }

    setError(null);
    try {
      const resolvedCardsPerPage = parseCardsPerPageInput(cardsPerPageInput, displaySettings.cards_per_page);
      setDisplaySettings({ ...displaySettings, cards_per_page: resolvedCardsPerPage });
      setCardsPerPageInput(String(resolvedCardsPerPage));

      await onSave({
        upload_defaults: {
          logical_path: uploadDefaults.logical_path.trim(),
          tags: uploadDefaults.tags,
        },
        display: {
          cards_per_page: resolvedCardsPerPage,
          log_typing_animation_enabled: displaySettings.log_typing_animation_enabled,
        },
        predefined_paths: predefinedPaths,
        predefined_tags: predefinedTags,
        handwriting_style_clustering: {
          enabled: handwritingStyle.enabled,
          embed_model: handwritingStyle.embed_model.trim(),
          neighbor_limit: handwritingStyle.neighbor_limit,
          match_min_similarity: handwritingStyle.match_min_similarity,
          bootstrap_match_min_similarity: handwritingStyle.bootstrap_match_min_similarity,
          bootstrap_sample_size: handwritingStyle.bootstrap_sample_size,
          image_max_side: handwritingStyle.image_max_side,
        },
        providers: providers.map((provider) => ({
          id: provider.id.trim(),
          label: provider.label.trim(),
          provider_type: provider.provider_type,
          base_url: provider.base_url.trim(),
          timeout_seconds: provider.timeout_seconds,
          api_key: provider.api_key.trim() || undefined,
          clear_api_key: provider.clear_api_key,
        })),
        tasks: {
          ocr_handwriting: {
            enabled: ocrTask.enabled,
            provider_id: ocrTask.provider_id,
            model: ocrTask.model.trim(),
            prompt: ocrTask.prompt,
          },
          summary_generation: {
            enabled: summaryTask.enabled,
            provider_id: summaryTask.provider_id,
            model: summaryTask.model.trim(),
            prompt: summaryTask.prompt,
            max_input_tokens: summaryTask.max_input_tokens,
          },
          routing_classification: {
            enabled: routingTask.enabled,
            provider_id: routingTask.provider_id,
            model: routingTask.model.trim(),
            prompt: routingTask.prompt,
            neighbor_count: routingTask.neighbor_count,
            neighbor_min_similarity: routingTask.neighbor_min_similarity,
            auto_apply_confidence_threshold: routingTask.auto_apply_confidence_threshold,
            auto_apply_neighbor_similarity_threshold: routingTask.auto_apply_neighbor_similarity_threshold,
            neighbor_path_override_enabled: routingTask.neighbor_path_override_enabled,
            neighbor_path_override_min_similarity: routingTask.neighbor_path_override_min_similarity,
            neighbor_path_override_min_gap: routingTask.neighbor_path_override_min_gap,
            neighbor_path_override_max_confidence: routingTask.neighbor_path_override_max_confidence,
          },
        },
      });
    } catch (caughtError) {
      setError(caughtError instanceof Error ? caughtError.message : 'Failed to save settings');
    }
  }, [
    cardsPerPageInput,
    displaySettings,
    handwritingStyle,
    ocrTask,
    onSave,
    predefinedPaths,
    predefinedTags,
    providers,
    routingTask,
    summaryTask,
    uploadDefaults,
  ]);

  useEffect(() => {
    if (!onRegisterSaveAction) {
      return;
    }
    if (!settings || !ocrTask || !summaryTask || !routingTask || !handwritingStyle || !uploadDefaults || !displaySettings) {
      onRegisterSaveAction(null);
      return;
    }
    onRegisterSaveAction(() => handleSave());
    return () => onRegisterSaveAction(null);
  }, [displaySettings, handleSave, handwritingStyle, ocrTask, onRegisterSaveAction, routingTask, settings, summaryTask, uploadDefaults]);

  if (!settings || !ocrTask || !summaryTask || !routingTask || !handwritingStyle || !uploadDefaults || !displaySettings) {
    return (
      <section className="settings-layout">
        <div className="settings-card">
          <h2>Settings</h2>
          <p>Loading settings...</p>
        </div>
      </section>
    );
  }

  return (
    <section className="settings-layout">
      {error && <p className="error-banner">{error}</p>}

      <div className="settings-card settings-section">
        <div className="settings-section-header">
          <h3>Workspace</h3>
          <p className="small">Defaults and display behavior for document operations.</p>
        </div>
        <div className="settings-field-grid">
          <label className="settings-field settings-field-wide">
            Default Path
            <PathInput
              value={uploadDefaults.logical_path}
              onChange={(nextPath) => setUploadDefaults({ ...uploadDefaults, logical_path: nextPath })}
              suggestions={knownPaths}
            />
          </label>
          <label className="settings-field settings-field-wide">
            Default Tags
            <TagInput
              value={uploadDefaults.tags}
              onChange={(nextTags) => setUploadDefaults({ ...uploadDefaults, tags: nextTags })}
              suggestions={knownTags}
            />
          </label>
          <label className="settings-field">
            Cards Per Page
            <input
              type="number"
              min={1}
              max={200}
              value={cardsPerPageInput}
              onChange={(event) => setCardsPerPageInput(event.target.value)}
            />
          </label>
          <label className="inline-checkbox settings-checkbox-field">
            <input
              type="checkbox"
              checked={displaySettings.log_typing_animation_enabled}
              onChange={(event) =>
                setDisplaySettings({ ...displaySettings, log_typing_animation_enabled: event.target.checked })
              }
            />
            Processing log typing animation enabled
          </label>
        </div>
      </div>

      <div className="settings-card settings-section">
        <div className="settings-section-header">
          <h3>Catalog Presets</h3>
          <p className="small">Pre-register allowed paths and tags. Global-shared is irreversible.</p>
        </div>
        <div className="settings-catalog-grid">
          <section className="settings-catalog-card">
            <h4>Predefined Paths</h4>
            <div className="settings-catalog-add-row">
              <input
                placeholder="Add path"
                value={newPredefinedPath}
                onChange={(event) => setNewPredefinedPath(event.target.value)}
              />
              <button type="button" className="secondary-action" onClick={addPredefinedPath}>
                Add
              </button>
            </div>
            <div className="settings-catalog-list">
              {predefinedPaths.map((entry) => (
                <div key={entry.value} className="settings-catalog-row">
                  <span>{entry.value}</span>
                  <label className="inline-checkbox">
                    <input
                      type="checkbox"
                      checked={entry.global_shared}
                      disabled={entry.global_shared}
                      onChange={(event) =>
                        setPredefinedPaths((current) =>
                          current.map((item) =>
                            item.value === entry.value
                              ? { ...item, global_shared: item.global_shared || event.target.checked }
                              : item,
                          ),
                        )
                      }
                    />
                    Global
                  </label>
                  <button
                    type="button"
                    className="secondary-action"
                    onClick={() => setPredefinedPaths((current) => current.filter((item) => item.value !== entry.value))}
                  >
                    Remove
                  </button>
                </div>
              ))}
            </div>
          </section>
          <section className="settings-catalog-card">
            <h4>Predefined Tags</h4>
            <div className="settings-catalog-add-row">
              <input
                placeholder="Add tag"
                value={newPredefinedTag}
                onChange={(event) => setNewPredefinedTag(event.target.value)}
              />
              <button type="button" className="secondary-action" onClick={addPredefinedTag}>
                Add
              </button>
            </div>
            <div className="settings-catalog-list">
              {predefinedTags.map((entry) => (
                <div key={entry.value} className="settings-catalog-row">
                  <span>{entry.value}</span>
                  <label className="inline-checkbox">
                    <input
                      type="checkbox"
                      checked={entry.global_shared}
                      disabled={entry.global_shared}
                      onChange={(event) =>
                        setPredefinedTags((current) =>
                          current.map((item) =>
                            item.value === entry.value
                              ? { ...item, global_shared: item.global_shared || event.target.checked }
                              : item,
                          ),
                        )
                      }
                    />
                    Global
                  </label>
                  <button
                    type="button"
                    className="secondary-action"
                    onClick={() => setPredefinedTags((current) => current.filter((item) => item.value !== entry.value))}
                  >
                    Remove
                  </button>
                </div>
              ))}
            </div>
          </section>
        </div>
      </div>

      <div className="settings-card settings-section">
        <div className="settings-section-header">
          <h3>Providers</h3>
          <p className="small">Configure OpenAI-compatible model endpoints.</p>
        </div>
        <div className="provider-list">
          {providers.map((provider, index) => (
            <div key={provider.row_id} className="provider-grid">
              <div className="provider-header">
                <h4>{provider.label || `Provider ${index + 1}`}</h4>
                <button
                  type="button"
                  className="danger-action"
                  onClick={() => removeProvider(provider.row_id)}
                  disabled={providers.length <= 1 || isSaving}
                >
                  Remove
                </button>
              </div>
              <div className="settings-field-grid">
                <label className="settings-field">
                  Provider ID
                  <input
                    value={provider.id}
                    onChange={(event) =>
                      setProviders((current) =>
                        current.map((item) => (item.row_id === provider.row_id ? { ...item, id: event.target.value } : item)),
                      )
                    }
                  />
                </label>
                <label className="settings-field">
                  Label
                  <input
                    value={provider.label}
                    onChange={(event) =>
                      setProviders((current) =>
                        current.map((item) =>
                          item.row_id === provider.row_id ? { ...item, label: event.target.value } : item,
                        ),
                      )
                    }
                  />
                </label>
                <label className="settings-field">
                  Timeout Seconds
                  <input
                    type="number"
                    value={provider.timeout_seconds}
                    onChange={(event) => {
                      const nextTimeout = Number.parseInt(event.target.value, 10);
                      if (Number.isNaN(nextTimeout)) {
                        return;
                      }
                      setProviders((current) =>
                        current.map((item) =>
                          item.row_id === provider.row_id ? { ...item, timeout_seconds: nextTimeout } : item,
                        ),
                      );
                    }}
                  />
                </label>
                <label className="settings-field settings-field-wide">
                  Base URL
                  <input
                    value={provider.base_url}
                    onChange={(event) =>
                      setProviders((current) =>
                        current.map((item) =>
                          item.row_id === provider.row_id ? { ...item, base_url: event.target.value } : item,
                        ),
                      )
                    }
                  />
                </label>
                <label className="settings-field settings-field-wide">
                  API Key
                  <input
                    type="password"
                    placeholder={provider.api_key_set ? `Stored: ${provider.api_key_masked}` : 'Optional API key'}
                    value={provider.api_key}
                    onChange={(event) =>
                      setProviders((current) =>
                        current.map((item) =>
                          item.row_id === provider.row_id ? { ...item, api_key: event.target.value } : item,
                        ),
                      )
                    }
                  />
                </label>
                <label className="inline-checkbox settings-checkbox-field">
                  <input
                    type="checkbox"
                    checked={provider.clear_api_key}
                    onChange={(event) =>
                      setProviders((current) =>
                        current.map((item) =>
                          item.row_id === provider.row_id ? { ...item, clear_api_key: event.target.checked } : item,
                        ),
                      )
                    }
                  />
                  Clear Stored API Key
                </label>
              </div>
            </div>
          ))}
        </div>
        <div className="settings-section-actions">
          <button type="button" className="secondary-action" onClick={addProvider} disabled={isSaving}>
            Add Provider
          </button>
        </div>
      </div>

      <div className="settings-card settings-section">
        <div className="settings-section-header">
          <h3>Task Runtime</h3>
          <p className="small">Bind providers and tune OCR, summary, routing, and handwriting style behavior.</p>
        </div>

        <div className="task-settings-block">
          <div className="task-block-header">
            <h4>OCR Handwriting</h4>
            <label className="inline-checkbox settings-toggle">
              <input type="checkbox" checked={ocrTask.enabled} onChange={(event) => setOcrTask({ ...ocrTask, enabled: event.target.checked })} />
              Enabled
            </label>
          </div>
          <div className="settings-field-grid">
            <label className="settings-field">
              Provider
              <select value={ocrTask.provider_id} onChange={(event) => setOcrTask({ ...ocrTask, provider_id: event.target.value || fallbackProviderId })}>
                {providers.map((provider) => (
                  <option key={provider.row_id} value={provider.id}>
                    {provider.label} ({provider.id})
                  </option>
                ))}
              </select>
            </label>
            <label className="settings-field">
              Model
              <input value={ocrTask.model} onChange={(event) => setOcrTask({ ...ocrTask, model: event.target.value })} />
            </label>
            <label className="settings-field settings-field-wide">
              OCR Prompt
              <textarea value={ocrTask.prompt} onChange={(event) => setOcrTask({ ...ocrTask, prompt: event.target.value })} />
            </label>
          </div>
        </div>

        <div className="task-settings-block">
          <div className="task-block-header">
            <h4>Summary Generation</h4>
            <label className="inline-checkbox settings-toggle">
              <input type="checkbox" checked={summaryTask.enabled} onChange={(event) => setSummaryTask({ ...summaryTask, enabled: event.target.checked })} />
              Enabled
            </label>
          </div>
          <div className="settings-field-grid">
            <label className="settings-field">
              Provider
              <select value={summaryTask.provider_id} onChange={(event) => setSummaryTask({ ...summaryTask, provider_id: event.target.value || fallbackProviderId })}>
                {providers.map((provider) => (
                  <option key={provider.row_id} value={provider.id}>
                    {provider.label} ({provider.id})
                  </option>
                ))}
              </select>
            </label>
            <label className="settings-field">
              Model
              <input value={summaryTask.model} onChange={(event) => setSummaryTask({ ...summaryTask, model: event.target.value })} />
            </label>
            <label className="settings-field">
              Max Input Tokens
              <input
                type="number"
                min={512}
                max={64000}
                value={summaryTask.max_input_tokens}
                onChange={(event) => {
                  const nextValue = Number.parseInt(event.target.value, 10);
                  if (!Number.isNaN(nextValue)) {
                    setSummaryTask({ ...summaryTask, max_input_tokens: nextValue });
                  }
                }}
              />
            </label>
            <label className="settings-field settings-field-wide">
              Summary Prompt
              <textarea value={summaryTask.prompt} onChange={(event) => setSummaryTask({ ...summaryTask, prompt: event.target.value })} />
            </label>
          </div>
        </div>

        <div className="task-settings-block">
          <div className="task-block-header">
            <h4>Routing Classification</h4>
            <label className="inline-checkbox settings-toggle">
              <input type="checkbox" checked={routingTask.enabled} onChange={(event) => setRoutingTask({ ...routingTask, enabled: event.target.checked })} />
              Enabled
            </label>
          </div>
          <div className="settings-field-grid">
            <label className="settings-field">
              Provider
              <select value={routingTask.provider_id} onChange={(event) => setRoutingTask({ ...routingTask, provider_id: event.target.value || fallbackProviderId })}>
                {providers.map((provider) => (
                  <option key={provider.row_id} value={provider.id}>
                    {provider.label} ({provider.id})
                  </option>
                ))}
              </select>
            </label>
            <label className="settings-field">
              Model
              <input value={routingTask.model} onChange={(event) => setRoutingTask({ ...routingTask, model: event.target.value })} />
            </label>
            <label className="settings-field">
              Neighbor Count
              <input type="number" value={routingTask.neighbor_count} onChange={(event) => setRoutingTask({ ...routingTask, neighbor_count: Number.parseInt(event.target.value, 10) || routingTask.neighbor_count })} />
            </label>
            <label className="settings-field">
              Min Neighbor Similarity
              <input type="number" step="0.01" min="0" max="1" value={routingTask.neighbor_min_similarity} onChange={(event) => setRoutingTask({ ...routingTask, neighbor_min_similarity: Number.parseFloat(event.target.value) || routingTask.neighbor_min_similarity })} />
            </label>
            <label className="settings-field">
              Auto Apply Confidence
              <input type="number" step="0.01" min="0" max="1" value={routingTask.auto_apply_confidence_threshold} onChange={(event) => setRoutingTask({ ...routingTask, auto_apply_confidence_threshold: Number.parseFloat(event.target.value) || routingTask.auto_apply_confidence_threshold })} />
            </label>
            <label className="settings-field">
              Auto Apply Neighbor Similarity
              <input type="number" step="0.01" min="0" max="1" value={routingTask.auto_apply_neighbor_similarity_threshold} onChange={(event) => setRoutingTask({ ...routingTask, auto_apply_neighbor_similarity_threshold: Number.parseFloat(event.target.value) || routingTask.auto_apply_neighbor_similarity_threshold })} />
            </label>
            <label className="inline-checkbox settings-checkbox-field">
              <input type="checkbox" checked={routingTask.neighbor_path_override_enabled} onChange={(event) => setRoutingTask({ ...routingTask, neighbor_path_override_enabled: event.target.checked })} />
              Dominant neighbor path override enabled
            </label>
            <label className="settings-field">
              Override Min Similarity
              <input type="number" step="0.01" min="0" max="1" value={routingTask.neighbor_path_override_min_similarity} onChange={(event) => setRoutingTask({ ...routingTask, neighbor_path_override_min_similarity: Number.parseFloat(event.target.value) || routingTask.neighbor_path_override_min_similarity })} />
            </label>
            <label className="settings-field">
              Override Min Gap
              <input type="number" step="0.01" min="0" max="1" value={routingTask.neighbor_path_override_min_gap} onChange={(event) => setRoutingTask({ ...routingTask, neighbor_path_override_min_gap: Number.parseFloat(event.target.value) || routingTask.neighbor_path_override_min_gap })} />
            </label>
            <label className="settings-field">
              Override Max LLM Confidence
              <input type="number" step="0.01" min="0" max="1" value={routingTask.neighbor_path_override_max_confidence} onChange={(event) => setRoutingTask({ ...routingTask, neighbor_path_override_max_confidence: Number.parseFloat(event.target.value) || routingTask.neighbor_path_override_max_confidence })} />
            </label>
            <label className="settings-field settings-field-wide">
              Routing Prompt
              <textarea value={routingTask.prompt} onChange={(event) => setRoutingTask({ ...routingTask, prompt: event.target.value })} />
            </label>
          </div>
        </div>

        <div className="task-settings-block">
          <div className="task-block-header">
            <h4>Handwriting Style Clustering</h4>
            <label className="inline-checkbox settings-toggle">
              <input type="checkbox" checked={handwritingStyle.enabled} onChange={(event) => setHandwritingStyle({ ...handwritingStyle, enabled: event.target.checked })} />
              Enabled
            </label>
          </div>
          <div className="settings-field-grid">
            <label className="settings-field settings-field-wide">
              Typesense Embedding Model Slug
              <input value={handwritingStyle.embed_model} onChange={(event) => setHandwritingStyle({ ...handwritingStyle, embed_model: event.target.value })} />
            </label>
            <label className="settings-field">
              Neighbor Limit
              <input type="number" min={1} max={32} value={handwritingStyle.neighbor_limit} onChange={(event) => setHandwritingStyle({ ...handwritingStyle, neighbor_limit: Number.parseInt(event.target.value, 10) || handwritingStyle.neighbor_limit })} />
            </label>
            <label className="settings-field">
              Match Min Similarity
              <input type="number" step="0.01" min="0" max="1" value={handwritingStyle.match_min_similarity} onChange={(event) => setHandwritingStyle({ ...handwritingStyle, match_min_similarity: Number.parseFloat(event.target.value) || handwritingStyle.match_min_similarity })} />
            </label>
            <label className="settings-field">
              Bootstrap Match Min Similarity
              <input type="number" step="0.01" min="0" max="1" value={handwritingStyle.bootstrap_match_min_similarity} onChange={(event) => setHandwritingStyle({ ...handwritingStyle, bootstrap_match_min_similarity: Number.parseFloat(event.target.value) || handwritingStyle.bootstrap_match_min_similarity })} />
            </label>
            <label className="settings-field">
              Bootstrap Sample Size
              <input type="number" min={1} max={30} value={handwritingStyle.bootstrap_sample_size} onChange={(event) => setHandwritingStyle({ ...handwritingStyle, bootstrap_sample_size: Number.parseInt(event.target.value, 10) || handwritingStyle.bootstrap_sample_size })} />
            </label>
            <label className="settings-field">
              Max Image Side (px)
              <input type="number" min={256} max={4096} value={handwritingStyle.image_max_side} onChange={(event) => setHandwritingStyle({ ...handwritingStyle, image_max_side: Number.parseInt(event.target.value, 10) || handwritingStyle.image_max_side })} />
            </label>
          </div>
        </div>
      </div>
    </section>
  );
}
