/* header prompt → a tiny playful shell.
   type a command + Enter: known targets navigate, anything else is an
   easter egg (a fake shell error). the menu below is always "open" and
   clickable, so typing is optional. */
(function () {
  "use strict";
  var bar = document.querySelector(".topbar");
  var input = document.querySelector(".prompt__input");
  var out = document.querySelector(".prompt__out");
  var menu = document.querySelector(".menu");
  if (!bar || !input) return;

  var home = bar.getAttribute("data-home") || "/";

  // command → url: the always-open menu, plus any context routes (e.g. the
  // portfolio project slugs, only present in the DOM while inside /portfolio/).
  // rebuilt after each pjax navigation since .routes changes per section.
  var routes = {};
  function buildRoutes() {
    routes = {};
    Array.prototype.forEach.call(document.querySelectorAll(".menu a, .routes a, footer a[data-name]"), function (a) {
      var key = (a.getAttribute("data-name") || a.textContent).trim().toLowerCase().replace(/\/+$/, "");
      if (key) routes[key] = a.getAttribute("href");
    });
  }
  buildRoutes();
  document.addEventListener("pjax:load", buildRoutes);

  function pwd() {
    var p = document.querySelector(".prompt__path");
    return p ? p.textContent.replace(/^:/, "").replace(/\$$/, "") : "~";
  }

  function say(msg) { if (out) out.textContent = msg; }
  function navigate(u) { input.textContent = ""; if (window.pjax) window.pjax(u); else window.location.href = u; }

  function pad(n) { return (n < 10 ? "0" : "") + n; }
  function dateStr() {
    var d = new Date();
    var days = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
    var mons = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
    return days[d.getDay()] + " " + mons[d.getMonth()] + " " + pad(d.getDate()) + " " + d.getFullYear();
  }
  function timeStr() {
    var d = new Date();
    return pad(d.getHours()) + ":" + pad(d.getMinutes()) + ":" + pad(d.getSeconds());
  }
  function infoStr() {
    var lines = [];
    var info = bar.getAttribute("data-info");
    var email = bar.getAttribute("data-email");
    if (info) lines.push(info);
    if (email) lines.push(email);
    lines.push("type: portfolio · about · studio · openbureau");
    return lines.join("\n");
  }

  // command history, kept for the whole tab session (survives navigation)
  var hist = [];
  try { hist = JSON.parse(sessionStorage.getItem("kgv_hist") || "[]"); } catch (e) { hist = []; }
  var hpos = hist.length;
  function remember(cmd) {
    if (hist[hist.length - 1] !== cmd) hist.push(cmd);
    hpos = hist.length;
    try { sessionStorage.setItem("kgv_hist", JSON.stringify(hist.slice(-100))); } catch (e) {}
  }
  function historyStr() {
    if (!hist.length) return "(empty)";
    return hist.map(function (c, i) { return ("  " + (i + 1)).slice(-4) + "  " + c; }).join("\n");
  }

  function unameStr(lc) {
    return lc === "uname -a" ? "kgv-sh 1.0 architecture lucerne ch" : "kgv-sh";
  }

  // ls -a reveals the hidden dotfiles
  function lsa() {
    var items = ["./", "../"];
    Array.prototype.forEach.call(document.querySelectorAll(".menu a"), function (a) {
      items.push((a.getAttribute("data-name") || "") + "/");
    });
    items.push(".colophon", ".legal-notice");
    return items.join("   ");
  }

  function tree() {
    var work = [];
    Array.prototype.forEach.call(document.querySelectorAll(".routes a"), function (a) {
      work.push(a.getAttribute("data-name"));
    });
    var l = ["."];
    l.push("├── portfolio/");
    work.forEach(function (s, i) { l.push("│   " + (i === work.length - 1 ? "└── " : "├── ") + s + "/"); });
    l.push("├── about/");
    l.push("├── studio/");
    l.push("├── openbureau/");
    l.push("├── .colophon");
    l.push("└── .legal-notice");
    return l.join("\n");
  }

  function fetchStr() {
    var up = Math.max(1, Math.round((window.performance && performance.now ? performance.now() : 0) / 1000));
    return [
      "   _      karimgabrielevarano",
      "  | | __  -------------------",
      "  | |/ /  os:       kgv-sh 1.0",
      "  |   <   location: lucerne",
      "  |_|\\_\\  degree:   ba architecture",
      "          status:   ma in progress",
      "          uptime:   " + up + "s",
      "          ~:        portfolio · about · studio · openbureau"
    ].join("\n");
  }

  function setTheme(mode) {
    var dark = mode === "dark";
    document.documentElement.classList.toggle("dark", dark);
    try { localStorage.setItem("kgv_theme", dark ? "dark" : "light"); } catch (e) {}
  }

  // `sl` — a steam locomotive rolls across the screen (the classic `ls` typo gag)
  var TRAIN = [
    "      ====        ________                ___________ ",
    "  _D _|  |_______/        \\__I_I_____===__|_________| ",
    "   |(_)---  |   H\\________/ |   |        =|___ ___|   ",
    "   /     |  |   H  |  |     |   |         ||_| |_||    ",
    "  |      |  |   H  |__--------------------| [___] |    ",
    "  | ________|___H__/__|_____/[][]~\\_______|       |   ",
    "  |/ |   |-----------I_____I [][] []  D   |=======|__  ",
    "__/ =| o |=-~~\\  /~~\\  /~~\\  /~~\\ ____Y___________|__  ",
    " |/-=|___|=    ||    ||    ||    |_____/~\\___/        ",
    "  \\_/      \\O=====O=====O=====O_/      \\_/            "
  ].join("\n");
  function sl() {
    if (document.querySelector(".sl")) return;
    var pre = document.createElement("pre");
    pre.className = "sl";
    pre.textContent = TRAIN;
    document.body.appendChild(pre);
    pre.style.transform = "translateX(" + window.innerWidth + "px)";
    requestAnimationFrame(function () {
      pre.style.transition = "transform 4s linear";
      pre.style.transform = "translateX(-" + (pre.offsetWidth + 40) + "px)";
    });
    setTimeout(function () { pre.remove(); }, 4200);
  }

  // secret: `doom` boots shareware DOOM (id Software) in a draggable window
  function doom() {
    if (document.querySelector(".doom-window")) return;
    var win = document.createElement("div");
    win.className = "doom-window";
    var bar = document.createElement("div");
    bar.className = "doom-window__bar";
    var label = document.createElement("span");
    label.className = "doom-window__title";
    label.textContent = "doom";
    var close = document.createElement("button");
    close.className = "doom-window__close";
    close.setAttribute("aria-label", "close");
    close.textContent = "✕";
    var frame = document.createElement("iframe");
    frame.src = "https://archive.org/embed/DoomsharewareEpisode";
    frame.setAttribute("allowfullscreen", "");
    frame.allow = "fullscreen; autoplay; gamepad";
    bar.appendChild(label);
    bar.appendChild(close);
    win.appendChild(bar);
    win.appendChild(frame);
    document.body.appendChild(win);

    function kill() { win.remove(); document.removeEventListener("keydown", esc); }
    function esc(e) { if (e.key === "Escape") kill(); }
    close.addEventListener("click", kill);
    document.addEventListener("keydown", esc);

    // drag by the title bar (shield the iframe so it doesn't swallow the mouse)
    bar.addEventListener("mousedown", function (e) {
      if (e.target === close) return;
      var r = win.getBoundingClientRect();
      win.style.left = r.left + "px";
      win.style.top = r.top + "px";
      win.style.transform = "none";
      var dx = e.clientX - r.left, dy = e.clientY - r.top;
      frame.style.pointerEvents = "none";
      function mv(ev) { win.style.left = (ev.clientX - dx) + "px"; win.style.top = (ev.clientY - dy) + "px"; }
      function up() { frame.style.pointerEvents = ""; document.removeEventListener("mousemove", mv); document.removeEventListener("mouseup", up); }
      document.addEventListener("mousemove", mv);
      document.addEventListener("mouseup", up);
      e.preventDefault();
    });
  }

  function egg(lc, raw) {
    var arg0 = raw.split(/\s+/)[0];
    if (/^sudo\s+make\s+me\s+a\s+sandwich$/.test(lc)) return "okay.";
    if (/^make\s+me\s+a\s+sandwich$/.test(lc)) return "what? make it yourself.";
    if (/^sudo\b/.test(lc) || lc === "su") return "permission denied: nice try.";
    if (/^rm\b/.test(lc)) return "rm: some things you keep.";
    if (lc === "whoami") return "karim";
    if (lc === "pwd") return pwd();
    if (lc === "help" || /^man\b/.test(lc)) return "nav:  portfolio · about · studio · openbureau · cv\nbasics:  info · contact · date · time · tree · fetch · history\ntheme:  dark · light";
    if (lc === "hello" || lc === "hi" || lc === "hey") return "hi :)";
    if (lc === "exit" || lc === "logout") return "there is no exit. only architecture.";
    if (lc === "coffee" || lc === "brew") return "☕ brewing… (418: i'm a teapot)";
    if (/^(cat|open|vim|nano|emacs|less)\b/.test(lc)) return arg0 + ": permission denied";
    return "zsh: command not found: " + arg0;
  }

  // tab-completion over known commands + navigable routes
  var COMMANDS = ["help", "man", "info", "contact", "date", "time", "tree", "fetch", "neofetch",
    "uname", "history", "clear", "echo", "pwd", "whoami", "ls", "cd", "cat", "open",
    "dark", "light", "theme", "sl", "doom", "coffee"];
  function complete() {
    var val = input.textContent;
    var parts = val.split(" ");
    var last = (parts[parts.length - 1] || "").toLowerCase();
    if (!last) return;
    var pool = parts.length > 1 ? Object.keys(routes) : COMMANDS.concat(Object.keys(routes));
    var matches = [];
    for (var i = 0; i < pool.length; i++) {
      if (pool[i].indexOf(last) === 0 && matches.indexOf(pool[i]) < 0) matches.push(pool[i]);
    }
    if (!matches.length) return;
    var common = matches.reduce(function (a, b) {
      var n = 0; while (n < a.length && a.charAt(n) === b.charAt(n)) n++; return a.slice(0, n);
    });
    parts[parts.length - 1] = matches.length === 1 ? matches[0] : common;
    input.textContent = parts.join(" ");
    caretToEnd();
    say(matches.length > 1 ? matches.join("   ") : "");   // list options when ambiguous
  }

  function run(raw) {
    var cmd = raw.replace(/\s+/g, " ").trim();
    if (!cmd) return;
    var lc = cmd.toLowerCase();
    remember(cmd);

    if (lc === "clear") { say(""); input.textContent = ""; return; }
    if (lc === "doom") { doom(); say(""); input.textContent = ""; return; }
    if (lc === "sl") { sl(); say(""); input.textContent = ""; return; }
    if (lc === "dark" || lc === "light") { setTheme(lc); say(""); input.textContent = ""; return; }
    if (lc === "theme") { var next = document.documentElement.classList.contains("dark") ? "light" : "dark"; setTheme(next); say("theme: " + next); input.textContent = ""; return; }

    // strip a leading verb, leading ./ and trailing slash
    var t = lc.replace(/^(cd|ls|cat|open)\b\s*/, "").replace(/^\.\//, "").replace(/\/+$/, "").trim();

    // `ls` of the current/home dir — the listing is already on screen
    if (/^ls\b/.test(lc) && (t === "" || t === "~" || t === ".")) { say(""); input.textContent = ""; return; }
    // home / up
    if (t === "" || t === "~" || t === ".." || t === "." || t === "home" || t === "/") { navigate(home); return; }
    // a known menu target
    if (routes[t]) { navigate(routes[t]); return; }

    // basics that just print
    if (lc === "info") { say(infoStr()); input.textContent = ""; return; }
    if (lc === "contact") { say(bar.getAttribute("data-email") || ""); input.textContent = ""; return; }
    if (lc === "date") { say(dateStr()); input.textContent = ""; return; }
    if (lc === "time") { say(timeStr()); input.textContent = ""; return; }
    if (lc === "history") { say(historyStr()); input.textContent = ""; return; }
    if (lc === "tree") { say(tree()); input.textContent = ""; return; }
    if (lc === "fetch" || lc === "neofetch") { say(fetchStr()); input.textContent = ""; return; }
    if (lc === "uname" || lc === "uname -a") { say(unameStr(lc)); input.textContent = ""; return; }
    if (/^ls\s+-(la|al|a)$/.test(lc) || lc === "ls --all") { say(lsa()); input.textContent = ""; return; }
    if (lc === "echo" || lc.indexOf("echo ") === 0) { say(cmd.slice(4).trim()); input.textContent = ""; return; }

    say(egg(lc, cmd));      // unknown → shell error, fresh empty prompt
    input.textContent = "";
  }

  input.addEventListener("keydown", function (e) {
    if (e.key === "Enter") { e.preventDefault(); run(input.textContent); return; }
    if (e.key === "Tab") { e.preventDefault(); complete(); return; }
    if (e.key === "ArrowUp" && hist.length) {
      e.preventDefault();
      hpos = Math.max(0, hpos - 1);
      input.textContent = hist[hpos] || "";
      caretToEnd(); say("");
    } else if (e.key === "ArrowDown" && hist.length) {
      e.preventDefault();
      hpos = Math.min(hist.length, hpos + 1);
      input.textContent = hist[hpos] || "";
      caretToEnd(); say("");
    }
  });
  input.addEventListener("input", function () { say(""); });

  function caretToEnd() {
    var r = document.createRange();
    r.selectNodeContents(input);
    r.collapse(false);
    var s = window.getSelection();
    s.removeAllRanges();
    s.addRange(r);
  }

  // start typing anywhere → the keystroke goes straight into the command line
  document.addEventListener("keydown", function (e) {
    if (document.querySelector(".doom-window")) return;        // playing doom
    var t = e.target;
    if (t === input) return;                                    // already typing
    if (t && (t.isContentEditable || /^(input|textarea|select)$/i.test(t.tagName))) return;
    if (e.metaKey || e.ctrlKey || e.altKey) return;
    if (e.key && e.key.length === 1) {                          // a printable character
      e.preventDefault();
      input.focus();
      input.textContent += e.key;
      caretToEnd();
      say("");
    }
  });

  // clicking anywhere on the bar focuses the prompt (but let links + text selection through)
  bar.addEventListener("click", function (e) {
    if (e.target.closest("a")) return;
    if (window.getSelection && String(window.getSelection())) return;
    input.focus();
    caretToEnd();
  });
})();
