<?php
// /var/www/m2usenet/index.php
// m2usenet v2.6.0 - Face Header + Identity Hash v2

if (session_status() === PHP_SESSION_NONE) {
    ini_set('session.cookie_httponly', 1);
    ini_set('session.cookie_secure', 0);  // .onion non ha TLS
    ini_set('session.use_strict_mode', 1);
    ini_set('session.cookie_samesite', 'Lax');  // Strict può bloccare su .onion
    session_start();
}

if (!isset($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$csrfToken = $_SESSION['csrf_token'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>m2usenet Gateway v2.6</title>
  <style>
    :root {
      --background: #f9f9f9;
      --card-bg: #fff;
      --text: #333;
      --border: #ccc;
      --primary: #4caf50;
      --primary-hover: #45a049;
      --tab-bg: #eee;
      --input-bg: #fff;
      --input-readonly: #eee;
      --progress-bg: #ddd;
      --success: #28a745;
      --warning: #ffc107;
      --error: #dc3545;
    }

    .dark-theme {
      --background: #1a1a1a;
      --card-bg: #2c2c2c;
      --text: #e0e0e0;
      --border: #444;
      --primary: #5cbb60;
      --primary-hover: #4caf50;
      --tab-bg: #333;
      --input-bg: #3c3c3c;
      --input-readonly: #2a2a2a;
      --progress-bg: #444;
    }

    body {
      background: var(--background);
      color: var(--text);
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      margin: 0;
      padding: 0;
      transition: background 0.3s ease;
    }

    .container {
      max-width: 800px;
      margin: auto;
      padding: 20px;
    }

    header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20px;
    }

    .theme-toggle {
      display: flex;
      align-items: center;
      gap: 8px;
    }

    .toggle {
      position: relative;
      width: 60px;
      height: 30px;
      background: #ccc;
      border-radius: 30px;
      padding: 4px;
      cursor: pointer;
      transition: 0.3s;
    }

    .toggle:before {
      content: '';
      position: absolute;
      width: 26px;
      height: 26px;
      border-radius: 50%;
      background: white;
      top: 2px;
      left: 2px;
      transition: 0.3s;
    }

    input[type="checkbox"]:checked + .toggle {
      background: #4caf50;
    }

    input[type="checkbox"]:checked + .toggle:before {
      transform: translateX(30px);
    }

    input[type="checkbox"] {
      display: none;
    }

    .notification {
      position: fixed;
      top: 20px;
      right: 20px;
      max-width: 400px;
      padding: 15px 20px;
      border-radius: 8px;
      box-shadow: 0 4px 12px rgba(0,0,0,0.3);
      z-index: 10000;
      animation: slideIn 0.3s ease;
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .notification.success { background: var(--success); color: white; }
    .notification.error { background: var(--error); color: white; }
    .notification.warning { background: var(--warning); color: #333; }
    .notification.info { background: #007bff; color: white; }

    @keyframes slideIn {
      from { transform: translateX(400px); opacity: 0; }
      to { transform: translateX(0); opacity: 1; }
    }

    @keyframes pulse {
      0% { box-shadow: 0 0 0 0 rgba(156, 39, 176, 0.7); }
      50% { box-shadow: 0 0 0 15px rgba(156, 39, 176, 0); }
      100% { box-shadow: 0 0 0 0 rgba(156, 39, 176, 0); }
    }

    .notification-icon { font-size: 1.5em; }
    .notification-close { margin-left: auto; cursor: pointer; font-size: 1.2em; opacity: 0.8; }
    .notification-close:hover { opacity: 1; }

    .section-info {
      background: var(--card-bg);
      border-left: 4px solid var(--primary);
      padding: 10px 15px;
      margin-bottom: 15px;
      border-radius: 0 4px 4px 0;
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }

    .tabs {
      display: flex;
      flex-direction: column;
      gap: 8px;
      margin-bottom: 15px;
    }

    .tabs button {
      display: flex;
      align-items: center;
      justify-content: space-between;
      width: 100%;
      padding: 12px 15px;
      border: none;
      background: var(--tab-bg);
      color: var(--text);
      cursor: pointer;
      border-radius: 4px;
      font-weight: bold;
      transition: background 0.2s, transform 0.1s;
      position: relative;
    }

    .tabs button:hover { background: var(--primary); color: white; }
    .tabs button:active { transform: scale(0.98); }

    .tabs button.completed::after {
      content: '✓';
      position: absolute;
      right: 15px;
      background: var(--success);
      color: white;
      width: 24px;
      height: 24px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 0.9em;
    }

    .tab-content {
      display: none !important;
      padding: 20px;
      background: var(--card-bg);
      border: 1px solid var(--border);
      border-radius: 4px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.1);
      margin-bottom: 20px;
    }

    .tab-content.active {
      display: block !important;
    }

    label {
      display: block;
      margin-top: 15px;
      font-weight: bold;
      margin-bottom: 5px;
    }

    input, textarea, select {
      width: 100%;
      padding: 10px;
      margin-top: 5px;
      box-sizing: border-box;
      border: 1px solid var(--border);
      border-radius: 4px;
      background: var(--input-bg);
      color: var(--text);
      font-family: inherit;
    }

    input:focus, textarea:focus, select:focus {
      outline: none;
      border-color: var(--primary);
      box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.2);
    }

    input.error, textarea.error { border-color: var(--error); }

    input[readonly], textarea[readonly] {
      background: var(--input-readonly);
      cursor: not-allowed;
      border: 2px solid #999;
    }

    input.prefilled {
      background: #e8f5e9;
      border: 2px solid var(--primary);
    }

    .dark-theme input.prefilled {
      background: #1b3d1b;
    }

    button {
      margin-top: 15px;
      padding: 12px 20px;
      background: var(--primary);
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-weight: bold;
      transition: background 0.2s, opacity 0.2s;
      font-family: inherit;
    }

    button:hover:not(:disabled) { background: var(--primary-hover); }
    button:disabled { opacity: 0.6; cursor: not-allowed; }

    .btn-secondary {
      background: #6c757d;
    }
    .btn-secondary:hover:not(:disabled) { background: #5a6268; }

    .progress-bar {
      width: 100%;
      background: var(--progress-bg);
      border-radius: 5px;
      overflow: hidden;
      height: 20px;
      margin-top: 10px;
    }

    .progress-bar-inner {
      height: 100%;
      width: 0;
      background: var(--primary);
      text-align: center;
      color: white;
      line-height: 20px;
      transition: width 0.3s;
      font-size: 0.85em;
    }

    .output-field {
      margin-top: 15px;
      padding: 10px;
      background: var(--input-readonly);
      border: 1px solid var(--border);
      border-radius: 4px;
      word-break: break-all;
      min-height: 30px;
      font-family: monospace;
      font-size: 0.9em;
    }

    .output-field.empty { color: #999; font-style: italic; }

    .gateway-info {
      background: var(--card-bg);
      border: 1px solid var(--border);
      padding: 15px;
      margin: 15px 0;
      border-radius: 4px;
      border-left: 4px solid #007bff;
    }

    .gateway-item {
      display: flex;
      align-items: center;
      padding: 8px 0;
      border-bottom: 1px solid var(--border);
    }

    .gateway-item:last-child { border-bottom: none; }

    .gateway-priority {
      background: #007bff;
      color: white;
      padding: 2px 8px;
      border-radius: 12px;
      font-size: 0.8em;
      margin-right: 10px;
      min-width: 70px;
      text-align: center;
    }

    .gateway-address {
      font-family: monospace;
      background: var(--input-readonly);
      padding: 4px 8px;
      border-radius: 4px;
      flex: 1;
      font-size: 0.85em;
    }

    .prefill-banner {
      background: linear-gradient(135deg, #4caf50 0%, #45a049 100%);
      color: white;
      padding: 12px 15px;
      border-radius: 4px;
      margin-bottom: 15px;
      display: flex;
      align-items: center;
      gap: 10px;
      box-shadow: 0 2px 8px rgba(76, 175, 80, 0.3);
    }

    .prefill-banner.reply {
      background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);
    }

    .prefill-banner-icon { font-size: 1.5em; }
    .prefill-banner-text { flex: 1; }
    .prefill-banner-text strong { display: block; margin-bottom: 2px; }
    .prefill-banner-text small { opacity: 0.9; }

    .keypair-actions {
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
      margin-top: 15px;
    }

    .keypair-actions button {
      flex: 1;
      min-width: 150px;
    }

    .identity-loaded {
      background: #d4edda;
      border: 1px solid #c3e6cb;
      padding: 10px 15px;
      border-radius: 4px;
      margin-top: 15px;
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .dark-theme .identity-loaded {
      background: #1e3d1e;
      border-color: #2e5d2e;
    }

    .identity-loaded-icon { font-size: 1.5em; }
    .identity-loaded-text { flex: 1; }

    .identicon-preview {
      display: inline-block;
      vertical-align: middle;
      margin-left: 10px;
    }

    .identicon-preview img {
      width: 32px;
      height: 32px;
      image-rendering: pixelated;
      border: 1px solid var(--border);
      border-radius: 4px;
    }

    .identicon-section {
      background: var(--card-bg);
      border: 1px solid var(--border);
      border-left: 4px solid #9c27b0;
      padding: 15px;
      margin: 15px 0;
      border-radius: 0 4px 4px 0;
      text-align: center;
    }

    .identicon-section h4 {
      margin: 0 0 15px 0;
      color: #9c27b0;
    }

    .identicon-large-preview {
      margin: 15px 0;
    }

    .identicon-hash {
      font-size: 0.8em;
      color: #666;
      word-break: break-all;
      margin: 10px 0;
    }

    .identicon-hash code {
      background: var(--input-readonly);
      padding: 4px 8px;
      border-radius: 4px;
      display: inline-block;
      max-width: 100%;
      overflow-x: auto;
    }

    .identicon-actions {
      display: flex;
      gap: 10px;
      justify-content: center;
      flex-wrap: wrap;
      margin: 15px 0;
    }

    .identicon-actions button {
      margin: 0;
      padding: 8px 15px;
      font-size: 0.9em;
    }

    .identicon-tip {
      background: #f3e5f5;
      padding: 10px;
      border-radius: 4px;
      margin-top: 10px;
    }

    .dark-theme .identicon-tip {
      background: #2d1f30;
    }

    .dark-theme #saveIdentityWarning {
      background: linear-gradient(135deg, #3d3510 0%, #4a4012 100%);
      border-color: #856404;
    }
    
    .dark-theme #saveIdentityWarning p {
      color: #ffc107;
    }

    footer {
      text-align: center;
      margin-top: 40px;
      padding-top: 20px;
      border-top: 1px solid var(--border);
      font-size: 0.9em;
      color: #888;
    }

    .footer-links {
      display: flex;
      justify-content: center;
      gap: 20px;
      margin-top: 10px;
    }

    .footer-links a {
      color: var(--primary);
      text-decoration: none;
      transition: color 0.2s;
    }

    .footer-links a:hover {
      color: var(--primary-hover);
      text-decoration: underline;
    }

    @media (max-width: 600px) {
      .container { padding: 10px; }
      .tab-content { padding: 15px 10px; }
      .footer-links { flex-direction: column; gap: 10px; }
      .gateway-item { flex-direction: column; align-items: flex-start; gap: 5px; }
      .gateway-address { width: 100%; }
      .notification { right: 10px; left: 10px; max-width: none; }
      .keypair-actions { flex-direction: column; }
      .keypair-actions button { min-width: 100%; }
    }
  </style>
  <script src="https://cdn.jsdelivr.net/npm/tweetnacl@1.0.3/nacl.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/tweetnacl-util@0.15.1/nacl-util.min.js"></script>
</head>
<body>
<div class="container">
  <header>
    <h1>m2usenet Gateway v2.6</h1>
    <div class="theme-toggle">
      <span>🌞</span>
      <input type="checkbox" id="themeToggle">
      <label for="themeToggle" class="toggle"></label>
      <span>🌙</span>
    </div>
  </header>

  <div id="prefillBanner" class="prefill-banner" style="display: none;">
    <span class="prefill-banner-icon">📝</span>
    <div class="prefill-banner-text">
      <strong id="prefillTitle">New Post</strong>
      <small id="prefillDetails">Fields pre-filled from Onion Newsreader</small>
    </div>
  </div>

  <div class="tabs">
    <button id="tabBtn1" onclick="showTab('pow')">
      <span>1. Generate Hashcash Token</span>
    </button>
    <button id="tabBtn2" onclick="showTab('sign')">
      <span>2. Sign Message (Identity)</span>
    </button>
    <button id="tabBtn3" onclick="showTab('send')">
      <span>3. Send Message</span>
    </button>
  </div>

  <div id="pow" class="tab-content active">
    <h2>1. Load Identity or Start Fresh</h2>
    
    <div class="identity-loader" style="background: var(--card-bg); border: 2px dashed var(--primary); border-radius: 8px; padding: 20px; margin-bottom: 20px; text-align: center;">
      <p style="margin: 0 0 15px 0;"><strong>🔑 Have a saved identity?</strong> Load it to auto-fill all fields.</p>
      <button id="loadIdentityBtn" class="btn-primary" style="font-size: 1.1em; padding: 12px 30px;">📂 Load Identity File</button>
      <input type="file" id="identityFileInput" accept=".json" style="display:none;">
      <p style="margin: 15px 0 0 0; font-size: 0.9em; color: var(--text); opacity: 0.7;">Or fill the fields below to create a new identity.</p>
    </div>
    
    <div id="identityLoadedPow" class="identity-loaded" style="display:none; margin-bottom: 20px;">
      <span class="identity-loaded-icon">✅</span>
      <div class="identity-loaded-text">
        <strong id="loadedIdentityName">Identity Loaded</strong>
        <small id="loadedIdentityEmail">email@example.com</small>
      </div>
      <div class="identicon-preview">
        <img id="identiconPreviewPow" alt="Your identicon" style="width: 48px; height: 48px; image-rendering: pixelated; border-radius: 4px;">
      </div>
    </div>
    
    <div class="section-info">
      <p><strong>About m2usenet:</strong> This application is a privacy-focused gateway that sends your messages to Usenet newsgroups via Tor hidden services. No access logs are collected.</p>
      <p><strong>What is Proof-of-Work?</strong> This step generates a hashcash token that prevents spam by requiring your computer to perform some calculations.</p>
    </div>
    
    <label>Username (your pseudonym): <input type="text" id="fromName" placeholder="YourPseudonym" required></label>
    <label>Email (for identity hash): <input type="email" id="hcEmail" placeholder="your@email.onion" required></label>
    <label>Difficulty (bits):
      <select id="hcBits">
        <option value="16">16 bits (very fast, ~instant - recommended for Tor Browser)</option>
        <option value="20" selected>20 bits (fast, ~few seconds)</option>
        <option value="24">24 bits (medium, ~30-60 seconds)</option>
        <option value="28">28 bits (slow, ~several minutes)</option>
      </select>
    </label>
    <button id="genTokenBtn">Generate Token</button>
    <div class="progress-bar"><div id="tokenProgress" class="progress-bar-inner">Ready</div></div>
    <label>Generated Token:</label>
    <div id="tokenOutput" class="output-field empty">Token will appear here after generation</div>
  </div>

  <div id="sign" class="tab-content">
    <h2>2. Sign Your Message</h2>
    
    <div id="identiconSection" class="identicon-section" style="display:none;">
      <h4>🎨 Your Visual Identity</h4>
      <div style="display: flex; align-items: center; gap: 20px; flex-wrap: wrap;">
        <div class="identicon-large-preview">
          <img id="identiconPreviewLarge" alt="Your identicon" style="width:96px;height:96px;image-rendering:pixelated;border:2px solid var(--border);border-radius:8px;">
        </div>
        <div style="flex: 1; min-width: 200px;">
          <p style="margin: 0 0 5px 0;"><strong id="identityUsername">Username</strong></p>
          <p style="margin: 0 0 10px 0; font-size: 0.9em; color: var(--text); opacity: 0.8;" id="identityEmail">email@example.com</p>
          <p class="identicon-hash" style="margin: 0;"><small>Hash: <code id="identityHashDisplay"></code></small></p>
        </div>
      </div>
      <div class="identicon-actions" style="margin-top: 15px;">
        <button type="button" id="downloadIdenticonBtn" class="btn-secondary">📥 Identicon</button>
        <button type="button" id="saveIdentityBtn" class="btn-secondary">💾 Save Identity</button>
      </div>
      <div id="saveIdentityWarning" style="margin-top: 15px; padding: 12px; background: linear-gradient(135deg, #fff3cd 0%, #ffeeba 100%); border: 1px solid #ffc107; border-radius: 6px; text-align: center;">
        <p style="margin: 0; color: #856404; font-weight: bold;">⚠️ You must save your identity to continue!</p>
        <p style="margin: 5px 0 0 0; color: #856404; font-size: 0.9em;">Click "Save Identity" above to download your identity file. This is required before signing and sending messages.</p>
      </div>
      <p style="margin-top: 15px; text-align: center; font-size: 0.9em;">
        <a href="/verify/" style="color: #9c27b0; text-decoration: none;">🔐 VFACE Verifier - Verify an identity</a>
      </p>
    </div>
    
    <div class="section-info">
      <p><strong>What is this?</strong> Your message will be signed with Ed25519. The signature proves you authored this post.</p>
      <p><strong>Face Header:</strong> Your identicon is embedded as a <code>Face:</code> header (RFC 4021) visible in newsreaders like Newsgrouper.</p>
    </div>

    <label>Email (from PoW):</label>
    <input type="text" id="readonlyEmailSign" readonly>
    
    <label>Message to Sign:</label>
    <textarea id="messageToSign" rows="6" placeholder="Write your message here..." required></textarea>
    
    <div class="keypair-actions">
      <button id="genKeyBtn">🔑 Generate New Keypair</button>
    </div>
    <input type="file" id="keyFileInput" accept=".json" style="display:none;">
    
    <button id="signMsgBtn" disabled>✍️ Sign Message</button>
    
    <label>Public Key:</label>
    <div id="pubKeyOutput" class="output-field empty">Public key will appear here</div>
    <label>Signature:</label>
    <div id="signatureOutput" class="output-field empty">Signature will appear here</div>
  </div>

  <div id="send" class="tab-content">
    <h2>Send Message</h2>
    <div class="section-info">
      <p><strong>What is this?</strong> This final step sends your signed message to the Usenet network via Tor hidden services.</p>
      <div class="gateway-info">
        <h4>🔐 Full Onion Network Path</h4>
        <p style="margin-bottom: 15px; font-size: 0.95em;">Your message travels entirely within the Tor network:</p>
        
        <div class="gateway-item">
          <span class="gateway-priority">Step 1</span>
          <div style="flex: 1;">
            <strong>SMTP Relays:</strong>
            <p style="font-size: 0.85em; margin: 5px 0 0 0; color: #666;">Specialized SMTP relays operating over Tor hidden services</p>
          </div>
        </div>
        <details style="margin-top: 8px; font-size: 0.8em;">
          <summary style="cursor: pointer; color: #007bff;">Show relay nodes</summary>
          <ul style="margin: 8px 0; padding-left: 20px; font-family: monospace; color: #555;">
            <li><strong>PRIMARY:</strong> 4uwpi53u524xdphjw2dv5kywsxmyjxtk4facb76jgl3sc3nda3sz4fqd.onion:25</li>
            <li><strong>FALLBACK:</strong> xilb7y4kj6u6qfo45o3yk2kilfv54ffukzei3puonuqlncy7cn2afwyd.onion:25</li>
          </ul>
        </details>
        
        <div class="gateway-item">
          <span class="gateway-priority">Step 2</span>
          <div style="flex: 1;">
            <strong>Mail2News Gateway</strong>
            <div class="gateway-address" style="margin-top: 5px;">mail2news@xilb7y4kj6u6qfo45o3yk2kilfv54ffukzei3puonuqlncy7cn2afwyd.onion</div>
            <p style="font-size: 0.85em; margin: 5px 0 0 0; color: #666;">Converts email to Usenet posts while maintaining full anonymity.</p>
          </div>
        </div>
        
        <div class="gateway-item">
          <span class="gateway-priority">Step 3</span>
          <div style="flex: 1;">
            <strong>NNTP Server</strong>
            <div class="gateway-address" style="margin-top: 5px;">nntp://peannyjkqwqfynd24p6dszvtchkq7hfkwymi5by5y332wmosy5dwfaqd.onion</div>
            <p style="font-size: 0.85em; margin: 5px 0 0 0; color: #666;">Final destination for Usenet Tor hidden service.</p>
          </div>
        </div>
        
        <p style="margin-top: 15px; padding: 10px; background: rgba(0,123,255,0.1); border-radius: 4px; font-size: 0.9em;">
          <strong>🔒 Privacy Guarantee:</strong> Your message never leaves the Tor network until it reaches the NNTP server. All three components (SMTP → Mail2News → NNTP) operate as Tor hidden services, providing end-to-end anonymity.
        </p>
      </div>
    </div>

    <label>Email used for PoW:</label>
    <input type="text" id="readonlyEmailSend" readonly>
    <form id="sendForm" method="POST" action="send.php">
      <input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
      <label>From (Name):</label>
      <input type="text" id="readonlyFromName" readonly>
      <input type="hidden" name="from" id="fromFull">
      <label>Newsgroups (max 3, comma separated):
        <input type="text" name="newsgroups" id="newsgroups" required placeholder="e.g. alt.privacy, comp.security">
      </label>
      <label>Subject: <input type="text" name="subject" id="subject" required placeholder="Message Subject"></label>
      <label>References (optional): <input type="text" name="references" id="references" placeholder="Message-ID of post you're replying to"></label>
      <label>X-Hashcash Token: <input type="text" name="xhashcash" id="hcToken" required readonly></label>
      <label>Message:</label>
      <textarea name="message" id="messageContent" rows="8" required placeholder="Your message will appear here after signing..."></textarea>
      <input type="hidden" name="x-ed25519-pub" id="x-ed25519-pub">
      <input type="hidden" name="x-ed25519-sig" id="x-ed25519-sig">
      <button type="submit" id="sendBtn">Send Message</button>
    </form>
  </div>

  <footer>
    <div>m2usenet Gateway v2.6.0 © 2025 - Privacy-focused Usenet posting via Tor</div>
    <div class="footer-links">
      <a href="https://yamn.virebent.art">Home</a>
      <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;%69%6E%66%6F%40%76%69%72%65%62%65%6E%74%2E%61%72%74">Contact</a>
      <a href="https://github.com/gabrix73/m2usenet-go">Code</a>
    </div>
  </footer>
</div>

<script>
// ============================================================================
// GLOBAL FUNCTIONS - MUST BE DEFINED FIRST
// ============================================================================

function showTab(id) {
  // Block access to send tab if identity not saved
  if (id === 'send' && !appState.identitySaved) {
    showNotification('⚠ Please save your identity first before sending!', 'warning');
    return;
  }
  document.querySelectorAll('.tab-content').forEach(el => el.classList.remove('active'));
  document.getElementById(id).classList.add('active');
}

function showNotification(message, type, duration) {
  type = type || 'info';
  duration = duration === undefined ? 5000 : duration;
  const icons = { success: '✓', error: '✗', warning: '⚠', info: 'ℹ' };
  const notification = document.createElement('div');
  notification.className = `notification ${type}`;
  notification.innerHTML = `
    <span class="notification-icon">${icons[type] || icons.info}</span>
    <span class="notification-message">${message}</span>
    <span class="notification-close" onclick="this.parentElement.remove()">×</span>
  `;
  document.body.appendChild(notification);
  if (duration > 0) {
    setTimeout(() => { if (notification.parentElement) notification.remove(); }, duration);
  }
}

// ============================================================================
// STATE MANAGEMENT
// ============================================================================

const appState = {
  step1Complete: false,
  step2Complete: false,
  step3Complete: false,
  identitySaved: false,
  prefillMode: null
};

function updateTabIndicators() {
  if (appState.step1Complete) document.getElementById('tabBtn1').classList.add('completed');
  if (appState.step2Complete) document.getElementById('tabBtn2').classList.add('completed');
  if (appState.step3Complete) document.getElementById('tabBtn3').classList.add('completed');
}

let keyPair = null;
let workersSupported = true;

try {
  if (typeof Worker === 'undefined') {
    workersSupported = false;
  }
} catch (e) {
  workersSupported = false;
}

// ============================================================================
// THEME TOGGLE
// ============================================================================

document.getElementById('themeToggle').addEventListener('change', function() {
  document.body.classList.toggle('dark-theme', this.checked);
  localStorage.setItem('darkTheme', this.checked);
});

// ============================================================================
// IDENTICON GENERATION (client-side)
// ============================================================================

let currentIdenticonData = null;

async function generateIdenticon(username, email, pubkeyBase64) {
  const identityString = username + '|' + email + '|' + pubkeyBase64;
  const encoder = new TextEncoder();
  const data = encoder.encode(identityString);
  const hashBuffer = await crypto.subtle.digest('SHA-256', data);
  const hash = new Uint8Array(hashBuffer);
  const hashHex = Array.from(hash).map(b => b.toString(16).padStart(2, '0')).join('');
  
  const size = 128;
  const gridSize = 5;
  const padding = 0.08;
  
  const hue = ((hash[0] << 8) | hash[1]) % 360;
  const fgColor = `hsl(${hue}, 65%, 45%)`;
  const bgHue = (hue + 180) % 360;
  const bgColor = `hsl(${bgHue}, 15%, 92%)`;
  
  const grid = [];
  const halfWidth = Math.ceil(gridSize / 2);
  let bitIndex = 16;
  
  for (let row = 0; row < gridSize; row++) {
    grid[row] = [];
    for (let col = 0; col < halfWidth; col++) {
      const byteIndex = Math.floor(bitIndex / 8);
      const bitOffset = bitIndex % 8;
      const bit = (hash[byteIndex] >> bitOffset) & 1;
      grid[row][col] = bit === 1;
      bitIndex++;
    }
    for (let col = halfWidth; col < gridSize; col++) {
      grid[row][col] = grid[row][gridSize - 1 - col];
    }
  }
  
  const canvas = document.createElement('canvas');
  canvas.width = size;
  canvas.height = size;
  const ctx = canvas.getContext('2d');
  
  const paddingPx = Math.floor(size * padding);
  const cellSize = Math.floor((size - paddingPx * 2) / gridSize);
  const offset = paddingPx + Math.floor((size - paddingPx * 2 - cellSize * gridSize) / 2);
  
  ctx.fillStyle = bgColor;
  ctx.fillRect(0, 0, size, size);
  
  ctx.fillStyle = fgColor;
  for (let row = 0; row < gridSize; row++) {
    for (let col = 0; col < gridSize; col++) {
      if (grid[row][col]) {
        ctx.fillRect(offset + col * cellSize, offset + row * cellSize, cellSize, cellSize);
      }
    }
  }
  
  const dataUrl = canvas.toDataURL('image/png');
  
  currentIdenticonData = {
    dataUrl: dataUrl,
    hash: hashHex,
    username: username,
    email: email,
    pubkey: pubkeyBase64,
    claim: JSON.stringify({
      version: 2,
      type: 'm2usenet-identity',
      username: username,
      email: email,
      pubkey: pubkeyBase64,
      identityHash: hashHex,
      created: new Date().toISOString(),
      algorithm: 'sha256(username|email|pubkey)'
    }, null, 2)
  };
  
  return dataUrl;
}

async function updateIdenticonPreview() {
  if (!keyPair) return;
  
  const pubB64 = nacl.util.encodeBase64(keyPair.publicKey);
  const username = document.getElementById('fromName').value || 'Anonymous';
  const email = document.getElementById('hcEmail').value || 'anonymous@m2usenet.local';
  
  try {
    const identiconUrl = await generateIdenticon(username, email, pubB64);
    
    document.getElementById('identiconPreviewPow').src = identiconUrl;
    document.getElementById('identiconPreviewLarge').src = identiconUrl;
    document.getElementById('identityHashDisplay').textContent = currentIdenticonData.hash.substring(0, 16) + '...';
    document.getElementById('identityUsername').textContent = username;
    document.getElementById('identityEmail').textContent = email;
    document.getElementById('identiconSection').style.display = 'block';
    
  } catch (e) {
    console.error('Identicon generation failed:', e);
  }
}

document.getElementById('downloadIdenticonBtn').onclick = function() {
  if (!currentIdenticonData) {
    showNotification('⚠ Generate a keypair first!', 'warning');
    return;
  }
  
  const a = document.createElement('a');
  a.href = currentIdenticonData.dataUrl;
  a.download = 'identicon-' + currentIdenticonData.hash.substring(0, 8) + '.png';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  
  showNotification('✓ Identicon downloaded!', 'success', 3000);
};

// ============================================================================
// INITIALIZATION
// ============================================================================

document.addEventListener('DOMContentLoaded', function() {
  const darkTheme = localStorage.getItem('darkTheme') === 'true';
  document.getElementById('themeToggle').checked = darkTheme;
  document.body.classList.toggle('dark-theme', darkTheme);

  if (typeof nacl === 'undefined') {
    showNotification('Cryptography library failed to load. Please refresh the page.', 'error', 0);
    return;
  }

  if (typeof nacl.util === 'undefined') {
    nacl.util = {
      decodeUTF8: function(str) { return new TextEncoder().encode(str); },
      encodeUTF8: function(arr) { return new TextDecoder().decode(arr); },
      encodeBase64: function(arr) {
        return btoa(Array.from(new Uint8Array(arr)).map(byte => String.fromCharCode(byte)).join(''));
      },
      decodeBase64: function(b64) {
        const bin = atob(b64);
        const arr = new Uint8Array(bin.length);
        for (let i = 0; i < bin.length; i++) arr[i] = bin.charCodeAt(i);
        return arr;
      }
    };
  }

  showTab('pow');
  showNotification('m2usenet Gateway v2.6.0 ready', 'success', 3000);
});

// ============================================================================
// FORM SUBMISSION PROTECTION
// ============================================================================

document.addEventListener('DOMContentLoaded', function() {
  const form = document.querySelector('form');
  const submitButton = form.querySelector('button[type="submit"]');
  
  if (!submitButton) return;
  
  let isSubmitting = false;
  
  form.addEventListener('submit', function(e) {
    if (isSubmitting) {
      e.preventDefault();
      return false;
    }
    
    isSubmitting = true;
    submitButton.disabled = true;
    submitButton.textContent = 'Sending...';
    submitButton.style.opacity = '0.6';
    submitButton.style.cursor = 'not-allowed';
    
    const progressDiv = document.createElement('div');
    progressDiv.id = 'sending-progress';
    progressDiv.style.cssText = 'margin-top: 10px; padding: 10px; background: #fff3cd; border-left: 4px solid #ffc107; color: #856404;';
    progressDiv.innerHTML = '<strong>⏳ Sending message...</strong><br>This may take up to 60 seconds via Tor. Please wait.';
    submitButton.parentNode.insertBefore(progressDiv, submitButton.nextSibling);
    
    return true;
  });
});

// ============================================================================
// SHA-1 IMPLEMENTATION
// ============================================================================

function sha1(str) {
  function rotate_left(n, s) { return (n << s) | (n >>> (32 - s)); }
  function cvt_hex(val) {
    let str = '';
    for (let i = 7; i >= 0; i--) {
      const v = (val >>> (i * 4)) & 0x0f;
      str += v.toString(16);
    }
    return str;
  }
  function utf8Encode(str) { return unescape(encodeURIComponent(str)); }

  let blockstart, i, j;
  const W = new Array(80);
  let H0 = 0x67452301, H1 = 0xEFCDAB89, H2 = 0x98BADCFE, H3 = 0x10325476, H4 = 0xC3D2E1F0;
  let A, B, C, D, E, temp;

  str = utf8Encode(str);
  const str_len = str.length;
  const word_array = [];
  
  for (i = 0; i < str_len - 3; i += 4) {
    j = str.charCodeAt(i) << 24 | str.charCodeAt(i + 1) << 16 | str.charCodeAt(i + 2) << 8 | str.charCodeAt(i + 3);
    word_array.push(j);
  }

  switch (str_len % 4) {
    case 0: i = 0x080000000; break;
    case 1: i = str.charCodeAt(str_len - 1) << 24 | 0x0800000; break;
    case 2: i = str.charCodeAt(str_len - 2) << 24 | str.charCodeAt(str_len - 1) << 16 | 0x08000; break;
    case 3: i = str.charCodeAt(str_len - 3) << 24 | str.charCodeAt(str_len - 2) << 16 | str.charCodeAt(str_len - 1) << 8 | 0x80; break;
  }

  word_array.push(i);
  while ((word_array.length % 16) != 14) word_array.push(0);
  word_array.push(str_len >>> 29);
  word_array.push((str_len << 3) & 0x0ffffffff);

  for (blockstart = 0; blockstart < word_array.length; blockstart += 16) {
    for (i = 0; i < 16; i++) W[i] = word_array[blockstart + i];
    for (i = 16; i <= 79; i++) W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);

    A = H0; B = H1; C = H2; D = H3; E = H4;

    for (i = 0; i <= 19; i++) {
      temp = (rotate_left(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
      E = D; D = C; C = rotate_left(B, 30); B = A; A = temp;
    }
    for (i = 20; i <= 39; i++) {
      temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
      E = D; D = C; C = rotate_left(B, 30); B = A; A = temp;
    }
    for (i = 40; i <= 59; i++) {
      temp = (rotate_left(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
      E = D; D = C; C = rotate_left(B, 30); B = A; A = temp;
    }
    for (i = 60; i <= 79; i++) {
      temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
      E = D; D = C; C = rotate_left(B, 30); B = A; A = temp;
    }

    H0 = (H0 + A) & 0x0ffffffff;
    H1 = (H1 + B) & 0x0ffffffff;
    H2 = (H2 + C) & 0x0ffffffff;
    H3 = (H3 + D) & 0x0ffffffff;
    H4 = (H4 + E) & 0x0ffffffff;
  }

  return cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);
}

function mineSingleThread(prefix, targetZeros, progressCallback, foundCallback) {
  const target = '0'.repeat(targetZeros);
  let nonce = 0, checked = 0;
  const batchSize = 100;

  function mineNextBatch() {
    const endNonce = nonce + batchSize;
    while (nonce < endNonce) {
      const token = prefix + nonce;
      const hash = sha1(token);
      checked++;
      if (hash.startsWith(target)) {
        foundCallback(nonce, checked);
        return;
      }
      nonce++;
    }
    progressCallback(checked);
    setTimeout(mineNextBatch, 0);
  }
  mineNextBatch();
}

// ============================================================================
// STEP 1: HASHCASH TOKEN GENERATION
// ============================================================================

document.getElementById('genTokenBtn').onclick = () => {
  const email = document.getElementById('hcEmail').value.trim();
  const bits = parseInt(document.getElementById('hcBits').value);

  if (!email) {
    showNotification('⚠ Please enter your email address first!', 'warning');
    document.getElementById('hcEmail').classList.add('error');
    document.getElementById('hcEmail').focus();
    return;
  }

  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailRegex.test(email)) {
    showNotification('⚠ Please enter a valid email address!', 'warning');
    document.getElementById('hcEmail').classList.add('error');
    document.getElementById('hcEmail').focus();
    return;
  }

  document.getElementById('hcEmail').classList.remove('error');
  showNotification(`🔨 Starting token generation (${bits} bits)...`, 'info');

  const btn = document.getElementById('genTokenBtn');
  btn.disabled = true;
  btn.textContent = 'Mining Token...';

  const now = new Date();
  const timestamp = now.getUTCFullYear().toString().slice(2) +
                    ("0"+(now.getUTCMonth()+1)).slice(-2) +
                    ("0"+now.getUTCDate()).slice(-2) +
                    ("0"+now.getUTCHours()).slice(-2) +
                    ("0"+now.getUTCMinutes()).slice(-2) +
                    ("0"+now.getUTCSeconds()).slice(-2);
  const ext = "";
  const rand = Math.floor(Math.random()*1e6);
  const prefix = `1:${bits}:${timestamp}:${email}:${ext}:${rand}:`;
  const zeros = bits/4;

  const progBar = document.getElementById('tokenProgress');
  progBar.style.width = '0%';
  progBar.innerText = 'Mining...';

  let totalChecked = 0;
  let startTime = Date.now();

  function updateProgress(checked) {
    totalChecked += checked;
    const elapsed = (Date.now() - startTime) / 1000;
    const hashRate = Math.round(totalChecked / elapsed);
    progBar.style.width = Math.min(95, (totalChecked / 10000)) + '%';
    progBar.innerText = `${totalChecked} hashes (${hashRate}/s)`;
  }

  function onFound(nonce, totalHashes) {
    const token = prefix + nonce;
    const outputField = document.getElementById('tokenOutput');
    outputField.innerText = token;
    outputField.classList.remove('empty');
    document.getElementById('hcToken').value = token;

    const fromName = document.getElementById('fromName').value || 'Anonymous';
    document.getElementById('fromFull').value = `${fromName} <${email}>`;
    document.getElementById('readonlyFromName').value = fromName;
    document.getElementById('readonlyEmailSign').value = email;
    document.getElementById('readonlyEmailSend').value = email;

    btn.disabled = false;
    btn.textContent = 'Generate Token';
    progBar.style.width = '100%';
    progBar.innerText = `Complete! (${totalHashes} hashes)`;

    appState.step1Complete = true;
    updateTabIndicators();

    const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
    showNotification(`✓ Token generated in ${elapsed}s!`, 'success', 8000);

    setTimeout(() => showTab('sign'), 2000);
  }

  if (workersSupported) {
    try {
      const cores = navigator.hardwareConcurrency || 2;
      let found = false;
      let coreChecked = Array(cores).fill(0);
      const workers = [];

      function updateCombinedProgress() {
        const sum = coreChecked.reduce((a,b)=>a+b,0);
        updateProgress(sum - totalChecked);
      }

      for (let i = 0; i < cores; i++) {
        try {
          const w = new Worker('powWorker.js');
          w.postMessage({ prefix, targetZeros: zeros, startNonce: i, step: cores });

          w.onmessage = e => {
            if (found) return;
            if (e.data.type === 'found') {
              found = true;
              workers.forEach(x => x.terminate());
              onFound(e.data.nonce, e.data.checked);
            }
            if (e.data.type === 'progress') {
              coreChecked[i] = e.data.checked;
              updateCombinedProgress();
            }
          };

          w.onerror = (err) => {
            if (i === 0) {
              workers.forEach(x => x.terminate());
              mineSingleThread(prefix, zeros, updateProgress, onFound);
            }
          };

          workers.push(w);
        } catch (err) {
          if (i === 0) {
            mineSingleThread(prefix, zeros, updateProgress, onFound);
            return;
          }
        }
      }

    } catch (err) {
      mineSingleThread(prefix, zeros, updateProgress, onFound);
    }
  } else {
    mineSingleThread(prefix, zeros, updateProgress, onFound);
  }
};

// ============================================================================
// STEP 2: ED25519 SIGNATURE + KEYPAIR MANAGEMENT
// ============================================================================

document.getElementById('genKeyBtn').onclick = async function() {
  try {
    showNotification('🔐 Generating Ed25519 key pair...', 'info');
    keyPair = nacl.sign.keyPair();

    const pubB64 = nacl.util.encodeBase64(keyPair.publicKey);

    const pubOutput = document.getElementById('pubKeyOutput');
    pubOutput.innerText = pubB64;
    pubOutput.classList.remove('empty');
    document.getElementById('x-ed25519-pub').value = pubB64;
    document.getElementById('signMsgBtn').disabled = false;

    const username = document.getElementById('fromName').value || 'Anonymous';
    const email = document.getElementById('hcEmail').value || '';
    document.getElementById('identityLoadedPow').style.display = 'flex';
    document.getElementById('loadedIdentityName').textContent = username;
    document.getElementById('loadedIdentityEmail').textContent = email || 'New keypair - save identity!';
    
    await updateIdenticonPreview();

    showNotification('✓ Key pair generated! Write your message and sign it.', 'success', 6000);
  } catch (error) {
    showNotification('✗ Error: ' + error.message, 'error');
  }
};

document.getElementById('loadIdentityBtn').onclick = function() {
  document.getElementById('identityFileInput').click();
};

document.getElementById('identityFileInput').onchange = async function(e) {
  const file = e.target.files[0];
  if (!file) return;

  try {
    const text = await file.text();
    const data = JSON.parse(text);

    if (!data.publicKey || !data.secretKey) {
      throw new Error('Invalid identity file format');
    }

    const pubKey = nacl.util.decodeBase64(data.publicKey);
    const secKey = nacl.util.decodeBase64(data.secretKey);

    if (pubKey.length !== 32 || secKey.length !== 64) {
      throw new Error('Invalid key lengths');
    }

    keyPair = { publicKey: pubKey, secretKey: secKey };

    const pubB64 = data.publicKey;
    const pubOutput = document.getElementById('pubKeyOutput');
    pubOutput.innerText = pubB64;
    pubOutput.classList.remove('empty');
    document.getElementById('x-ed25519-pub').value = pubB64;
    document.getElementById('signMsgBtn').disabled = false;

    if (data.username) {
      document.getElementById('fromName').value = data.username;
      document.getElementById('readonlyFromName').value = data.username;
    }
    if (data.email) {
      document.getElementById('hcEmail').value = data.email;
      const fromName = document.getElementById('fromName').value || 'Anonymous';
      document.getElementById('fromFull').value = `${fromName} <${data.email}>`;
      document.getElementById('readonlyEmailSign').value = data.email;
      document.getElementById('readonlyEmailSend').value = data.email;
    }

    const username = data.username || 'Anonymous';
    const email = data.email || '';
    document.getElementById('identityLoadedPow').style.display = 'flex';
    document.getElementById('loadedIdentityName').textContent = username;
    document.getElementById('loadedIdentityEmail').textContent = email;
    
    await updateIdenticonPreview();
    
    if (currentIdenticonData && currentIdenticonData.dataUrl) {
      document.getElementById('identiconPreviewPow').src = currentIdenticonData.dataUrl;
    }

    document.getElementById('genKeyBtn').disabled = true;
    document.getElementById('genKeyBtn').textContent = '✓ Keypair Loaded';
    
    // Identity already saved (loaded from file) - allow access to send tab
    appState.identitySaved = true;
    document.getElementById('saveIdentityBtn').textContent = '✓ Identity Loaded';
    document.getElementById('saveIdentityBtn').style.background = '#28a745';
    
    // Hide the warning message
    const warning = document.getElementById('saveIdentityWarning');
    if (warning) warning.style.display = 'none';

    showNotification('✓ Identity loaded! Username and email populated. Now generate PoW token.', 'success', 6000);
  } catch (error) {
    showNotification('✗ Failed to load identity: ' + error.message, 'error');
  }

  e.target.value = '';
};

document.getElementById('saveIdentityBtn').onclick = async function() {
  if (!keyPair) {
    showNotification('⚠ Generate a keypair first!', 'warning');
    return;
  }

  const username = document.getElementById('fromName').value || 'Anonymous';
  const email = document.getElementById('hcEmail').value || 'anonymous@m2usenet.local';
  const pubB64 = nacl.util.encodeBase64(keyPair.publicKey);
  const secB64 = nacl.util.encodeBase64(keyPair.secretKey);
  
  const identityString = username + '|' + email + '|' + pubB64;
  const encoder = new TextEncoder();
  const hashBuffer = await crypto.subtle.digest('SHA-256', encoder.encode(identityString));
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  const identityHash = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');

  const data = {
    version: 2,
    type: 'm2usenet-identity',
    username: username,
    email: email,
    publicKey: pubB64,
    secretKey: secB64,
    identityHash: identityHash,
    algorithm: 'sha256(username|email|pubkey)',
    created: new Date().toISOString(),
    warning: 'Keep this file secure! Anyone with this file can sign messages as you.'
  };

  const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'm2usenet-identity-' + username + '.json';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);

  // Mark identity as saved - allows access to send tab
  appState.identitySaved = true;
  
  // Update button to show saved state
  this.textContent = '✓ Identity Saved';
  this.style.background = '#28a745';
  
  // Hide the warning message
  const warning = document.getElementById('saveIdentityWarning');
  if (warning) warning.style.display = 'none';
  
  // If message already signed, go to send tab
  if (appState.step2Complete) {
    showNotification('✓ Identity saved! Proceeding to send...', 'success', 4000);
    setTimeout(() => showTab('send'), 1500);
  } else {
    showNotification('✓ Identity saved! Now sign your message to continue.', 'success', 6000);
  }
};

document.getElementById('signMsgBtn').onclick = function() {
  try {
    if (!keyPair) {
      showNotification('⚠ Please generate or load a key pair first!', 'warning');
      return;
    }

    const msg = document.getElementById('messageToSign').value.trim();
    if (!msg) {
      showNotification('⚠ Please write a message!', 'warning');
      document.getElementById('messageToSign').classList.add('error');
      document.getElementById('messageToSign').focus();
      return;
    }

    if (msg.length < 10) {
      showNotification('⚠ Message too short (min 10 characters)', 'warning');
      return;
    }

    document.getElementById('messageToSign').classList.remove('error');
    showNotification('✍ Signing message...', 'info');

    const msgBytes = nacl.util.decodeUTF8(msg);
    const sig = nacl.sign.detached(msgBytes, keyPair.secretKey);
    const sigB64 = nacl.util.encodeBase64(sig);

    const sigOutput = document.getElementById('signatureOutput');
    sigOutput.innerText = sigB64;
    sigOutput.classList.remove('empty');
    document.getElementById('x-ed25519-sig').value = sigB64;

    document.getElementById('messageContent').value = msg + "\n\n--- Digital Signature ---\n" + sigB64;

    appState.step2Complete = true;
    updateTabIndicators();

    // After signing, check if identity is saved
    if (!appState.identitySaved) {
      // Scroll to identicon section and prompt to save
      showNotification('✓ Message signed! Now save your identity to continue.', 'warning', 10000);
      setTimeout(() => {
        const identiconSection = document.getElementById('identiconSection');
        if (identiconSection) {
          identiconSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
          identiconSection.style.animation = 'pulse 1s ease-in-out 3';
        }
      }, 500);
    } else {
      // Identity already saved, proceed to send
      showNotification('✓ Message signed with your identity!', 'success', 8000);
      setTimeout(() => showTab('send'), 2000);
    }
  } catch (error) {
    showNotification('✗ Error: ' + error.message, 'error');
  }
};

document.getElementById('fromName').addEventListener('input', function() {
  const email = document.getElementById('hcEmail').value;
  document.getElementById('readonlyFromName').value = this.value;
  if (email) {
    document.getElementById('fromFull').value = `${this.value} <${email}>`;
  }
  if (keyPair) {
    updateIdenticonPreview();
  }
});

// ============================================================================
// STEP 3: SEND FORM
// ============================================================================

document.getElementById('sendForm').addEventListener('submit', function(e) {
  const requiredFields = [
    {id: 'fromFull', name: 'From'},
    {id: 'newsgroups', name: 'Newsgroups'},
    {id: 'subject', name: 'Subject'},
    {id: 'hcToken', name: 'Hashcash Token'},
    {id: 'messageContent', name: 'Message'},
    {id: 'x-ed25519-pub', name: 'Public Key'},
    {id: 'x-ed25519-sig', name: 'Signature'}
  ];

  const missing = [];
  requiredFields.forEach(field => {
    const el = document.getElementById(field.id);
    if (!el.value.trim()) {
      missing.push(field.name);
      el.classList.add('error');
    } else {
      el.classList.remove('error');
    }
  });

  if (missing.length > 0) {
    e.preventDefault();
    showNotification(`⚠ Missing: ${missing.join(', ')}`, 'warning', 8000);
    return false;
  }

  const messageLen = document.getElementById('messageContent').value.length;
  if (messageLen < 10) {
    e.preventDefault();
    showNotification('⚠ Message too short', 'warning');
    return false;
  }

  const newsgroups = document.getElementById('newsgroups').value.split(',').map(g => g.trim()).filter(g => g);
  if (newsgroups.length === 0) {
    e.preventDefault();
    showNotification('⚠ Enter at least one newsgroup!', 'warning');
    return false;
  }

  if (newsgroups.length > 3) {
    e.preventDefault();
    showNotification('⚠ Max 3 newsgroups!', 'warning');
    return false;
  }

  const confirmMsg = `Send message?\n\nNewsgroups: ${newsgroups.join(', ')}\nSubject: ${document.getElementById('subject').value}\nLength: ${messageLen} chars\n\nDelivery via Tor may take up to 60 seconds.`;

  if (!confirm(confirmMsg)) {
    e.preventDefault();
    return false;
  }

  showNotification('📤 Sending message...', 'info', 0);
  document.getElementById('sendBtn').disabled = true;
  document.getElementById('sendBtn').textContent = 'Sending...';

  return true;
});

// ============================================================================
// ONION-NEWSREADER INTEGRATION
// ============================================================================

(function() {
  function decode(s) {
    if (!s) return '';
    try {
      return decodeURIComponent(s.replace(/\+/g, ' '));
    } catch(e) {
      return s;
    }
  }

  function fillField(id, value, highlight) {
    highlight = highlight !== false;
    const field = document.getElementById(id);
    if (field && value) {
      field.value = value;
      if (highlight) field.classList.add('prefilled');
      return true;
    }
    return false;
  }

  function showPrefillBanner(isReply, details) {
    const banner = document.getElementById('prefillBanner');
    const title = document.getElementById('prefillTitle');
    const detailsEl = document.getElementById('prefillDetails');
    
    if (banner) {
      banner.style.display = 'flex';
      if (isReply) {
        banner.classList.add('reply');
        title.textContent = '💬 Reply Mode';
      } else {
        title.textContent = '📝 New Post';
      }
      detailsEl.textContent = details;
    }
  }

  let prefillData = null;
  let prefillSource = null;

  try {
    const storedData = localStorage.getItem('m2usenet_prefill');
    if (storedData) {
      prefillData = JSON.parse(storedData);
      prefillSource = 'localStorage';
      localStorage.removeItem('m2usenet_prefill');
      
      if (prefillData.newsgroups) prefillData.newsgroups = decode(prefillData.newsgroups);
      if (prefillData.subject) prefillData.subject = decode(prefillData.subject);
      if (prefillData.references) prefillData.references = decode(prefillData.references);
    }
  } catch (e) {
    localStorage.removeItem('m2usenet_prefill');
  }

  if (!prefillData) {
    const params = new URLSearchParams(window.location.search);
    const action = params.get('action');
    
    if (action === 'new' || action === 'reply' || params.has('newsgroups')) {
      prefillData = {
        newsgroups: decode(params.get('newsgroups') || ''),
        subject: decode(params.get('subject') || ''),
        references: decode(params.get('references') || ''),
        body: decode(params.get('body') || '')
      };
      prefillSource = 'URL';
    }
  }

  if (prefillData) {
    let filledFields = [];
    
    if (prefillData.newsgroups) {
      fillField('newsgroups', prefillData.newsgroups);
      filledFields.push('Newsgroups');
    }
    
    if (prefillData.subject) {
      fillField('subject', prefillData.subject);
      filledFields.push('Subject');
    }
    
    if (prefillData.references) {
      fillField('references', prefillData.references);
      filledFields.push('References');
    }
    
    if (prefillData.body) {
      fillField('messageToSign', prefillData.body);
      filledFields.push('Quoted message');
    }

    const isReply = !!(prefillData.references || 
                       (prefillData.subject && prefillData.subject.toLowerCase().startsWith('re:')));

    if (filledFields.length > 0) {
      const details = `Pre-filled: ${filledFields.join(', ')} (from ${prefillSource})`;
      showPrefillBanner(isReply, details);
      
      if (isReply) {
        showNotification(`💬 Reply mode: ${prefillData.newsgroups}`, 'info', 5000);
      } else {
        showNotification(`📝 New post to: ${prefillData.newsgroups}`, 'success', 5000);
      }
    }

    setTimeout(() => showTab('pow'), 300);
  }
})();
</script>

</body>
</html>
