// display-engine.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache-2.0

'use strict';

const path = require('path');

const pug = require('pug');
const uuidv4 = require('uuid').v4;

const { SiteService, SiteError } = require('../../lib/site-lib');

class DisplayList {

  constructor (service, name) {
    this.name = name;
    this.id = uuidv4();
    this.commands = [ ];
  }

  showNotification (message, status, pos, timeout) {
    this.commands.push({
      action: 'showNotification',
      params: { message, status, pos, timeout },
    });
  }

  showModal (html) {
    this.commands.push({
      action: 'showModal',
      params: { html },
    });
  }

  closeModal ( ) {
    this.commands.push({
      action: 'closeModal',
      params: { },
    });
  }

  addElement (selector, where, html) {
    this.commands.push({
      selector, action: 'addElement',
      params: { where, html },
    });
  }

  setTextContent (selector, text) {
    this.commands.push({
      selector, action: 'setTextContent',
      params: { text },
    });
  }

  setInputValue (selector, value) {
    this.commands.push({
      selector, action: 'setInputValue',
      params: { value },
    });
  }

  replaceElement (selector, html) {
    this.commands.push({
      selector, action: 'replaceElement',
      params: { html },
    });
  }

  removeElement (selector) {
    this.commands.push({
      selector, action: 'removeElement',
      params: { },
    });  
  }  

  setAttribute (selector, name, value) {
    this.commands.push({
      selector, action: 'setAttribute',
      params: { name, value },
    });
  }

  removeAttribute (selector, name) {
    this.commands.push({
      selector, action: 'removeAttribute',
      params: { name },
    });
  }

  addClass (selector, add) {
    this.commands.push({
      selector, action: 'addClass',
      params: { add },
    });
  }

  removeClass (selector, remove) {
    this.commands.push({
      selector, action: 'removeClass',
      params: { remove },
    });
  }

  replaceClass (selector, remove, add) {
    this.commands.push({
      selector, action: 'replaceClass',
      params: { remove, add },
    });
  }

  navigateTo (href) {
    this.commands.push({
      action: 'navigateTo',
      params: { href },
    });
  }

  reload ( ) {
    this.commands.push({
      action: 'reload',
      params: { },
    });
  }
}

class DisplayEngineService extends SiteService {

  constructor (dtp) {
    super(dtp, module.exports);
    this.templates = { };
  }

  async start ( ) { }

  async stop ( ) { }

  loadTemplate (name, pugScript) {
    const scriptFile = path.join(this.dtp.config.root, 'app', 'views', pugScript);
    this.templates[name] = pug.compileFile(scriptFile);
  }

  executeTemplate (name, data) {
    if (!this.templates[name]) {
      this.log.error('view engine template undefined', { name });
      throw new SiteError(500, 'Unknown display engine template');
    }
    data = Object.assign(this.dtp.app.locals, data);
    return this.templates[name](data);
  }

  createDisplayList (name = 'default') { return new DisplayList(this, name); }
}

module.exports = {
  slug: 'display-engine',
  name: 'displayEngine',
  create: (dtp) => { return new DisplayEngineService(dtp); },
};