import { NodeEditor, type GetSchemes, ClassicPreset } from "rete";
/* [stack-angular] import { type Injector } from '@angular/core' [/stack-angular] */
import { /* [import-area-extensions] AreaExtensions, [/import-area-extensions] */  AreaPlugin } from "rete-area-plugin";
import {
  ConnectionPlugin,
  Presets as ConnectionPresets
} from "rete-connection-plugin";
/* [stack-react] import { ReactPlugin, type ReactArea2D, Presets as ReactPresets } from 'rete-react-plugin' [/stack-react] */
/* [react18] import { createRoot } from 'react-dom/client' [/react18] */
/* [react19] import { createRoot } from 'react-dom/client' [/react19] */
/* [stack-vue] import { VuePlugin, type VueArea2D, Presets as VuePresets } from 'rete-vue-plugin/* [vue2] /vue2 [/vue2] */' [/stack-vue] */
/* [stack-angular] import { AngularPlugin, type AngularArea2D, Presets as AngularPresets } from 'rete-angular-plugin/* [angular12] /12 [/angular12] *//* [angular13] /13 [/angular13] *//* [angular14] /14 [/angular14] *//* [angular15] /15 [/angular15] *//* [angular16] /16 [/angular16] *//* [angular17] /17 [/angular17] *//* [angular18] /18 [/angular18] *//* [angular19] /19 [/angular19] *//* [angular20] /20 [/angular20] *//* [angular21] /21 [/angular21] *//* [angular22] /22 [/angular22] */' [/stack-angular] */
/* [stack-svelte] import { SveltePlugin, type SvelteArea2D, Presets as SveltePresets } from 'rete-svelte-plugin/* [svelte5] /5 [/svelte5] */' [/stack-svelte] */
/* [stack-lit] import { LitPlugin, type LitArea2D, Presets as LitPresets } from '@retejs/lit-plugin' [/stack-lit] */
/* [stack-react] import { CustomNode } from "../customization/CustomNode";
import { StyledNode } from "../customization/StyledNode";
import { CustomSocket } from "../customization/CustomSocket";
import { CustomConnection } from "../customization/CustomConnection"; [/stack-react] */
/* [stack-vue] import CustomNode from "../customization/CustomNode.vue";
import CustomConnection from "../customization/CustomConnection.vue";
import CustomSocket from "../customization/CustomSocket.vue"; [/stack-vue] */
/* [stack-angular] import { CustomSocketComponent } from "../customization/custom-socket/custom-socket.component";
import { CustomNodeComponent } from "../customization/custom-node/custom-node.component";
import { CustomConnectionComponent } from "../customization/custom-connection/custom-connection.component"; [/stack-angular] */
/* [stack-svelte]
import CustomNodeComponent from '../customization/CustomNode.svelte'
import CustomConnectionComponent from '../customization/CustomConnection.svelte'
import CustomSocketComponent from '../customization/CustomSocket.svelte' [/stack-svelte] */
/* [stack-lit]
import { html } from 'lit';
import { CustomNodeElement } from '../customization/custom-node'
import { CustomConnectionElement } from '../customization/custom-connection'
import { CustomSocketElement } from '../customization/custom-socket' [/stack-lit] */
import { addCustomBackground } from "../customization/custom-background";

/* [stack-lit]
customElements.define('custom-node', CustomNodeElement);
customElements.define('custom-connection', CustomConnectionElement);
customElements.define('custom-socket', CustomSocketElement); [/stack-lit] */

type Schemes = GetSchemes<
  ClassicPreset.Node,
  ClassicPreset.Connection<ClassicPreset.Node, ClassicPreset.Node>
>;
type AreaExtra =
  /* [stack-react] | ReactArea2D<Schemes> [/stack-react] */
  /* [stack-vue] | VueArea2D<Schemes> [/stack-vue] */
  /* [stack-angular] | AngularArea2D<Schemes> [/stack-angular] */
  /* [stack-svelte] | SvelteArea2D<Schemes> [/stack-svelte] */
  /* [stack-lit] | LitArea2D<Schemes> [/stack-lit] */

  const socket = new ClassicPreset.Socket("socket");

