import type { FC } from "hono/jsx";

export interface IdeMultiplayerProps {
  user?: any;
  sessionId?: string;
}

const baseLines = [
  { n: 148, text: "  const session = await sandbox.attach(pr.id);", color: "#16181d", bg: "transparent", agentCursor: false },
  { n: 149, text: "", color: "#16181d", bg: "transparent", agentCursor: false },
  { n: 150, text: "  // Bounded repair: never hold a sandbox forever.", color: "#8a8d99", bg: "transparent", agentCursor: false },
  { n: 151, text: "  for (let i = 0; i < MAX_REPAIR_ATTEMPTS; i++) {", color: "#2fbf83", bg: "rgba(30,127,92,0.05)", agentCursor: false },
  { n: 152, text: "    const patch = await attemptPatch(gate, session);", color: "#2fbf83", bg: "rgba(30,127,92,0.05)", agentCursor: false },
  { n: 153, text: "    if (await gates.rerun(session, patch)) break;", color: "#2fbf83", bg: "rgba(30,127,92,0.05)", agentCursor: false },
  { n: 154, text: "  }", color: "#2fbf83", bg: "rgba(30,127,92,0.05)", agentCursor: true },
  { n: 155, text: "", color: "#16181d", bg: "transparent", agentCursor: false },
  { n: 156, text: '  telemetry.record("repair.attempt", {', color: "#16181d", bg: "transparent", agentCursor: false },
  { n: 157, text: "    gate: gate.name,", color: "#16181d", bg: "transparent", agentCursor: false },
  { n: 158, text: "    attempts: i,", color: "#16181d", bg: "transparent", agentCursor: false },
  { n: 159, text: "    outcome: session.lastRun,", color: "#16181d", bg: "transparent", agentCursor: false },
  { n: 160, text: "  });", color: "#16181d", bg: "transparent", agentCursor: false },
];

const chatMessages = [
  { who: "CC", avatarBg: "#4353c9", text: "The loop needs an upper bound — a red gate could hold the sandbox forever." },
  { who: "CL", avatarBg: "#1e7f5c", text: "Agreed. Capping at MAX_REPAIR_ATTEMPTS and threading the session through each attempt — typing it now, lines 151–154." },
  { who: "CL", avatarBg: "#1e7f5c", text: "Done. Accept the suggestion and I'll re-run gate: tests in the sandbox." },
];

