import { NjetComponent } from "/njet.js";
class WebTerminal extends NjetComponent {
   
    commands = {
      "clear": () => {
        this.outputEl.innerHTML = "";
        return "";
      },
      "help": () => {
        return "Available commands: help, clear, date";
      },
      "date": () => {
        return new Date().toString();
      }
    };
    help = {
      "clear": "Clear the terminal",
      "help": "Show available commands",
      "date": "Show the current date"
    };




  connectedCallback() {

    this.innerHTML = `
      <style>
        .web-terminal {
          --terminal-bg: #111;
          --terminal-fg: #0f0;
          --terminal-accent: #0ff;
          --terminal-font: monospace;

          display: block;
          background: var(--terminal-bg);
          color: var(--terminal-fg);
          font-family: var(--terminal-font);
          padding: 1rem;
          border-radius: 8px;
          overflow-y: auto;
          max-height: 500px;
        }

        .web-terminal-output {
          white-space: pre-wrap;
          margin-bottom: 1em;
        }

        .input-line {
          display: flex;
        }

        .prompt {
          color: var(--terminal-accent);
          margin-right: 0.5em;
        }

        .web-terminal-input {
          background: transparent;
          border: none;
          color: var(--terminal-fg);
          outline: none;
          width: 100%;
          font-family: inherit;
          font-size: inherit;
        }

        dialog {
          border: none;
          background: transparent;
        }

        .dialog-backdrop {
          background: rgba(0, 0, 0, 0.8);
          padding: 2rem;
        }
      </style>
      <div class="web-terminal">
      <div class="web-terminal-output"  id="output"></div>
      <div class="input-line">
        <span  class="prompt">&gt;</span>
        <input type="text" class="web-terminal-input" id="input" autocomplete="off" autofocus />
      </div>
      </div>
    `;
    this.container = this.querySelector(".web-terminal");
    this.outputEl = this.querySelector(".web-terminal-output");
    this.inputEl = this.querySelector(".web-terminal-input");

    this.history = [];
    this.historyIndex = -1;

    this.inputEl.addEventListener("keyup", (e) => this.onKeyDown(e));
  }

  onKeyDown(event) {
    const value = this.inputEl.value;

    switch (event.key) {
      case "Enter":
        this.executeCommand(value);
        this.history.push(value);
        this.historyIndex = this.history.length;
        this.inputEl.value = "";
        break;

      case "ArrowUp":
        if (this.historyIndex > 0) {
          this.historyIndex--;
          this.inputEl.value = this.history[this.historyIndex];
        }
        break;

      case "ArrowDown":
        if (this.historyIndex < this.history.length - 1) {
          this.historyIndex++;
          this.inputEl.value = this.history[this.historyIndex];
        } else {
          this.historyIndex = this.history.length;
          this.inputEl.value = "";
        }
        break;
    }
  }

  executeCommand(command) {
    const outputLine = document.createElement("div");
    outputLine.textContent = `> ${command}`;
    this.outputEl.appendChild(outputLine);

    const resultLine = document.createElement("div");
    resultLine.textContent = this.mockExecute(command);
    this.outputEl.appendChild(resultLine);

    this.outputEl.scrollTop = this.outputEl.scrollHeight;
  }

  parseCommand(input) {
    const args = [];
    let current = '';
    let inSingleQuote = false;
    let inDoubleQuote = false;
    let inTemplate = false; // For ${...}
    let templateBuffer = '';

    for (let i = 0; i < input.length; i++) {
      const char = input[i];

      // Handle template expressions
      if (!inSingleQuote && !inDoubleQuote && char === '$' && input[i + 1] === '{') {
        inTemplate = true;
        i++; // Skip '{'
        templateBuffer = '${';
        continue;
      }

      if (inTemplate) {
        templateBuffer += char;
        if (char === '}') {
          // End of template
          args.push(eval(templateBuffer));
          inTemplate = false;
          templateBuffer = '';
        }
        continue; // Continue to next char
      }

      // Handle quotes
      if (char === "'" && !inDoubleQuote) {
        inSingleQuote = !inSingleQuote;
        continue; // Skip quote
      }

      if (char === '"' && !inSingleQuote) {
        inDoubleQuote = !inDoubleQuote;
        continue; // Skip quote
      }

      // Handle spaces outside quotes and templates
      if (char === ' ' && !inSingleQuote && !inDoubleQuote) {
        if (current.length > 0) {
          args.push(current);
          current = '';
        }
      } else {
        current += char;
      }
    }

    if (current.length > 0) {
      args.push(current);
    }

    return args;
  } 
  executeScript(script) {
      const scriptElement = document.createElement("script");
      scriptElement.textContent = script;
      this.appendChild(scriptElement);
  }
  mockExecute(command) {
    let args;
    try {
      args = this.parseCommand(command);
    } catch (e) {
      return e.toString();
    }
      console.info({ef:this})
      console.info({af:this})
      console.info({gf:args})
    let cmdName = args.shift();
    let commandHandler = this.commands[cmdName];
    if (commandHandler) {
      return commandHandler.apply(this, args);
    }
    try {
      // Try to eval as JS
      return this.executeScript(command);
    } catch (e) {
      return e.toString();
    }
  }

  /**
   * Static method to create a modal dialog with the terminal
   * @returns {HTMLDialogElement}
   */
  show() {
    const dialog = document.createElement("dialog");
    dialog.innerHTML = `
      <div class="dialog-backdrop">
        <web-terminal></web-terminal>
      </div>
    `;
    document.body.appendChild(dialog);
    dialog.showModal();
    return dialog;
  }
}

window.showTerm = function (options) {
  const term = new WebTerminal(options);
  term.show();
  return term;
}

customElements.define("web-terminal", WebTerminal);
export { WebTerminal };

