import mermaid from 'https://unpkg.com/mermaid@9.2.2/dist/mermaid.esm.min.mjs';
import { Actor } from './actor.js';
import { Action } from './action.js';
import { debounce } from '../util.js';

export class Scene {
  constructor(name, rootBox) {
    this.name = name;
    this.box = rootBox.addBox(name);
    this.titleBox = this.box.addBox().setInnerHTML(name);
    this.box.addBox('Spacer').setInnerHTML(' ');
    this.displayValuesBox = this.box.addBox(`${this.name}-values`);
    this.box.addBox('Spacer').setInnerHTML(' ');
    this.actors = new Set();
    this.seqDiagramContainer = this.box.addBox(
      `${this.name}-seq-diagram-container`,
    );
    this.seqDiagramElement = this.box
      .addBox(`${this.name}-seq-diagram-element`)
      .setId();
    this.seqDiagramBox = this.box.addBox(`${this.name}-seq-diagram`);
    this.box.addBox('Spacer').setInnerHTML(' ');
    this.logBox = this.box.addBox(`${this.name}-log`);
    mermaid.mermaidAPI.initialize({
      startOnLoad: false,
      theme: 'base',
      themeVariables: {
        darkMode: true,
        primaryColor: '#2a5b6c',
        primaryTextColor: '#b6b6b6',
        fontFamily: 'monospace',
        noteBkgColor: '#516f77',
        noteTextColor: '#cecece',
      },
    });
    this.dateLastRender = null;
  }

  addActor(name) {
    const actor = new Actor(name, this);
    return actor;
  }

  registerActor(actor) {
    this.actors.add(actor);
  }

  addAction(name) {
    const action = new Action(name, this);
    return action;
  }

  addDisplayValue(name) {
    const dv = this.displayValuesBox.addDisplayValue(name);
    return dv;
  }

  log(msg) {
    this.logBox.addBox().setInnerHTML(msg).monospace();
    this.renderSequenceDiagram();
    return this;
  }

  deactivateAll() {
    for (const actor of this.actors.values()) {
      while (actor.active) {
        actor.deactivate();
      }
    }
  }

  async renderSequenceDiagram() {
    const render = async () => {
      const dateStart = new Date();
      const graph = await mermaid.mermaidAPI.render(
        this.seqDiagramElement.getId(),
        this.logBox.getInnerText(),
      );
      this.seqDiagramBox.setInnerHTML(graph);
      if (!this.dateLastRender) {
        this.dateLastRender = new Date();
      }
      this.dateLastRender = dateStart;
    };
    debounce(render, 100);
  }
}