export const IdeMultiplayer: FC<IdeMultiplayerProps> = (props) => {
  const { user, sessionId = "pr-218" } = props;
  const initials = user?.username
    ? user.username.slice(0, 2).toUpperCase()
    : "CC";

  return (
    <>
      <style dangerouslySetInnerHTML={{ __html: css }} />
      <div class="im-root">
        {/* Top nav */}
        <header class="im-header">
          <a href="/" class="im-logo">
            <span class="im-logo-mark" />
            gluecron
          </a>
          <span class="im-header-sep">/</span>
          <span class="im-header-sub">IDE extension · VS Code</span>
          <div class="im-header-right">
            <span class="im-header-note">Side-by-side, in your editor — the browser is optional</span>
          </div>
        </header>

        <main class="im-main">
          {/* Page heading */}
          <div class="im-intro">
            <div class="im-eyebrow">Multiplayer session · {sessionId} sandbox</div>
            <h1 class="im-h1">You and the agent, in the same file.</h1>
            <p class="im-lead">The extension joins the PR sandbox as a live session. You see the agent's cursor, it sees your edits, and either of you can take the keyboard — no context switch, no browser.</p>
          </div>

          {/* Editor mock */}
          <div class="im-window" id="im-window">
            {/* Title bar */}
            <div class="im-titlebar">
              <span class="im-dot im-dot-r" />
              <span class="im-dot im-dot-y" />
              <span class="im-dot im-dot-g" />
              <span class="im-titlebar-filename">auto-repair.ts — gluecron · sandbox {sessionId}</span>
              <span class="im-titlebar-chips">
                <span class="im-chip im-chip-you">
                  <span class="im-chip-avatar im-chip-avatar-you">{initials}</span>
                  you
                </span>
                <span class="im-chip im-chip-claude">
                  <span class="im-chip-avatar im-chip-avatar-claude">CL</span>
                  claude
                </span>
              </span>
            </div>

            {/* Body: code pane + session rail */}
            <div class="im-body">
              {/* Code pane */}
              <div class="im-code-pane" id="im-code-pane">
                {baseLines.map((line) => (
                  <div
                    class="im-code-line"
                    style={`background:${line.bg}`}
                    data-agent-line={line.agentCursor ? "true" : "false"}
                  >
                    <span class="im-line-num">{line.n}</span>
                    <span
                      class="im-line-text"
                      style={`color:${line.color}`}
                      data-is-green={line.color === "#2fbf83" ? "true" : "false"}
                    >
                      {line.text}
                      {line.agentCursor && (
                        <>
                          <span class="im-caret" />
                          <span class="im-caret-label">← claude</span>
                        </>
                      )}
                    </span>
                  </div>
                ))}
              </div>

              {/* Session rail */}
              <div class="im-rail">
                {/* Status section */}
                <div class="im-rail-status">
                  <div class="im-rail-label">Session</div>
                  <div class="im-status-rows">
                    <div class="im-status-row">
                      <span class="im-dot-status im-dot-green im-dot-pulse" />
                      <span class="im-status-text" id="im-agent-status">claude finished — 4 lines suggested</span>
                    </div>
                    <div class="im-status-row">
                      <span class="im-dot-status im-dot-green" />
                      <span class="im-status-secondary">sandbox {sessionId} · terminal shared</span>
                    </div>
                    <div class="im-status-row">
                      <span class="im-dot-status im-gate-dot" id="im-gate-dot" />
                      <span class="im-status-secondary" id="im-gate-status">gates ready to re-run on accept</span>
                    </div>
                  </div>
                </div>

                {/* Chat feed */}
                <div class="im-chat-feed" id="im-chat-feed">
                  <div class="im-rail-label">Chat</div>
                  {chatMessages.map((msg) => (
                    <div class="im-chat-msg">
                      <span
                        class="im-chat-avatar"
                        style={`background:${msg.avatarBg}`}
                      >
                        {msg.who}
                      </span>
                      <p class="im-chat-text">{msg.text}</p>
                    </div>
                  ))}
                </div>

                {/* Message input */}
                <div class="im-chat-input-row">
                  <input
                    class="im-chat-input"
                    placeholder="Message claude…"
                    id="im-msg-input"
                    type="text"
                  />
                  <button class="im-chat-send" type="button" id="im-msg-send">Send</button>
                </div>
              </div>
            </div>

            {/* Status bar */}
            <div class="im-statusbar">
              <span>⎇ feat/repair-sandbox-loop</span>
              <span>gluecron: connected</span>
              <span class="im-statusbar-right">
                agent edits: suggested → you accept ·{" "}
                <button
                  class="im-mode-toggle"
                  type="button"
                  id="im-mode-toggle"
                >
                  switch to observe-only
                </button>
              </span>
            </div>
          </div>

          {/* Manual note row */}
          <div class="im-footer-note">
            <p class="im-footer-text">
              Don't want the agent typing? Set it to{" "}
              <strong class="im-footer-strong">observe-only</strong> and it becomes a reviewer in your gutter — you keep the keyboard, it keeps the receipts. Works identically in JetBrains.
            </p>
            <a href="#" class="im-footer-link">Open this session on the web →</a>
          </div>
        </main>
      </div>

      <script dangerouslySetInnerHTML={{ __html: js }} />
    </>
  );
};

export default IdeMultiplayer;

const js = `
(function() {
  var step = 3;
  var agentMode = "suggest";

  var agentStatusEl = document.getElementById("im-agent-status");
  var gateDotEl = document.getElementById("im-gate-dot");
  var gateStatusEl = document.getElementById("im-gate-status");
  var modeToggleEl = document.getElementById("im-mode-toggle");
  var msgInput = document.getElementById("im-msg-input");
  var msgSend = document.getElementById("im-msg-send");
  var chatFeed = document.getElementById("im-chat-feed");

  function applyStep(s) {
    if (!agentStatusEl) return;
    if (s < 3) {
      agentStatusEl.textContent = "claude is typing in auto-repair.ts";
    } else {
      agentStatusEl.textContent = "claude finished — 4 lines suggested";
    }
    if (gateDotEl) {
      if (s >= 3) {
        gateDotEl.style.background = "#b45309";
        gateDotEl.classList.add("im-dot-pulse");
      } else {
        gateDotEl.style.background = "#c4c6cf";
        gateDotEl.classList.remove("im-dot-pulse");
      }
    }
    if (gateStatusEl) {
      gateStatusEl.textContent = s >= 3 ? "gates ready to re-run on accept" : "gates idle";
    }

    // show/hide green lines based on step
    var codePane = document.getElementById("im-code-pane");
    if (codePane) {
      var greenLines = codePane.querySelectorAll("[data-is-green='true']");
      greenLines.forEach(function(el, i) {
        var lineDiv = el.parentElement;
        var shown = s === 0 ? 1 : s === 1 ? 3 : 4;
        if (i < shown) {
          lineDiv.style.display = "";
        } else {
          lineDiv.style.display = "none";
        }
        // update cursor visibility
        var agentLine = lineDiv.getAttribute("data-agent-line");
        if (agentLine === "true") {
          var caret = lineDiv.querySelector(".im-caret");
          var caretLabel = lineDiv.querySelector(".im-caret-label");
          if (s < 3) {
            if (i === shown - 1) {
              if (caret) caret.style.display = "inline-block";
              if (caretLabel) caretLabel.style.display = "inline-block";
            } else {
              if (caret) caret.style.display = "none";
              if (caretLabel) caretLabel.style.display = "none";
            }
          } else {
            if (caret) caret.style.display = "none";
            if (caretLabel) caretLabel.style.display = "none";
          }
        }
      });
    }
  }

  applyStep(step);

  if (modeToggleEl) {
    modeToggleEl.addEventListener("click", function() {
      agentMode = agentMode === "suggest" ? "observe" : "suggest";
      modeToggleEl.textContent = agentMode === "suggest" ? "switch to observe-only" : "switch to suggest";
    });
  }

  if (msgSend && msgInput && chatFeed) {
    function sendMsg() {
      var val = msgInput.value.trim();
      if (!val) return;
      var msg = document.createElement("div");
      msg.className = "im-chat-msg";
      msg.innerHTML = '<span class="im-chat-avatar" style="background:#4353c9">CC</span><p class="im-chat-text">' + val.replace(/</g,"&lt;").replace(/>/g,"&gt;") + '</p>';
      chatFeed.appendChild(msg);
      chatFeed.scrollTop = chatFeed.scrollHeight;
      msgInput.value = "";
    }
    msgSend.addEventListener("click", sendMsg);
    msgInput.addEventListener("keydown", function(e) {
      if (e.key === "Enter") sendMsg();
    });
  }
})();
`;

