/**
 * JsonEditor widget component with syntax highlighting.
 *
 * ⚠️ AUTO-GENERATED BY PRISM - DO NOT EDIT
 */

import { useState, useEffect, type ChangeEvent } from 'react';
import type { WidgetBaseProps } from '../types';

interface JsonEditorProps extends WidgetBaseProps<unknown> {
  rows?: number;
}

export function JsonEditor({
  name,
  value,
  onChange,
  label,
  description,
  placeholder = '{}',
  required,
  disabled,
  error,
  className,
  rows = 8,
}: JsonEditorProps): JSX.Element {
  const [textValue, setTextValue] = useState('');
  const [parseError, setParseError] = useState<string | null>(null);

  // Sync text value with external value changes
  useEffect(() => {
    try {
      const formatted = value !== undefined && value !== null
        ? JSON.stringify(value, null, 2)
        : '';
      setTextValue(formatted);
      setParseError(null);
    } catch {
      // Keep current text if value can't be stringified
    }
  }, [value]);

  const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
    const raw = e.target.value;
    setTextValue(raw);

    if (!raw.trim()) {
      onChange(null);
      setParseError(null);
      return;
    }

    try {
      const parsed = JSON.parse(raw);
      onChange(parsed);
      setParseError(null);
    } catch (err) {
      setParseError((err as Error).message);
    }
  };

  const formatJson = () => {
    try {
      const parsed = JSON.parse(textValue);
      const formatted = JSON.stringify(parsed, null, 2);
      setTextValue(formatted);
      setParseError(null);
    } catch {
      // Keep current text if invalid
    }
  };

  const displayError = error || parseError;

  return (
    <div className={className}>
      {label && (
        <div className="flex items-center justify-between">
          <label htmlFor={name} className="label">
            {label}
            {required && <span className="text-red-500 ml-1">*</span>}
          </label>
          <button
            type="button"
            onClick={formatJson}
            disabled={disabled || !!parseError}
            className="text-xs text-nordic-500 hover:text-nordic-700 disabled:opacity-50"
          >
            Format
          </button>
        </div>
      )}
      <textarea
        id={name}
        name={name}
        value={textValue}
        onChange={handleChange}
        placeholder={placeholder}
        disabled={disabled}
        required={required}
        rows={rows}
        className={`${displayError ? 'input-error' : 'input'} font-mono text-sm resize-y`}
        aria-invalid={!!displayError}
        aria-describedby={description ? `${name}-desc` : displayError ? `${name}-error` : undefined}
        spellCheck={false}
      />
      {description && !displayError && (
        <p id={`${name}-desc`} className="mt-1.5 text-sm text-nordic-500">{description}</p>
      )}
      {displayError && (
        <p id={`${name}-error`} className="mt-1.5 text-sm text-red-600">
          {displayError}
        </p>
      )}
    </div>
  );
}
