import { ClassicPreset as Classic, type GetSchemes, NodeEditor } from 'rete'
import { /* [import-area-extensions] AreaExtensions, [/import-area-extensions] */ AreaPlugin } from 'rete-area-plugin'
/* [stack-angular] import { type Injector } from '@angular/core' [/stack-angular] */
/* [react-render] import { ReactPlugin, type ReactArea2D, Presets as ReactPresets } from 'rete-react-plugin' [/react-render] */
/* [react18] import { createRoot } from 'react-dom/client' [/react18] */
/* [react19] import { createRoot } from 'react-dom/client' [/react19] */
/* [vue-render] import { VuePlugin, type VueArea2D, Presets as VuePresets } from 'rete-vue-plugin/* [vue2] /vue2 [/vue2] */' [/vue-render] */
/* [angular-render] 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] */' [/angular-render] */
/* [svelte-render] import { SveltePlugin, type SvelteArea2D, Presets as SveltePresets } from 'rete-svelte-plugin/* [svelte5] /5 [/svelte5] */' [/svelte-render] */
/* [lit-render] import { LitPlugin, type LitArea2D, Presets as LitPresets } from '@retejs/lit-plugin' [/lit-render] */


class Node extends Classic.Node {
  constructor() {
    super('Perf')

    this.addInput('port', new Classic.Input(socket, 'Input'))
    this.addOutput('port', new Classic.Output(socket, 'Output'))
  }
}

class Connection<A extends Node, B extends Node> extends Classic.Connection<A, B> { }

type Schemes = GetSchemes<Node, Connection<Node, Node>>

type AreaExtra =
  /* [react-render] | ReactArea2D<Schemes> [/react-render] */
  /* [vue-render] | VueArea2D<Schemes> [/vue-render] */
  /* [angular-render] | AngularArea2D<Schemes> [/angular-render] */
  /* [svelte-render] | SvelteArea2D<Schemes> [/svelte-render] */
  /* [lit-render] | LitArea2D<Schemes> [/lit-render] */

  const socket = new Classic.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)
  /* [react-render] const reactRender = new ReactPlugin<Schemes, AreaExtra>(/* [react18] { createRoot } [/react18] *//* [react19] { createRoot } [/react19] */)[/react-render] */
  /* [vue-render] const vueRender = new VuePlugin<Schemes, AreaExtra>() [/vue-render] */
  /* [angular-render] const angularRender = new AngularPlugin<Schemes, AreaExtra>({ injector }) [/angular-render] */
  /* [svelte-render] const svelteRender = new SveltePlugin<Schemes, AreaExtra>() [/svelte-render] */
  /* [lit-render] const litRender = new LitPlugin<Schemes, AreaExtra>() [/lit-render] */

  editor.use(area)

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

  /* [react-render] reactRender.addPreset(ReactPresets.classic.setup()) [/react-render] */
  /* [vue-render] vueRender.addPreset(VuePresets.classic.setup()) [/vue-render] */
  /* [angular-render] angularRender.addPreset(AngularPresets.classic.setup()) [/angular-render] */
  /* [svelte-render] svelteRender.addPreset(SveltePresets.classic.setup()) [/svelte-render] */
  /* [lit-render] litRender.addPreset(LitPresets.classic.setup()) [/lit-render] */

  // eslint-disable-next-line no-restricted-globals
  const query = new URLSearchParams(location.search)
  const rows = Number(query.get('rows') || 0) || 12
  const cols = Number(query.get('cols') || 0) || 12

  let prev: null | Node = null
  for (let row = 0; row < rows; row++) {
    for (let col = 0; col < cols; col++) {
      const a = new Node()

      await editor.addNode(a)
      await area.translate(a.id, { x: col * 310, y: row * 190 })

      if (prev) {
        await editor.addConnection(new Connection(prev, 'port', a, 'port'))
      }
      prev = a
    }
  }

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

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

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

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