import { useEffect, useRef, useState } from 'react';
import { Handle, Position } from '@xyflow/react';
import { useWorkflow } from '../context/WorkflowContext.jsx';

function getStatusLabel(status) {
  switch (status) {
    case 'running':
      return 'Running';
    case 'waiting':
      return 'Waiting';
    case 'skipped':
      return 'Skipped';
    case 'success':
      return 'Ready';
    case 'error':
      return 'Error';
    default:
      return '';
  }
}

const HANDLE_COLORS_BY_ID = {
  answer: '#38bdf8',
  question: '#a78bfa',
  turn: '#f59e0b',
  dialog: '#22c55e',
  'dialog-in': '#22c55e',
};

const HANDLE_COLORS_BY_DATA_TYPE = {
  string: '#38bdf8',
  object: '#f59e0b',
  '*': '#94a3b8',
};

function getHandleColor(handle) {
  return HANDLE_COLORS_BY_ID[handle?.id] || HANDLE_COLORS_BY_DATA_TYPE[handle?.dataType] || '#94a3b8';
}

export default function NodeShell({
  nodeId,
  title,
  accent,
  selected,
  status,
  inputs = [],
  outputs = [],
  children,
  footer,
  className = '',
  bodyClassName = '',
  renderInputAddon,
}) {
  const { patchNodeData } = useWorkflow();
  const rows = Math.max(inputs.length, outputs.length);
  const [isEditingTitle, setIsEditingTitle] = useState(false);
  const [draftTitle, setDraftTitle] = useState(title || '');
  const titleInputRef = useRef(null);

  useEffect(() => {
    if (!isEditingTitle) {
      setDraftTitle(title || '');
    }
  }, [isEditingTitle, title]);

  useEffect(() => {
    if (isEditingTitle && titleInputRef.current) {
      titleInputRef.current.focus();
      titleInputRef.current.select();
    }
  }, [isEditingTitle]);

  const finishTitleEditing = () => {
    const nextTitle = draftTitle.trim() || title || 'Untitled';
    if (nodeId && nextTitle !== title) {
      patchNodeData(nodeId, { title: nextTitle });
    }
    setDraftTitle(nextTitle);
    setIsEditingTitle(false);
  };

  return (
    <div
      className={[
        'node-shell',
        selected ? 'is-selected' : '',
        status ? `status-${status}` : '',
        className,
      ]
        .filter(Boolean)
        .join(' ')}
      style={{ '--node-accent': accent }}
    >
      <div className="node-shell__header drag-handle">
        {isEditingTitle ? (
          <input
            ref={titleInputRef}
            className="nodrag node-shell__title-input"
            value={draftTitle}
            onChange={(event) => setDraftTitle(event.target.value)}
            onBlur={finishTitleEditing}
            onKeyDown={(event) => {
              if (event.key === 'Enter') {
                event.preventDefault();
                finishTitleEditing();
              }
              if (event.key === 'Escape') {
                event.preventDefault();
                setDraftTitle(title || '');
                setIsEditingTitle(false);
              }
            }}
          />
        ) : (
          <button
            type="button"
            className="nodrag node-shell__title node-shell__title-button"
            title="Нажмите, чтобы переименовать"
            onClick={() => {
              if (nodeId) {
                setIsEditingTitle(true);
              }
            }}
          >
            {title}
          </button>
        )}
        {status && status !== 'idle' ? (
          <div className={`node-shell__status-pill status-${status || 'idle'}`}>
            {getStatusLabel(status)}
          </div>
        ) : null}
      </div>

      {rows > 0 ? (
        <div className="node-shell__ports">
          {Array.from({ length: rows }).map((_, index) => {
            const input = inputs[index];
            const output = outputs[index];

            return (
              <div className="node-shell__port-row" key={`${input?.id || 'empty'}-${output?.id || 'empty'}`}>
                <div className="node-shell__port node-shell__port--input">
                  {input ? (
                    <>
                      <Handle
                        type="target"
                        position={Position.Left}
                        id={input.id}
                        className="node-shell__handle"
                        style={{ top: '50%', '--handle-color': getHandleColor(input) }}
                      />
                      <div className="node-shell__port-content node-shell__port-content--input">
                        <span>{input.label}</span>
                        {renderInputAddon ? renderInputAddon(input, index) : null}
                      </div>
                    </>
                  ) : (
                    <span className="node-shell__port-placeholder" />
                  )}
                </div>

                <div className="node-shell__port node-shell__port--output">
                  {output ? (
                    <>
                      <Handle
                        type="source"
                        position={Position.Right}
                        id={output.id}
                        className="node-shell__handle"
                        style={{ top: '50%', '--handle-color': getHandleColor(output) }}
                      />
                      <div className="node-shell__port-content node-shell__port-content--output">
                        <span>{output.label}</span>
                      </div>
                    </>
                  ) : (
                    <span className="node-shell__port-placeholder" />
                  )}
                </div>
              </div>
            );
          })}
        </div>
      ) : null}

      <div className={`node-shell__body ${rows === 0 ? 'node-shell__body--flush' : ''} ${bodyClassName}`.trim()}>
        {children}
      </div>

      {footer ? <div className="node-shell__footer">{footer}</div> : null}
    </div>
  );
}