export async function createEditor(container: HTMLElement/* [stack-angular] , injector: Injector [/stack-angular] */) {
  const editor = new NodeEditor<Schemes>();
  const area = new AreaPlugin<Schemes, AreaExtra>(container);
  const connection = new ConnectionPlugin<Schemes, AreaExtra>();
  /* [stack-react] const reactRender = new ReactPlugin<Schemes, AreaExtra>(/* [react18] { createRoot } [/react18] *//* [react19] { createRoot } [/react19] */)[/stack-react] */
  /* [stack-vue] const vueRender = new VuePlugin<Schemes, AreaExtra>() [/stack-vue] */
  /* [stack-angular] const angularRender = new AngularPlugin<Schemes, AreaExtra>({ injector }) [/stack-angular] */
  /* [stack-svelte] const svelteRender = new SveltePlugin<Schemes, AreaExtra>() [/stack-svelte] */
  /* [stack-lit] const litRender = new LitPlugin<Schemes, AreaExtra>() [/stack-lit] */

  /* [selectable] AreaExtensions.selectableNodes(area, AreaExtensions.selector(), {
    accumulating: AreaExtensions.accumulateOnCtrl()
  }); [/selectable] */

  /* [stack-react] reactRender.addPreset(
    ReactPresets.classic.setup({
      customize: {
        node(context) {
          if (context.payload.label === "Fully customized") {
            return CustomNode;
          }
          if (context.payload.label === "Override styles") {
            return StyledNode;
          }
          return ReactPresets.classic.Node;
        },
        socket() {
          return CustomSocket;
        },
        connection() {
          return CustomConnection;
        }
      }
    })
  ); [/stack-react] */

  /* [stack-vue] vueRender.addPreset(
    VuePresets.classic.setup({
      customize: {
        node(context) {
          if (context.payload.label === "Custom") {
            return CustomNode;
          }
          return VuePresets.classic.Node;
        },
        socket() {
          return CustomSocket;
        },
        connection() {
          return CustomConnection;
        }
      }
    })
  ); [/stack-vue] */

  /* [stack-angular]
  angularRender.addPreset(
    AngularPresets.classic.setup({
      customize: {
        node() {
          return CustomNodeComponent;
        },
        connection() {
          return CustomConnectionComponent;
        },
        socket() {
          return CustomSocketComponent;
        }
      }
    })
  ); [/stack-angular] */

  /* [stack-svelte]
  svelteRender.addPreset(
    SveltePresets.classic.setup({
      customize: {
        node() {
          return CustomNodeComponent;
        },
        connection() {
          return CustomConnectionComponent;
        },
        socket() {
          return CustomSocketComponent;
        }
      },
    })
  ); [/stack-svelte] */

  /* [stack-lit]
  litRender.addPreset(
    LitPresets.classic.setup({
      customize: {
        node(data) {
          return ({ emit }) => html`<custom-node .data=${data.payload} .emit=${emit}></rete-custom>`;
        },
        connection() {
          return ({ path }) => html`<custom-connection .path=${path}></custom-connection>`;
        },
        socket(data) {
          return () => html`<custom-socket .data=${data}></custom-socket>`;
        },
      },
    })
  ); [/stack-lit] */

  connection.addPreset(ConnectionPresets.classic.setup());

    addCustomBackground(area);

    editor.use(area);
    area.use(connection);
  /* [stack-react] area.use(reactRender) [/stack-react] */
  /* [stack-vue] area.use(vueRender) [/stack-vue] */
  /* [stack-angular] area.use(angularRender) [/stack-angular] */
  /* [stack-svelte] area.use(svelteRender) [/stack-svelte] */
  /* [stack-lit] area.use(litRender) [/stack-lit] */

  /* [order-nodes] AreaExtensions.simpleNodesOrder(area); [/order-nodes] */

  /* [stack-react] const aLabel = "Override styles";
  const bLabel = "Fully customized"; [/stack-react] */
  /* [!stack-react] const aLabel = "Custom";
  const bLabel = "Custom"; [/!stack-react] */

  const a = new ClassicPreset.Node(aLabel);
  a.addOutput("a", new ClassicPreset.Output(socket));
  a.addInput("a", new ClassicPreset.Input(socket));
  await editor.addNode(a);

  const b = new ClassicPreset.Node(bLabel);
  b.addOutput("a", new ClassicPreset.Output(socket));
  b.addInput("a", new ClassicPreset.Input(socket));
  await editor.addNode(b);

  await area.translate(a.id, { x: 0, y: 0 });
  await area.translate(b.id, { x: 300, y: 0 });

  await editor.addConnection(new ClassicPreset.Connection(a, "a", b, "a"));

  /* [zoom-at] setTimeout(() => {
    AreaExtensions.zoomAt(area, editor.getNodes());
  }, 300); [/zoom-at] */

  return {
    destroy: () => area.destroy()
  };
}