const css = `
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;450;500;600;700&family=Inter+Tight:wght@500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');

@keyframes imPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
@keyframes imCaret {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

*, *::before, *::after { box-sizing: border-box; }

.im-root {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.55;
  letter-spacing: -0.008em;
  color: #16181d;
  background: #fcfcfd;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Header */
.im-header {
  height: 56px;
  border-bottom: 1px solid rgba(22,24,29,0.07);
  background: #fcfcfd;
  display: flex;
  align-items: center;
  padding: 0 28px;
  gap: 20px;
}

.im-logo {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: 'Inter Tight', sans-serif;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.02em;
  color: #16181d;
  text-decoration: none;
}

.im-logo-mark {
  width: 16px;
  height: 16px;
  border-radius: 5px;
  background: #4353c9;
  display: inline-block;
  flex-shrink: 0;
}

.im-header-sep {
  color: #c4c6cf;
}

.im-header-sub {
  font-size: 13px;
  color: #16181d;
  font-weight: 500;
}

.im-header-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 14px;
}

.im-header-note {
  font-size: 12.5px;
  color: #6b7080;
}

/* Main */
.im-main {
  flex: 1;
  max-width: 1240px;
  width: 100%;
  margin: 0 auto;
  padding: 44px 32px 80px;
  box-sizing: border-box;
}

/* Intro */
.im-intro {
  max-width: 680px;
  margin-bottom: 32px;
}

.im-eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #8a8d99;
  margin-bottom: 10px;
}

.im-h1 {
  font-family: 'Inter Tight', sans-serif;
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.15;
  margin: 0 0 8px;
  color: #111318;
}

.im-lead {
  font-size: 14px;
  color: #6b7080;
  margin: 0;
  line-height: 1.6;
}

/* Editor window */
.im-window {
  border: 1px solid rgba(22,24,29,0.10);
  border-radius: 14px;
  background: #ffffff;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(22,24,29,0.03), 0 16px 44px -24px rgba(22,24,29,0.16);
}

/* Title bar */
.im-titlebar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border-bottom: 1px solid rgba(22,24,29,0.07);
  background: #fcfcfd;
}

.im-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.im-dot-r { background: #ff5f57; }
.im-dot-y { background: #febc2e; }
.im-dot-g { background: #28c840; }

.im-titlebar-filename {
  margin-left: 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: #6b7080;
}

.im-titlebar-chips {
  margin-left: auto;
  display: inline-flex;
  gap: 6px;
}

.im-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 10px 2px 4px;
  border-radius: 9999px;
  font-size: 11px;
  font-weight: 600;
}

.im-chip-you {
  background: rgba(67,83,201,0.07);
  border: 1px solid rgba(67,83,201,0.20);
  color: #4353c9;
}

.im-chip-claude {
  background: rgba(30,127,92,0.07);
  border: 1px solid rgba(30,127,92,0.22);
  color: #1e7f5c;
}

.im-chip-avatar {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 8px;
  font-weight: 700;
  color: #fff;
  flex-shrink: 0;
}

.im-chip-avatar-you { background: #4353c9; }
.im-chip-avatar-claude { background: #1e7f5c; }

/* Body grid */
.im-body {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(280px, 1fr);
}

/* Code pane */
.im-code-pane {
  border-right: 1px solid rgba(22,24,29,0.07);
  background: #0f1116;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12.5px;
  line-height: 1.85;
  padding: 14px 0;
  overflow-x: auto;
}

.im-code-line {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
}

.im-line-num {
  text-align: right;
  padding-right: 14px;
  color: #c4c6cf;
  user-select: none;
  opacity: 0.4;
}

.im-line-text {
  white-space: pre;
  position: relative;
  padding-right: 16px;
}

.im-caret {
  display: inline-block;
  width: 2px;
  height: 15px;
  background: #1e7f5c;
  vertical-align: text-bottom;
  animation: imCaret 1s step-end infinite;
}

.im-caret-label {
  display: inline-block;
  font-family: 'Inter', sans-serif;
  font-size: 9px;
  font-weight: 600;
  color: #fff;
  background: #1e7f5c;
  border-radius: 3px;
  padding: 0 5px;
  position: relative;
  top: -9px;
  left: 4px;
}

/* Session rail */
.im-rail {
  display: flex;
  flex-direction: column;
  background: #fcfcfd;
  min-height: 340px;
}

.im-rail-status {
  padding: 14px 18px;
  border-bottom: 1px solid rgba(22,24,29,0.06);
}

.im-rail-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #8a8d99;
  font-weight: 500;
  margin-bottom: 10px;
}

.im-status-rows {
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 12.5px;
}

.im-status-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.im-dot-status {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}

.im-dot-green { background: #1e7f5c; }
.im-gate-dot { background: #b45309; }

.im-dot-pulse {
  animation: imPulse 1.4s ease-in-out infinite;
}

.im-status-text {
  color: #16181d;
}

.im-status-secondary {
  color: #6b7080;
}

/* Chat feed */
.im-chat-feed {
  flex: 1;
  padding: 14px 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow-y: auto;
  max-height: 260px;
}

.im-chat-msg {
  display: flex;
  gap: 9px;
  align-items: flex-start;
}

.im-chat-avatar {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 8px;
  font-weight: 700;
  flex-shrink: 0;
  margin-top: 1px;
}

.im-chat-text {
  font-size: 12.5px;
  color: #16181d;
  margin: 0;
  line-height: 1.55;
}

/* Chat input */
.im-chat-input-row {
  padding: 12px 14px;
  border-top: 1px solid rgba(22,24,29,0.06);
  display: flex;
  gap: 8px;
}

.im-chat-input {
  flex: 1;
  border: 1px solid rgba(22,24,29,0.10);
  border-radius: 8px;
  padding: 7px 12px;
  outline: none;
  font-family: inherit;
  font-size: 12.5px;
  color: #16181d;
  background: #ffffff;
  box-sizing: border-box;
  min-width: 0;
}

.im-chat-input:focus {
  border-color: rgba(67,83,201,0.35);
  box-shadow: 0 0 0 2px rgba(67,83,201,0.08);
}

.im-chat-send {
  padding: 7px 13px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 500;
  border: 0;
  background: #16181d;
  color: #fff;
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
  transition: opacity 0.15s;
}

.im-chat-send:hover {
  opacity: 0.85;
}

/* Status bar */
.im-statusbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 7px 16px;
  border-top: 1px solid rgba(22,24,29,0.07);
  background: #fcfcfd;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: #8a8d99;
}

.im-statusbar-right {
  margin-left: auto;
}

.im-mode-toggle {
  border: 0;
  background: none;
  color: #4353c9;
  cursor: pointer;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  padding: 0;
  text-decoration: underline;
  text-decoration-color: transparent;
  transition: text-decoration-color 0.15s;
}

.im-mode-toggle:hover {
  text-decoration-color: #4353c9;
}

/* Footer note */
.im-footer-note {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-top: 24px;
  align-items: flex-start;
}

.im-footer-text {
  font-size: 12.5px;
  color: #8a8d99;
  margin: 0;
  max-width: 60ch;
  line-height: 1.6;
}

.im-footer-strong {
  color: #16181d;
  font-weight: 500;
}

.im-footer-link {
  font-size: 13px;
  color: #4353c9;
  text-decoration: none;
  white-space: nowrap;
}

.im-footer-link:hover {
  text-decoration: underline;
}

@media (max-width: 768px) {
  .im-main {
    padding: 28px 18px 60px;
  }
  .im-body {
    grid-template-columns: 1fr;
  }
  .im-rail {
    border-top: 1px solid rgba(22,24,29,0.07);
    border-right: none;
  }
}
`;
