import {
  DecoratorNode,
  DOMExportOutput,
  LexicalNode,
  NodeKey,
  SerializedLexicalNode,
  Spread,
} from 'lexical';
import React from 'react';
import { StepsDiagramComponent } from './StepsDiagramComponent';

export type SerializedStepsDiagramNode = Spread<
  {
    directiveId: string;
  },
  SerializedLexicalNode
>;

export class StepsDiagramNode extends DecoratorNode<JSX.Element> {
  __directiveId: string;

  static getType(): string {
    return 'steps-diagram';
  }

  static clone(node: StepsDiagramNode): StepsDiagramNode {
    return new StepsDiagramNode(node.__directiveId, node.__key);
  }

  constructor(directiveId: string, key?: NodeKey) {
    super(key);
    this.__directiveId = directiveId;
  }

  createDOM(): HTMLElement {
    const div = document.createElement('div');
    div.className = 'steps-diagram-block';
    return div;
  }

  updateDOM(): boolean {
    return false;
  }

  decorate(): JSX.Element {
    return <StepsDiagramComponent directiveId={this.__directiveId} />;
  }

  exportJSON(): SerializedStepsDiagramNode {
    return {
      ...super.exportJSON(),
      type: 'steps-diagram',
      directiveId: this.__directiveId,
      version: 1,
    };
  }

  static importJSON(serializedNode: SerializedStepsDiagramNode): StepsDiagramNode {
    return $createStepsDiagramNode(serializedNode.directiveId);
  }

  isInline(): boolean {
    return false;
  }

  canInsertTextBefore(): boolean {
    return false;
  }

  canInsertTextAfter(): boolean {
    return false;
  }

  exportDOM(): DOMExportOutput {
    const element = document.createElement('div');
    element.className = 'steps-diagram-block';
    element.setAttribute('data-directive-id', this.__directiveId);
    element.textContent = '[Steps Diagram]';
    return { element };
  }
}

export function $createStepsDiagramNode(directiveId: string): StepsDiagramNode {
  return new StepsDiagramNode(directiveId);
}

export function $isStepsDiagramNode(
  node: LexicalNode | null | undefined,
): node is StepsDiagramNode {
  return node instanceof StepsDiagramNode;
}
