import { memo, useEffect } from 'react';
import { useUpdateNodeInternals } from '@xyflow/react';
import NodeShell from '../components/NodeShell.jsx';
import { NodeDraftInput } from '../components/NodeDraftField.jsx';
import { useWorkflow } from '../context/WorkflowContext.jsx';
import { createBrowserId } from '../lib/ids.js';
import { getNodeAccent } from '../lib/nodeRegistry.js';

function JsonParserFlowNode({ id, data, selected, type }) {
  const { getNodeHandles, replaceNodeData, removeHandleConnections } = useWorkflow();
  const updateNodeInternals = useUpdateNodeInternals();
  const handles = getNodeHandles(type, data);
  const runtime = data.runtime || {};
  const values = runtime.values || {};

  useEffect(() => {
    updateNodeInternals(id);
  }, [id, data.extracts.length, updateNodeInternals]);

  const addExtract = () => {
    replaceNodeData(id, (current) => ({
      ...current,
      extracts: [
        ...current.extracts,
        {
          id: createBrowserId('json-extract'),
          label: `result ${current.extracts.length}`,
          path: '',
          fields: '',
        },
      ],
    }));
  };

  const updateExtract = (extractId, patch) => {
    replaceNodeData(id, (current) => ({
      ...current,
      extracts: current.extracts.map((extract) =>
        extract.id === extractId ? { ...extract, ...patch } : extract,
      ),
    }));
  };

  const removeExtract = (extractId) => {
    if (data.extracts.length <= 1) {
      return;
    }

    removeHandleConnections(id, extractId, 'source');
    replaceNodeData(id, (current) => ({
      ...current,
      extracts: current.extracts.filter((extract) => extract.id !== extractId),
    }));
  };

  const filledValuesCount = Object.values(values).filter(Boolean).length;

  return (
    <NodeShell
      nodeId={id}
      title={data.title}
      accent={getNodeAccent(type)}
      selected={selected}
      status={runtime.status}
      inputs={handles.inputs}
      outputs={handles.outputs}
    >
      <div className="field-stack">
        <div className="json-parser-rule-list">
          {data.extracts.map((extract, index) => (
            <div key={extract.id} className="json-parser-rule">
              <div className="field-row">
                <label className="field-stack">
                  <span className="field-label">Выход</span>
                  <NodeDraftInput
                    className="nodrag node-input"
                    value={extract.label}
                    placeholder={`результат ${index + 1}`}
                    onCommit={(value) => updateExtract(extract.id, { label: value })}
                  />
                </label>
                <button
                  type="button"
                  className="nodrag chip__remove"
                  onClick={() => removeExtract(extract.id)}
                  disabled={data.extracts.length <= 1}
                >
                  x
                </button>
              </div>

              <label className="field-stack">
                <span className="field-label">Путь</span>
                <NodeDraftInput
                  className="nodrag node-input"
                  value={extract.path}
                  placeholder="data.filter_group.items"
                  onCommit={(value) => updateExtract(extract.id, { path: value })}
                />
              </label>

              <label className="field-stack">
                <span className="field-label">Поля</span>
                <NodeDraftInput
                  className="nodrag node-input"
                  value={extract.fields}
                  placeholder="key, name"
                  onCommit={(value) => updateExtract(extract.id, { fields: value })}
                />
              </label>
            </div>
          ))}
        </div>

        <button type="button" className="nodrag node-button node-button--ghost" onClick={addExtract}>
          + Добавить извлечение
        </button>

        <div className="node-note">
          {filledValuesCount > 0
            ? `Извлечено выходов: ${filledValuesCount}.`
            : 'Путь использует dot notation. Поля опциональны и задаются через запятую.'}
        </div>

        {runtime.error ? <div className="node-error">{runtime.error}</div> : null}
      </div>
    </NodeShell>
  );
}

export default memo(JsonParserFlowNode);
