import { render, screen, fireEvent } from '@testing-library/react';
import { ReactFlowProvider } from '@xyflow/react';
import { WorkflowNode } from '../WorkflowNode';
import type { WfNode } from '../types';

// xyflow handles need a provider + measured store; render inside one.
function renderNode(props: Parameters<typeof WorkflowNode>[0]) {
  return render(
    <ReactFlowProvider>
      <WorkflowNode {...props} />
    </ReactFlowProvider>
  );
}

function baseData(overrides: Partial<WfNode> = {}) {
  const node: WfNode = {
    id: 'n1',
    name: 'Send email',
    type: 'action.email',
    ...overrides,
  };
  return {
    node,
    category: 'action',
    status: 'idle' as const,
  };
}

describe('WorkflowNode', () => {
  it('renders the node title', () => {
    renderNode({ id: 'n1', data: baseData(), selected: false } as never);
    expect(screen.getByText('Send email')).toBeInTheDocument();
  });

  it('renders a status badge reflecting the node status', () => {
    renderNode({
      id: 'n1',
      data: { ...baseData(), status: 'running' },
      selected: false,
    } as never);
    expect(screen.getByText('Running')).toBeInTheDocument();
  });

  it('renders the category label from the theme', () => {
    renderNode({ id: 'n1', data: baseData(), selected: false } as never);
    // action category resolves to label "Action"
    expect(screen.getByText('Action')).toBeInTheDocument();
  });

  it('renders one output handle per output (multi-output: if/else)', () => {
    const { container } = renderNode({
      id: 'n1',
      data: {
        ...baseData({ type: 'condition.if' }),
        category: 'condition',
        outputLabels: ['true', 'false'],
        outputCount: 2,
      },
      selected: false,
    } as never);
    const outputs = container.querySelectorAll('[data-handle-kind="output"]');
    expect(outputs).toHaveLength(2);
    expect(screen.getByText('true')).toBeInTheDocument();
    expect(screen.getByText('false')).toBeInTheDocument();
  });

  it('applies disabled styling when disabled', () => {
    const { container } = renderNode({
      id: 'n1',
      data: { ...baseData({ disabled: true }) },
      selected: false,
    } as never);
    expect(
      container.querySelector('[data-disabled="true"]')
    ).toBeInTheDocument();
  });

  it('invokes onRename when the title is edited', () => {
    const onRename = jest.fn();
    renderNode({
      id: 'n1',
      data: { ...baseData(), onRename },
      selected: true,
    } as never);
    // double-click the title to enter edit mode
    fireEvent.doubleClick(screen.getByText('Send email'));
    const input = screen.getByRole('textbox');
    fireEvent.change(input, { target: { value: 'Send welcome email' } });
    fireEvent.blur(input);
    expect(onRename).toHaveBeenCalledWith('n1', 'Send welcome email');
  });
});
