import { Router } from "express";

const router = Router();

router.get("/ui", (_req, res) => {
  res.setHeader("Content-Type", "text/html");
  res.send(`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Timmy — Lightning AI Agent</title>
<style>
  :root {
    --bg: #0a0a0f;
    --surface: #13131a;
    --border: #2a2a3a;
    --accent: #f7931a;
    --accent2: #7b61ff;
    --text: #e8e8f0;
    --muted: #6b6b80;
    --green: #00d4aa;
    --red: #ff4d6d;
  }
  * { box-sizing: border-box; margin: 0; padding: 0; }
  body {
    background: var(--bg);
    color: var(--text);
    font-family: 'SF Mono', 'Fira Code', monospace;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 40px 20px;
  }
  header {
    text-align: center;
    margin-bottom: 40px;
  }
  header h1 {
    font-size: 2.2rem;
    font-family: system-ui, sans-serif;
    font-weight: 700;
    letter-spacing: -1px;
  }
  header h1 span { color: var(--accent); }
  header p {
    color: var(--muted);
    margin-top: 8px;
    font-family: system-ui, sans-serif;
    font-size: 0.95rem;
  }
  .badge {
    display: inline-block;
    background: #1a1a2e;
    border: 1px solid var(--accent2);
    color: var(--accent2);
    font-size: 0.7rem;
    padding: 2px 8px;
    border-radius: 4px;
    margin-left: 8px;
    vertical-align: middle;
    letter-spacing: 1px;
  }
  .card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 28px;
    width: 100%;
    max-width: 640px;
    margin-bottom: 16px;
  }
  .card h2 {
    font-family: system-ui, sans-serif;
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 16px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 1px;
  }
  textarea {
    width: 100%;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text);
    font-family: system-ui, sans-serif;
    font-size: 1rem;
    padding: 14px;
    resize: vertical;
    min-height: 100px;
    outline: none;
    transition: border-color 0.2s;
  }
  textarea:focus { border-color: var(--accent2); }
  .char-count {
    text-align: right;
    font-size: 0.75rem;
    color: var(--muted);
    margin-top: 6px;
  }
  .char-count.warn { color: var(--accent); }
  .char-count.over { color: var(--red); }
  button {
    background: var(--accent);
    color: #000;
    border: none;
    border-radius: 8px;
    padding: 12px 24px;
    font-family: system-ui, sans-serif;
    font-size: 0.95rem;
    font-weight: 700;
    cursor: pointer;
    transition: opacity 0.2s, transform 0.1s;
    margin-top: 16px;
    width: 100%;
  }
  button:hover { opacity: 0.9; transform: translateY(-1px); }
  button:disabled { opacity: 0.4; cursor: not-allowed; transform: none; }
  button.secondary {
    background: transparent;
    border: 1px solid var(--accent);
    color: var(--accent);
  }
  button.pay-btn {
    background: var(--green);
    color: #000;
  }
  .pipeline {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 24px;
    flex-wrap: wrap;
  }
  .step {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.78rem;
    color: var(--muted);
    font-family: system-ui, sans-serif;
  }
  .step .dot {
    width: 10px; height: 10px;
    border-radius: 50%;
    background: var(--border);
    flex-shrink: 0;
    transition: background 0.4s;
  }
  .step.active .dot { background: var(--accent); box-shadow: 0 0 8px var(--accent); }
  .step.done .dot { background: var(--green); }
  .step.rejected .dot { background: var(--red); }
  .step.active { color: var(--text); }
  .step.done { color: var(--green); }
  .step.rejected { color: var(--red); }
  .arrow { color: var(--border); font-size: 0.8rem; }
  .invoice-box {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 16px;
    margin-top: 12px;
  }
  .invoice-box .label {
    font-size: 0.72rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 1px;
    margin-bottom: 6px;
  }
  .invoice-box .amount {
    font-size: 1.8rem;
    font-weight: 700;
    color: var(--accent);
    font-family: system-ui, sans-serif;
  }
  .invoice-box .amount span {
    font-size: 1rem;
    color: var(--muted);
    font-weight: 400;
  }
  .invoice-box .payment-request {
    margin-top: 10px;
    font-size: 0.68rem;
    color: var(--muted);
    word-break: break-all;
    line-height: 1.4;
    border-top: 1px solid var(--border);
    padding-top: 10px;
  }
  .invoice-box .hash-line {
    margin-top: 8px;
    font-size: 0.72rem;
    color: var(--accent2);
  }
  .result-box {
    background: var(--bg);
    border: 1px solid var(--green);
    border-radius: 8px;
    padding: 20px;
    margin-top: 12px;
    line-height: 1.7;
    font-family: system-ui, sans-serif;
    font-size: 0.95rem;
    white-space: pre-wrap;
  }
  .rejected-box {
    background: var(--bg);
    border: 1px solid var(--red);
    border-radius: 8px;
    padding: 20px;
    margin-top: 12px;
    font-family: system-ui, sans-serif;
    font-size: 0.95rem;
    color: var(--red);
  }
  .status-line {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 0.85rem;
    color: var(--muted);
    margin-top: 12px;
    font-family: system-ui, sans-serif;
  }
  .spinner {
    width: 14px; height: 14px;
    border: 2px solid var(--border);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
    flex-shrink: 0;
  }
  @keyframes spin { to { transform: rotate(360deg); } }
  .hidden { display: none !important; }
  .error-msg {
    color: var(--red);
    font-family: system-ui, sans-serif;
    font-size: 0.88rem;
    margin-top: 10px;
  }
  .mode-tag {
    display: inline-block;
    font-size: 0.68rem;
    padding: 2px 6px;
    border-radius: 4px;
    margin-left: 6px;
    vertical-align: middle;
  }
  .mode-stub { background: #1a1a2e; color: var(--accent2); border: 1px solid var(--accent2); }
  .reset-btn {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--muted);
    margin-top: 8px;
  }
</style>
</head>
<body>

<header>
  <h1><span>⚡</span> Timmy <span class="badge">STUB MODE</span></h1>
  <p>Lightning-gated AI agent — visual payment flow demo</p>
</header>

<div class="card" id="pipeline-card">
  <div class="pipeline">
    <div class="step" id="s-request"><div class="dot"></div>Request</div>
    <div class="arrow">→</div>
    <div class="step" id="s-eval"><div class="dot"></div>Eval fee</div>
    <div class="arrow">→</div>
    <div class="step" id="s-judge"><div class="dot"></div>Judge</div>
    <div class="arrow">→</div>
    <div class="step" id="s-work"><div class="dot"></div>Work fee</div>
    <div class="arrow">→</div>
    <div class="step" id="s-result"><div class="dot"></div>Result</div>
  </div>
</div>

<!-- Step 1: Enter request -->
<div class="card" id="card-input">
  <h2>Your request</h2>
  <textarea id="request-input" placeholder="Ask Timmy anything — e.g. 'Explain how Lightning Network payment channels work'" maxlength="500"></textarea>
  <div class="char-count" id="char-count">0 / 500</div>
  <div id="input-error" class="error-msg hidden"></div>
  <button id="submit-btn" onclick="createJob()">Create job &amp; get eval invoice →</button>
</div>

<!-- Step 2: Pay eval invoice -->
<div class="card hidden" id="card-eval">
  <h2>Step 1 — Pay eval invoice <span class="mode-tag mode-stub">stub</span></h2>
  <div class="invoice-box">
    <div class="label">Amount due</div>
    <div class="amount" id="eval-amount">—<span> sats</span></div>
    <div class="payment-request" id="eval-pr"></div>
    <div class="hash-line">hash: <span id="eval-hash"></span></div>
  </div>
  <p style="font-family:system-ui,sans-serif;font-size:0.82rem;color:var(--muted);margin-top:14px;">
    In production this would be a scannable BOLT11 invoice. In stub mode, click below to simulate payment instantly.
  </p>
  <button class="pay-btn" id="pay-eval-btn" onclick="payEval()">⚡ Simulate eval payment</button>
  <div class="status-line hidden" id="eval-polling"><div class="spinner"></div> Waiting for eval AI…</div>
</div>

<!-- Step 3: Rejected -->
<div class="card hidden" id="card-rejected">
  <h2>Request rejected</h2>
  <div class="rejected-box" id="rejected-reason"></div>
  <button class="reset-btn" onclick="reset()">← Start over</button>
</div>

<!-- Step 4: Pay work invoice -->
<div class="card hidden" id="card-work">
  <h2>Step 2 — Pay work invoice <span class="mode-tag mode-stub">stub</span></h2>
  <div class="invoice-box">
    <div class="label">Amount due</div>
    <div class="amount" id="work-amount">—<span> sats</span></div>
    <div class="payment-request" id="work-pr"></div>
    <div class="hash-line">hash: <span id="work-hash"></span></div>
  </div>
  <p style="font-family:system-ui,sans-serif;font-size:0.82rem;color:var(--muted);margin-top:14px;">
    Work fee is priced by request length. Click to simulate payment and Timmy will start working.
  </p>
  <button class="pay-btn" id="pay-work-btn" onclick="payWork()">⚡ Simulate work payment</button>
  <div class="status-line hidden" id="work-polling"><div class="spinner"></div> Timmy is working…</div>
</div>

<!-- Step 5: Result -->
<div class="card hidden" id="card-result">
  <h2>✓ Complete</h2>
  <div class="result-box" id="result-text"></div>
  <button class="reset-btn" onclick="reset()">← New job</button>
</div>

<script>
  const BASE = window.location.origin;
  let jobId = null;
  let evalHash = null;
  let workHash = null;
  let pollTimer = null;

  const $ = id => document.getElementById(id);
  const show = id => $(id).classList.remove('hidden');
  const hide = id => $(id).classList.add('hidden');

  function setStep(name) {
    const steps = ['s-request','s-eval','s-judge','s-work','s-result'];
    const map = {
      request: 0, awaiting_eval_payment: 1, evaluating: 2,
      awaiting_work_payment: 3, executing: 3, complete: 4,
      rejected: 2
    };
    const idx = map[name] ?? -1;
    steps.forEach((s, i) => {
      const el = $(s);
      el.classList.remove('active','done','rejected');
      if (i < idx) el.classList.add('done');
      else if (i === idx) {
        el.classList.add(name === 'rejected' && i === 2 ? 'rejected' : 'active');
      }
    });
  }

  $('request-input').addEventListener('input', () => {
    const len = $('request-input').value.length;
    const el = $('char-count');
    el.textContent = len + ' / 500';
    el.className = 'char-count' + (len > 450 ? (len >= 500 ? ' over' : ' warn') : '');
  });

  async function createJob() {
    const req = $('request-input').value.trim();
    hide('input-error');
    if (!req) { showErr('input-error', 'Please enter a request.'); return; }

    $('submit-btn').disabled = true;
    $('submit-btn').textContent = 'Creating job…';

    try {
      const r = await fetch(BASE + '/api/jobs', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ request: req })
      });
      const data = await r.json();
      if (!r.ok) { showErr('input-error', data.error || 'Failed to create job'); $('submit-btn').disabled = false; $('submit-btn').textContent = 'Create job & get eval invoice →'; return; }

      jobId = data.jobId;
      evalHash = data.evalInvoice.paymentHash;

      $('eval-amount').innerHTML = data.evalInvoice.amountSats + '<span> sats</span>';
      $('eval-pr').textContent = data.evalInvoice.paymentRequest;
      $('eval-hash').textContent = evalHash;

      hide('card-input');
      show('card-eval');
      setStep('awaiting_eval_payment');
    } catch(e) {
      showErr('input-error', 'Network error: ' + e.message);
      $('submit-btn').disabled = false;
      $('submit-btn').textContent = 'Create job & get eval invoice →';
    }
  }

  async function payEval() {
    $('pay-eval-btn').disabled = true;
    $('pay-eval-btn').textContent = 'Paying…';
    try {
      const r = await fetch(BASE + '/api/dev/stub/pay/' + evalHash, { method: 'POST' });
      if (!r.ok) { alert('Stub pay failed'); $('pay-eval-btn').disabled = false; return; }
      show('eval-polling');
      setStep('evaluating');
      pollJob('eval');
    } catch(e) {
      alert('Error: ' + e.message);
      $('pay-eval-btn').disabled = false;
    }
  }

  async function payWork() {
    $('pay-work-btn').disabled = true;
    $('pay-work-btn').textContent = 'Paying…';
    try {
      const r = await fetch(BASE + '/api/dev/stub/pay/' + workHash, { method: 'POST' });
      if (!r.ok) { alert('Stub pay failed'); $('pay-work-btn').disabled = false; return; }
      show('work-polling');
      setStep('executing');
      pollJob('work');
    } catch(e) {
      alert('Error: ' + e.message);
      $('pay-work-btn').disabled = false;
    }
  }

  function pollJob(phase) {
    clearInterval(pollTimer);
    pollTimer = setInterval(async () => {
      try {
        const r = await fetch(BASE + '/api/jobs/' + jobId);
        if (!r.ok) return; // keep polling on transient errors
        const data = await r.json();
        const s = data.state;

        // Failed is terminal regardless of phase
        if (s === 'failed') {
          clearInterval(pollTimer);
          hide('card-eval');
          hide('card-work');
          $('rejected-reason').textContent = 'Error: ' + (data.errorMessage || 'Something went wrong. Try again.');
          show('card-rejected');
          setStep('rejected');
          return;
        }

        if (phase === 'eval') {
          // evaluating = AI running in background, keep waiting
          if (s === 'evaluating') return;
          if (s === 'rejected') {
            clearInterval(pollTimer);
            hide('card-eval');
            $('rejected-reason').textContent = data.reason || 'Request was rejected.';
            show('card-rejected');
            setStep('rejected');
          } else if (s === 'awaiting_work_payment') {
            clearInterval(pollTimer);
            workHash = data.workInvoice.paymentHash;
            $('work-amount').innerHTML = data.workInvoice.amountSats + '<span> sats</span>';
            $('work-pr').textContent = data.workInvoice.paymentRequest;
            $('work-hash').textContent = workHash;
            hide('card-eval');
            show('card-work');
            setStep('awaiting_work_payment');
          }
        } else if (phase === 'work') {
          // executing = AI running in background, keep waiting
          if (s === 'executing') return;
          if (s === 'complete') {
            clearInterval(pollTimer);
            hide('card-work');
            $('result-text').textContent = data.result;
            show('card-result');
            setStep('complete');
          }
        }
      } catch(e) { /* keep polling through network errors */ }
    }, 1500);
  }

  function reset() {
    clearInterval(pollTimer);
    jobId = evalHash = workHash = null;
    $('request-input').value = '';
    $('char-count').textContent = '0 / 500';
    $('submit-btn').disabled = false;
    $('submit-btn').textContent = 'Create job & get eval invoice →';
    $('pay-eval-btn').disabled = false;
    $('pay-eval-btn').textContent = '⚡ Simulate eval payment';
    $('pay-work-btn').disabled = false;
    $('pay-work-btn').textContent = '⚡ Simulate work payment';
    hide('eval-polling'); hide('work-polling');
    hide('card-eval'); hide('card-rejected'); hide('card-work'); hide('card-result');
    show('card-input');
    document.querySelectorAll('.step').forEach(el => el.classList.remove('active','done','rejected'));
  }

  function showErr(id, msg) { $(id).textContent = msg; show(id); }

  setStep('request');
  $('s-request').classList.add('active');
</script>
</body>
</html>`);
});

export default router;
