// content-backup-chat.js - Export current ChatGPT conversation as Markdown or HTML (ShareGift Theme + Print Fix + Logo Fix)
(function () {
  if (window.__chatgpt_backup_btn_injected__) return;
  window.__chatgpt_backup_btn_injected__ = true;

  const CHAT_RE = /\/c\/([a-z0-9\-]+)/i;
  const POS_KEY = "gpt_backup_btn_pos";

  // ---------- utils ----------
  const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
  const loadPos = () => { try { return JSON.parse(localStorage.getItem(POS_KEY) || "null"); } catch { return null; } };
  const savePos = (style) => {
    try {
      const vw = window.innerWidth, vh = window.innerHeight;
      const b = parseFloat(style.bottom || "80");
      const r = parseFloat(style.right || "24");
      localStorage.setItem(POS_KEY, JSON.stringify({
        bottomPct: clamp((b / vh) * 100, 0, 100),
        rightPct: clamp((r / vw) * 100, 0, 100),
      }));
    } catch {}
  };
  const applyPos = (btn) => {
    const pos = loadPos();
    if (pos && typeof pos.bottomPct === "number" && typeof pos.rightPct === "number") {
      btn.style.bottom = `${pos.bottomPct}vh`;
      btn.style.right = `${(pos.rightPct / 100) * window.innerWidth}px`;
    } else {
      btn.style.bottom = "80px";
      btn.style.right = "24px";
    }
  };

  // ---------- inject styles (ShareGift Theme) ----------
  const STYLE_ID = "gpt-backup-styles";
  if (!document.getElementById(STYLE_ID)) {
    const style = document.createElement("style");
    style.id = STYLE_ID;
    style.textContent = `
      /* Format selection modal - ShareGift Style */
      .bkp-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.6);backdrop-filter:blur(4px);display:none;z-index:2147483647;align-items:center;justify-content:center}
      .bkp-modal{width:min(480px,calc(100vw - 32px));border-radius:24px;background:rgba(13, 31, 67, 0.9);backdrop-filter:blur(16px);border:1px solid rgba(175, 197, 232, 0.15);color:#fff;box-shadow:0 24px 80px rgba(0,0,0,.5);padding:24px;font-family:'Vazirmatn',system-ui,sans-serif;direction:rtl;animation:bkpSlideUp .3s cubic-bezier(0.2,0.8,0.2,1)}
      @keyframes bkpSlideUp{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}
      .bkp-modal h3{margin:0 0 8px;font-size:18px;color:#2b78ff;text-align:center;font-weight:800}
      .bkp-modal .bkp-desc{font-size:13px;color:#b7c8e2;text-align:center;margin-bottom:20px}
      .bkp-format-btns{display:flex;gap:12px;margin-bottom:16px}
      .bkp-format-btn{flex:1;padding:16px 12px;border-radius:16px;border:1px solid rgba(255,255,255,0.1);background:rgba(255,255,255,0.03);color:#fff;cursor:pointer;text-align:center;transition:all .2s ease;font-family:inherit}
      .bkp-format-btn:hover{border-color:rgba(43, 120, 255, 0.4);background:rgba(43, 120, 255, 0.1);transform:translateY(-2px);box-shadow:0 8px 24px rgba(43,120,255,.15)}
      .bkp-format-btn .bkp-icon{font-size:28px;display:block;margin-bottom:8px}
      .bkp-format-btn .bkp-label{font-size:14px;font-weight:700;display:block;color:#fff}
      .bkp-format-btn .bkp-sublabel{font-size:11px;color:#b7c8e2;display:block;margin-top:4px;opacity:0.8}
      .bkp-cancel{width:100%;padding:12px;border-radius:14px;border:1px solid rgba(255,255,255,0.1);background:transparent;color:#b7c8e2;cursor:pointer;font-size:13px;font-weight:700;font-family:inherit;transition:all .2s}
      .bkp-cancel:hover{background:rgba(255,255,255,0.05);color:#fff}

      /* Progress bar - ShareGift Style */
      .bkp-progress-wrap{position:fixed;top:20px;left:50%;transform:translateX(-50%);z-index:2147483647;min-width:320px;background:rgba(13, 31, 67, 0.95);backdrop-filter:blur(16px);border:1px solid rgba(175, 197, 232, 0.15);border-radius:16px;padding:16px 20px;box-shadow:0 12px 40px rgba(0,0,0,.4);direction:rtl;font-family:'Vazirmatn',system-ui,sans-serif;animation:bkpSlideDown .3s cubic-bezier(0.2,0.8,0.2,1);display:none}
      @keyframes bkpSlideDown{from{opacity:0;transform:translate(-50%,-20px)}to{opacity:1;transform:translate(-50%,0)}}
      .bkp-progress-text{font-size:13px;color:#fff;margin-bottom:12px;font-weight:700}
      .bkp-progress-bar-outer{width:100%;height:6px;background:rgba(255,255,255,0.1);border-radius:6px;overflow:hidden}
      .bkp-progress-bar-inner{height:100%;background:linear-gradient(90deg,#2b78ff,#20df9e);border-radius:6px;transition:width .3s ease;width:0%}
      .bkp-progress-detail{font-size:11px;color:#b7c8e2;margin-top:8px;text-align:left}
    `;
    document.head.appendChild(style);
  }

  // ---------- format selection modal ----------
  const backdrop = document.createElement("div");
  backdrop.className = "bkp-backdrop";
  const modal = document.createElement("div");
  modal.className = "bkp-modal";
  modal.innerHTML = `
    <h3>خروجی بکاپ</h3>
    <div class="bkp-desc">فرمت مورد نظر خود را انتخاب کنید</div>
    <div class="bkp-format-btns">
      <div class="bkp-format-btn" data-format="html">
        <span class="bkp-icon">&lt;/&gt;</span>
        <span class="bkp-label">HTML</span>
        <span class="bkp-sublabel">صفحه وب زیبا و تعاملی</span>
      </div>
      <div class="bkp-format-btn" data-format="md">
        <span class="bkp-icon">#</span>
        <span class="bkp-label">Markdown</span>
        <span class="bkp-sublabel">متن ساده و قابل ویرایش</span>
      </div>
      <div class="bkp-format-btn" data-format="pdf">
        <span class="bkp-icon">📄</span>
        <span class="bkp-label">PDF</span>
        <span class="bkp-sublabel">فایل خوانا برای پرینت</span>
      </div>
    </div>
    <button class="bkp-cancel" id="bkpCancel">انصراف</button>
  `;
  backdrop.appendChild(modal);
  document.documentElement.appendChild(backdrop);

  // ---------- progress bar ----------
  const progressWrap = document.createElement("div");
  progressWrap.className = "bkp-progress-wrap";
  progressWrap.innerHTML = `
    <div class="bkp-progress-text">در حال آماده‌سازی بکاپ...</div>
    <div class="bkp-progress-bar-outer"><div class="bkp-progress-bar-inner"></div></div>
    <div class="bkp-progress-detail"></div>
  `;
  document.documentElement.appendChild(progressWrap);

  const progressText = progressWrap.querySelector(".bkp-progress-text");
  const progressBar = progressWrap.querySelector(".bkp-progress-bar-inner");
  const progressDetail = progressWrap.querySelector(".bkp-progress-detail");

  function showProgress(text, percent, detail = "") {
    progressWrap.style.display = "block";
    progressText.textContent = text;
    progressBar.style.width = `${percent}%`;
    progressDetail.textContent = detail;
  }
  function hideProgress() {
    progressWrap.style.display = "none";
  }

  // ---------- convert image to base64 ----------
  function imgToBase64(img) {
    return new Promise((resolve) => {
      try {
        if (img.src.startsWith("data:")) {
          resolve(img.src);
          return;
        }

        const canvas = document.createElement("canvas");
        canvas.width = img.naturalWidth || img.width || 300;
        canvas.height = img.naturalHeight || img.height || 300;
        const ctx = canvas.getContext("2d");

        const tempImg = new Image();
        tempImg.crossOrigin = "anonymous";
        tempImg.onload = () => {
          try {
            canvas.width = tempImg.naturalWidth || tempImg.width;
            canvas.height = tempImg.naturalHeight || tempImg.height;
            ctx.drawImage(tempImg, 0, 0);
            resolve(canvas.toDataURL("image/png"));
          } catch (e) {
            try {
              ctx.drawImage(img, 0, 0);
              resolve(canvas.toDataURL("image/png"));
            } catch (e2) {
              resolve(img.src);
            }
          }
        };
        tempImg.onerror = () => {
          try {
            ctx.drawImage(img, 0, 0);
            resolve(canvas.toDataURL("image/png"));
          } catch (e) {
            resolve(img.src);
          }
        };
        tempImg.src = img.src;
      } catch (e) {
        resolve(img.src);
      }
    });
  }

  // ---------- extract images from a turn ----------
  function collectImages(turn) {
    const images = [];
    const seen = new Set();

    const imgEls = turn.querySelectorAll("img");
    imgEls.forEach((img) => {
      if (!img.src || seen.has(img.src)) return;

      const w = img.naturalWidth || img.width || 0;
      const h = img.naturalHeight || img.height || 0;
      if (w < 50 || h < 50) return;

      if (img.closest('[data-testid*="avatar"]')) return;
      if (img.alt && img.alt.toLowerCase().includes("avatar")) return;

      const btn = img.closest("button");
      if (btn && !btn.querySelector("img[src*='oaidalleapiprod'], img[src*='file'], img[src*='upload']")) return;
      if (img.closest('[role="button"]') && img.width < 100) return;

      seen.add(img.src);
      images.push({
        src: img.src,
        alt: img.alt || "",
        width: w,
        height: h,
        element: img,
      });
    });

    const bgEls = turn.querySelectorAll('[style*="background-image"], [class*="image"], [class*="thumbnail"], [class*="upload"], [class*="file"], [class*="preview"]');
    bgEls.forEach((el) => {
      const style = el.style?.backgroundImage || getComputedStyle(el).backgroundImage || "";
      const match = style.match(/url\(["']?(.*?)["']?\)/);
      if (match && match[1] && !seen.has(match[1])) {
        const url = match[1];
        if (url.startsWith("data:image/svg")) return; 
        const rect = el.getBoundingClientRect();
        if (rect.width < 50 || rect.height < 50) return;
        seen.add(url);

        const tempImg = new Image();
        tempImg.crossOrigin = "anonymous";
        tempImg.src = url;

        images.push({
          src: url,
          alt: el.getAttribute("aria-label") || el.getAttribute("title") || "",
          width: Math.round(rect.width),
          height: Math.round(rect.height),
          element: tempImg,
        });
      }
    });

    return images;
  }

  // ---------- extract conversation from DOM ----------
  async function extractConversation() {
    const messages = new Map();

    function collectVisible() {
      const turns = document.querySelectorAll('[data-testid^="conversation-turn-"]');
      turns.forEach((turn) => {
        const testId = turn.getAttribute("data-testid") || "";
        const indexMatch = testId.match(/conversation-turn-(\d+)/);
        if (!indexMatch) return;
        const turnIndex = parseInt(indexMatch[1]);
        if (messages.has(turnIndex)) return;

        const roleEl = turn.querySelector("[data-message-author-role]");
        let role = "unknown";
        if (roleEl) {
          role = roleEl.getAttribute("data-message-author-role") || "unknown";
        } else {
          role = turnIndex % 2 === 1 ? "user" : "assistant";
        }

        let text = "";
        const contentSelectors = [".markdown", ".prose", '[class*="markdown"]', ".whitespace-pre-wrap"];
        for (const selector of contentSelectors) {
          const contentEls = turn.querySelectorAll(selector);
          if (contentEls.length > 0) {
            text = Array.from(contentEls).map((el) => extractFormattedText(el)).join("\n\n");
            break;
          }
        }
        
        if (!text.trim()) {
          const messageArea = turn.querySelector('[data-message-author-role]');
          if (messageArea) {
            const clone = messageArea.cloneNode(true);
            clone.querySelectorAll('img, [class*="image"], [class*="thumbnail"], [class*="upload"], [class*="preview"], [class*="file-"]').forEach(el => el.remove());
            text = clone.innerText || "";
          }
        }
        
        if (!text.trim()) {
          const textParts = [];
          turn.querySelectorAll("p, span, div").forEach((el) => {
            if (el.children.length === 0 || el.matches("p, span")) {
              const t = el.innerText?.trim();
              if (t && t.length > 1 && !el.closest("button") && !el.closest('[role="button"]') && !el.closest('[class*="avatar"]')) {
                textParts.push(t);
              }
            }
          });
          if (textParts.length > 0) {
            const unique = [];
            for (const part of textParts) {
              if (!unique.some(u => u.includes(part) || part.includes(u))) {
                unique.push(part);
              } else {
                const idx = unique.findIndex(u => u.includes(part) || part.includes(u));
                if (idx !== -1 && part.length > unique[idx].length) {
                  unique[idx] = part;
                }
              }
            }
            text = unique.join("\n");
          }
        }

        const images = collectImages(turn);

        if (text.trim() || images.length > 0) {
          messages.set(turnIndex, { role, text: text.trim(), images });
        }
      });
    }

    function extractFormattedText(el) {
      let result = "";
      const codeBlocks = el.querySelectorAll("pre");
      if (codeBlocks.length > 0) {
        const clone = el.cloneNode(true);
        const cloneCodeBlocks = clone.querySelectorAll("pre");
        const codeTexts = [];
        cloneCodeBlocks.forEach((pre, i) => {
          const codeEl = pre.querySelector("code");
          const lang = codeEl ? (codeEl.className.match(/language-(\w+)/)?.[1] || "") : "";
          const codeText = codeEl ? codeEl.innerText : pre.innerText;
          codeTexts.push({ lang, text: codeText });
          pre.textContent = `__CODE_BLOCK_${i}__`;
        });
        result = clone.innerText;
        codeTexts.forEach((code, i) => {
          result = result.replace(`__CODE_BLOCK_${i}__`, `\n\`\`\`${code.lang}\n${code.text}\n\`\`\`\n`);
        });
      } else {
        result = el.innerText;
      }
      return result;
    }

    const scrollContainer = document.querySelector('[class*="react-scroll-to-bottom"]')
      || document.querySelector("main")
      || document.querySelector('[role="presentation"]');

    if (!scrollContainer) {
      showProgress("خطا: کانتینر چت پیدا نشد", 0);
      return null;
    }

    let scrollEl = scrollContainer;
    const innerScroll = scrollContainer.querySelector('[class*="react-scroll-to-bottom"]');
    if (innerScroll) scrollEl = innerScroll;
    const possibleScrollables = scrollEl.querySelectorAll("div");
    for (const div of possibleScrollables) {
      if (div.scrollHeight > div.clientHeight + 100) { scrollEl = div; break; }
    }

    showProgress("در حال اسکرول به ابتدای مکالمه...", 5);
    scrollEl.scrollTop = 0;
    await new Promise((r) => setTimeout(r, 800));
    collectVisible();

    const totalHeight = scrollEl.scrollHeight;
    const maxIterations = 2000;
    let lastScrollTop = -1;
    let stuckCount = 0;

    for (let i = 0; i < maxIterations; i++) {
      const scrollAmount = scrollEl.clientHeight * 0.8;
      scrollEl.scrollTop += scrollAmount;
      await new Promise((r) => setTimeout(r, 300));
      collectVisible();

      const scrollPercent = Math.min(95, Math.round((scrollEl.scrollTop / totalHeight) * 100));
      showProgress(
        "در حال خواندن پیام‌ها...",
        scrollPercent,
        `${messages.size} پیام پیدا شد`
      );

      if (Math.abs(scrollEl.scrollTop - lastScrollTop) < 5) {
        stuckCount++;
        if (stuckCount > 5) {
          scrollEl.scrollTop += 3000;
          await new Promise((r) => setTimeout(r, 500));
          collectVisible();
          if (Math.abs(scrollEl.scrollTop - lastScrollTop) < 5) break;
          stuckCount = 0;
        }
      } else {
        stuckCount = 0;
      }
      lastScrollTop = scrollEl.scrollTop;
    }

    collectVisible();
    showProgress("در حال ساخت فایل بکاپ...", 98, `${messages.size} پیام`);
    return messages;
  }

  // ---------- helper: role label ----------
  function getRoleLabel(role) {
    switch (role) {
      case "user": return "شما";
      case "assistant": return "هوش مصنوعی";
      case "system": return "سیستم";
      default: return "هوش مصنوعی";
    }
  }

  // ---------- escape HTML ----------
  function escapeHtml(text) {
    const div = document.createElement("div");
    div.textContent = text;
    return div.innerHTML;
  }

  // ---------- convert to Markdown ----------
  function convertToMarkdown(messages) {
    const now = new Date().toLocaleString("fa-IR", {
      year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit",
    });

    let md = "";
    md += `# بکاپ مکالمه - شیرگیفت\n\n`;
    md += `> تاریخ بکاپ: ${now}  \n`;
    md += `> تعداد پیام‌ها: ${messages.size}\n\n`;
    md += `---\n\n`;

    const sorted = Array.from(messages.entries()).sort((a, b) => a[0] - b[0]);
    let msgNumber = 0;

    for (const [, msg] of sorted) {
      if (msg.role === "unknown" && !msg.text.trim()) continue;
      msgNumber++;
      const roleLabel = getRoleLabel(msg.role);
      const emoji = msg.role === "user" ? "👤" : "🤖";

      md += `### ${emoji} ${roleLabel} (پیام ${msgNumber})\n\n`;
      md += `${msg.text}\n\n`;

      if (msg.images && msg.images.length > 0) {
        msg.images.forEach((img, i) => {
          const altText = img.alt || `تصویر ${i + 1}`;
          md += `![${altText}](${img.src})\n\n`;
        });
      }

      md += `---\n\n`;
    }

    md += `\n> قدرت گرفته از افزونه شیرگیفت 💙\n`;
    return md;
  }

  // ---------- convert to HTML ----------
  function convertToHTML(messages) {
    const now = new Date().toLocaleString("fa-IR", {
      year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit",
    });

    const sorted = Array.from(messages.entries()).sort((a, b) => a[0] - b[0]);

    let messagesHtml = "";
    let msgNumber = 0;

    for (const [, msg] of sorted) {
      if (msg.role === "unknown" && !msg.text.trim()) continue;
      msgNumber++;
      const roleLabel = getRoleLabel(msg.role);
      const isUser = msg.role === "user";
      const avatar = isUser ? "👤" : "🤖";

      let processedText = escapeHtml(msg.text);

      processedText = processedText.replace(
        /```(\w*)\n([\s\S]*?)```/g,
        (_, lang, code) => {
          const langLabel = lang ? `<span class="code-lang">${lang}</span>` : "";
          return `<div class="code-block">${langLabel}<pre><code>${code}</code></pre></div>`;
        }
      );

      processedText = processedText.replace(/`([^`]+)`/g, '<code class="inline-code">$1</code>');
      processedText = processedText.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
      processedText = processedText.replace(/\n/g, "<br>");

      let imagesHtml = "";
      if (msg.images && msg.images.length > 0) {
        imagesHtml = '<div class="message-images">';
        msg.images.forEach((img, i) => {
          const src = img.base64 || img.src;
          const alt = escapeHtml(img.alt || `تصویر ${i + 1}`);
          imagesHtml += `<div class="image-wrapper"><img src="${src}" alt="${alt}" loading="lazy"><div class="image-caption">${alt}</div></div>`;
        });
        imagesHtml += "</div>";
      }

      messagesHtml += `
        <div class="message ${isUser ? "message-user" : "message-assistant"}">
          <div class="message-header">
            <span class="avatar">${avatar}</span>
            <span class="role-name">${roleLabel}</span>
            <span class="msg-number">پیام ${msgNumber}</span>
          </div>
          <div class="message-body">${imagesHtml}${processedText}</div>
        </div>
      `;
    }

    return `<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>بکاپ چت - شیرگیفت</title>
  <style>
    @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;600;700;800&display=swap');

    * { margin: 0; padding: 0; box-sizing: border-box; }

    body {
      font-family: 'Vazirmatn', system-ui, -apple-system, sans-serif;
      background: #071227;
      color: #ffffff;
      line-height: 1.8;
      min-height: 100vh;
      -webkit-print-color-adjust: exact;
      print-color-adjust: exact;
    }

    .header {
      background: linear-gradient(135deg, rgba(13, 31, 67, 0.8) 0%, rgba(7, 18, 39, 1) 50%, rgba(13, 31, 67, 0.8) 100%);
      border-bottom: 1px solid rgba(175, 197, 232, 0.15);
      padding: 40px 20px;
      text-align: center;
      position: relative;
      overflow: hidden;
    }

    .header::before {
      content: '';
      position: absolute;
      top: -50%;
      left: -50%;
      width: 200%;
      height: 200%;
      background: radial-gradient(circle at 30% 50%, rgba(43, 120, 255, 0.08) 0%, transparent 50%),
                  radial-gradient(circle at 70% 50%, rgba(32, 223, 158, 0.05) 0%, transparent 50%);
      animation: headerGlow 8s ease-in-out infinite alternate;
    }

    .header-content { position: relative; z-index: 1; max-width: 700px; margin: 0 auto; }

    /* تغییر رنگ تایتل به شکلی که "بکاپ مکالمه -" و "گیفت" آبی باشند و "شیر" سفید بماند */
    .header h1 {
      font-size: 28px;
      font-weight: 800;
      color: #ffffff;
      margin-bottom: 12px;
    }
    .header h1 span {
      color: #2b78ff;
    }

    .header-meta {
      display: flex;
      gap: 24px;
      justify-content: center;
      flex-wrap: wrap;
    }

    .meta-item {
      font-size: 13px;
      color: #b7c8e2;
      display: flex;
      align-items: center;
      gap: 6px;
    }

    .meta-item .meta-icon {
      width: 24px;
      height: 24px;
      background: rgba(43, 120, 255, 0.15);
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      color: #2b78ff;
      font-size: 12px;
    }

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

    .message {
      margin-bottom: 20px;
      border-radius: 16px;
      overflow: hidden;
      border: 1px solid rgba(175, 197, 232, 0.15);
      background: rgba(255, 255, 255, 0.02);
      transition: transform .2s ease, box-shadow .2s ease;
    }

    .message:hover {
      transform: translateY(-2px);
      box-shadow: 0 8px 30px rgba(0,0,0,.3);
    }

    .message-user {
      background: rgba(43, 120, 255, 0.05);
      border-color: rgba(43, 120, 255, 0.15);
    }

    .message-assistant {
      background: rgba(32, 223, 158, 0.03);
      border-color: rgba(32, 223, 158, 0.15);
    }

    .message-header {
      padding: 14px 20px;
      display: flex;
      align-items: center;
      gap: 10px;
      border-bottom: 1px solid rgba(255,255,255,.05);
    }

    .message-user .message-header { background: rgba(43, 120, 255, 0.08); }
    .message-assistant .message-header { background: rgba(32, 223, 158, 0.05); }

    .avatar {
      font-size: 18px;
      width: 36px;
      height: 36px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 12px;
    }

    .message-user .avatar { background: rgba(43, 120, 255, 0.15); color: #2b78ff; }
    .message-assistant .avatar { background: rgba(32, 223, 158, 0.15); color: #20df9e; }

    .role-name {
      font-weight: 700;
      font-size: 14px;
    }

    .message-user .role-name { color: #2b78ff; }
    .message-assistant .role-name { color: #20df9e; }

    .msg-number {
      margin-right: auto;
      font-size: 11px;
      color: #b7c8e2;
      background: rgba(255,255,255,.05);
      padding: 3px 10px;
      border-radius: 20px;
    }

    .message-body {
      padding: 20px;
      font-size: 14px;
      line-height: 1.9;
      color: #e2e8f0;
      word-wrap: break-word;
    }

    .code-block {
      background: rgba(0,0,0,0.4);
      border: 1px solid rgba(255,255,255,0.08);
      border-radius: 12px;
      margin: 14px 0;
      overflow: hidden;
    }

    .code-lang {
      display: block;
      padding: 8px 14px;
      font-size: 11px;
      color: #b7c8e2;
      background: rgba(255,255,255,.05);
      border-bottom: 1px solid rgba(255,255,255,0.08);
      font-family: monospace;
      text-transform: uppercase;
      letter-spacing: 1px;
    }

    .code-block pre {
      padding: 16px;
      margin: 0;
      overflow-x: auto;
      direction: ltr;
      text-align: left;
    }

    .code-block code {
      font-family: 'Fira Code', 'JetBrains Mono', 'Cascadia Code', monospace;
      font-size: 13px;
      color: #9fc2f1;
      line-height: 1.6;
    }

    .inline-code {
      background: rgba(43, 120, 255, 0.15);
      color: #9fc2f1;
      padding: 2px 8px;
      border-radius: 6px;
      font-family: 'Fira Code', monospace;
      font-size: 13px;
    }

    strong { color: #fff; font-weight: 800; }

    .message-images {
      display: flex;
      flex-wrap: wrap;
      gap: 12px;
      margin-bottom: 16px;
    }

    .image-wrapper {
      border-radius: 12px;
      overflow: hidden;
      border: 1px solid rgba(255,255,255,0.1);
      background: #000;
      max-width: 100%;
      transition: transform .2s ease, box-shadow .2s ease;
    }

    .image-wrapper:hover {
      transform: scale(1.02);
      box-shadow: 0 8px 24px rgba(0,0,0,.4);
    }

    .image-wrapper img {
      max-width: 100%;
      max-height: 500px;
      object-fit: contain;
      display: block;
    }

    .image-caption {
      padding: 8px 12px;
      font-size: 11px;
      color: #b7c8e2;
      text-align: center;
      border-top: 1px solid rgba(255,255,255,0.1);
    }

    .footer {
      text-align: center;
      padding: 40px 20px;
      color: #b7c8e2;
      font-size: 12px;
      border-top: 1px solid rgba(175, 197, 232, 0.15);
    }

    @media (max-width: 600px) {
      .header { padding: 24px 16px; }
      .header h1 { font-size: 22px; }
      .container { padding: 16px 12px 40px; }
      .message-body { padding: 14px; font-size: 14px; }
    }

    /* تنظیمات اختصاصی برای تبدیل به PDF و پرینت */
    @media print {
      body { background: #ffffff !important; color: #000000 !important; }
      
      .header { background: none !important; border-bottom: 2px solid #e2e8f0 !important; padding: 20px 0 !important; }
      .header::before { display: none !important; }
      
      /* در پرینت کلمات درون span رنگ آبی و بقیه مشکی می‌شوند */
      .header h1 { color: #000000 !important; -webkit-text-fill-color: #000000 !important; }
      .header h1 span { color: #2b78ff !important; -webkit-text-fill-color: #2b78ff !important; }
      
      .meta-item { color: #475569 !important; }
      .meta-item .meta-icon { background: #f1f5f9 !important; color: #0f172a !important; }
      
      .message { background: #ffffff !important; border: 1px solid #cbd5e1 !important; box-shadow: none !important; page-break-inside: avoid; margin-bottom: 16px !important; }
      .message-user { background: #f0f9ff !important; border-color: #bae6fd !important; }
      .message-assistant { background: #f0fdf4 !important; border-color: #bbf7d0 !important; }
      
      .message-header { background: transparent !important; border-bottom: 1px solid #e2e8f0 !important; }
      .role-name { color: #0f172a !important; font-weight: 800 !important; }
      .msg-number { background: #f1f5f9 !important; color: #64748b !important; border: 1px solid #e2e8f0 !important; }
      
      .message-body { color: #1e293b !important; font-size: 13px !important; }
      strong { color: #000000 !important; font-weight: 800 !important; }
      
      .code-block { background: #f8fafc !important; border: 1px solid #cbd5e1 !important; }
      .code-lang { background: #e2e8f0 !important; color: #334155 !important; border-bottom: 1px solid #cbd5e1 !important; font-weight: 700 !important; }
      .code-block code { color: #0f172a !important; font-weight: 600 !important; }
      .inline-code { background: #e2e8f0 !important; color: #000000 !important; font-weight: 600 !important; }
      
      .image-wrapper { background: #ffffff !important; border: 1px solid #cbd5e1 !important; }
      .image-caption { color: #475569 !important; border-top: 1px solid #cbd5e1 !important; }
      
      .footer { color: #64748b !important; border-top: 1px solid #e2e8f0 !important; }
    }
  </style>
</head>
<body>
  <div class="header">
    <div class="header-content">
      <h1><span>بکاپ مکالمه - </span>شیر<span>گیفت</span></h1>
      <div class="header-meta">
        <div class="meta-item">
          <span class="meta-icon">📅</span>
          <span>${now}</span>
        </div>
        <div class="meta-item">
          <span class="meta-icon">💬</span>
          <span>${msgNumber} پیام</span>
        </div>
        <div class="meta-item">
          <span class="meta-icon">🔗</span>
          <span dir="ltr">${location.href}</span>
        </div>
      </div>
    </div>
  </div>

  <div class="container">
    ${messagesHtml}
  </div>

  <div class="footer">
    قدرت گرفته از افزونه شیرگیفت 💙
  </div>
</body>
</html>`;
  }

  // ---------- download file ----------
  function downloadFile(content, filename, mimeType) {
    const blob = new Blob([content], { type: mimeType });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = filename;
    a.style.display = "none";
    document.body.appendChild(a);
    a.click();
    setTimeout(() => { URL.revokeObjectURL(url); a.remove(); }, 1000);
  }

  // ---------- toast ----------
  function toast(msg, isError = false) {
    const t = document.createElement("div");
    t.textContent = msg;
    Object.assign(t.style, {
      position: "fixed", bottom: "16px", left: "50%", transform: "translateX(-50%)",
      background: isError ? "#f87171" : "#20df9e", color: "#000", padding: "12px 20px",
      borderRadius: "14px", boxShadow: "0 8px 24px rgba(0,0,0,.3)", zIndex: "2147483647",
      fontSize: "13px", fontFamily: "'Vazirmatn', inherit", fontWeight: "700", direction: "rtl",
    });
    document.documentElement.appendChild(t);
    setTimeout(() => t.remove(), 3000);
  }

  function refreshChatGPTSession() {
    try {
      chrome.runtime.sendMessage({ action: "refreshChatGPTSession" }, (res) => {
        if (chrome.runtime.lastError) {
          console.warn("ChatGPT session refresh failed:", chrome.runtime.lastError.message);
          return;
        }
        if (!res?.success) {
          console.warn("ChatGPT session refresh failed:", res?.error || "unknown error");
        }
      });
    } catch (error) {
      console.warn("ChatGPT session refresh failed:", error);
    }
  }

  // ---------- backup logic ----------
  async function startBackup(format) {
    backdrop.style.display = "none";
    btn.disabled = true;
    btn.textContent = "در حال بکاپ...";
    btn.style.opacity = "0.7";

    try {
      showProgress("شروع بکاپ‌گیری...", 2, "آماده‌سازی");

      const messages = await extractConversation();
      if (!messages || messages.size === 0) {
        hideProgress();
        toast("هیچ پیامی پیدا نشد!", true);
        return;
      }

      if (format === "html" || format === "pdf") {
        let totalImages = 0;
        let processedImages = 0;
        messages.forEach((msg) => { totalImages += (msg.images || []).length; });

        if (totalImages > 0) {
          showProgress("در حال پردازش تصاویر...", 96, `${totalImages} تصویر`);

          for (const [, msg] of messages) {
            if (!msg.images || msg.images.length === 0) continue;
            for (let i = 0; i < msg.images.length; i++) {
              const img = msg.images[i];
              try {
                img.base64 = await imgToBase64(img.element);
              } catch (e) {
                img.base64 = img.src; 
              }
              processedImages++;
              showProgress(
                "در حال پردازش تصاویر...",
                96 + Math.round((processedImages / totalImages) * 2),
                `${processedImages} از ${totalImages} تصویر`
              );
            }
          }
        }
      }

      showProgress("در حال ساخت فایل...", 99, `${messages.size} پیام`);

      const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);

      if (format === "md") {
        const md = convertToMarkdown(messages);
        downloadFile(md, `ShareGift-Backup-${timestamp}.md`, "text/markdown;charset=utf-8");
      } else if (format === "pdf") {
        const html = convertToHTML(messages);
        showProgress("در حال آماده‌سازی PDF...", 99, "صفحه پرینت باز می‌شود");

        await chrome.storage.local.set({
          pdfHTML: html,
          pdfTitle: `ShareGift-Backup-${timestamp}`
        });
        chrome.runtime.sendMessage({ action: "openPdfPrintPage" });
        hideProgress();
      } else {
        const html = convertToHTML(messages);
        downloadFile(html, `ShareGift-Backup-${timestamp}.html`, "text/html;charset=utf-8");
      }

      showProgress("بکاپ با موفقیت انجام شد!", 100, `${messages.size} پیام`);
      setTimeout(hideProgress, 2500);
      
      refreshChatGPTSession();
      
      toast(`بکاپ با موفقیت انجام شد! (${messages.size} پیام)`);
    } catch (err) {
      console.error("Backup error:", err);
      hideProgress();
      toast("خطا در بکاپ‌گیری: " + err.message, true);
    } finally {
      btn.disabled = false;
      btn.textContent = "بکاپ چت";
      btn.style.opacity = "1";
    }
  }

  // ---------- modal events ----------
  modal.querySelectorAll(".bkp-format-btn").forEach((b) => {
    b.addEventListener("click", () => startBackup(b.dataset.format));
  });
  document.getElementById("bkpCancel").addEventListener("click", () => {
    backdrop.style.display = "none";
  });
  backdrop.addEventListener("click", (e) => {
    if (e.target === backdrop) backdrop.style.display = "none";
  });

  // ---------- floating button (ShareGift Blue) ----------
  const btn = document.createElement("button");
  btn.textContent = "بکاپ چت";
  Object.assign(btn.style, {
    position: "fixed", zIndex: "2147483647", padding: "10px 18px",
    borderRadius: "20px", border: "none", fontWeight: "700", cursor: "grab",
    boxShadow: "0 6px 20px rgba(43, 120, 255, 0.3)", background: "#1fb063", color: "#fff",
    fontFamily: "'Vazirmatn', inherit", userSelect: "none", display: "none", fontSize: "13px",
  });
  applyPos(btn);

  // ---------- drag ----------
  let dragging = false, startX = 0, startY = 0, startRight = 0, startBottom = 0, moved = false;
  const onPointerDown = (e) => {
    dragging = true; moved = false; btn.style.cursor = "grabbing";
    const vw = window.innerWidth, vh = window.innerHeight;
    const rect = btn.getBoundingClientRect();
    startRight = vw - rect.right; startBottom = vh - rect.bottom;
    startX = e.clientX ?? (e.touches ? e.touches[0].clientX : 0);
    startY = e.clientY ?? (e.touches ? e.touches[0].clientY : 0);
    e.preventDefault();
  };
  const onPointerMove = (e) => {
    if (!dragging) return;
    const clientX = e.clientX ?? (e.touches ? e.touches[0].clientX : 0);
    const clientY = e.clientY ?? (e.touches ? e.touches[0].clientY : 0);
    const dx = clientX - startX, dy = clientY - startY;
    if (Math.abs(dx) + Math.abs(dy) > 2) moved = true;
    const vw = window.innerWidth, vh = window.innerHeight;
    const rect = btn.getBoundingClientRect();
    btn.style.right = `${clamp(startRight - dx, 8, vw - rect.width - 8)}px`;
    btn.style.bottom = `${clamp(startBottom - dy, 8, vh - rect.height - 8)}px`;
  };
  const onPointerUp = () => { if (!dragging) return; dragging = false; btn.style.cursor = "grab"; savePos(btn.style); };
  btn.addEventListener("mousedown", onPointerDown);
  btn.addEventListener("touchstart", onPointerDown, { passive: false });
  window.addEventListener("mousemove", onPointerMove, { passive: false });
  window.addEventListener("touchmove", onPointerMove, { passive: false });
  window.addEventListener("mouseup", onPointerUp);
  window.addEventListener("touchend", onPointerUp);

  // ---------- click: open format modal ----------
  btn.addEventListener("click", (e) => {
    if (moved) { e.preventDefault(); return; }
    backdrop.style.display = "flex";
  });

  // ---------- keep in viewport ----------
  window.addEventListener("resize", () => {
    const rect = btn.getBoundingClientRect();
    const vw = window.innerWidth, vh = window.innerHeight;
    btn.style.right = `${clamp(vw - rect.right, 8, vw - rect.width - 8)}px`;
    btn.style.bottom = `${clamp(vh - rect.bottom, 8, vh - rect.height - 8)}px`;
    savePos(btn.style);
  });

  // ---------- attach/detach ----------
  let attached = false;
  function attachBtn() { if (attached) return; document.documentElement.appendChild(btn); attached = true; syncByUrl(); }
  function detachBtn() { if (!attached) return; try { btn.remove(); } catch {} attached = false; }
  function syncByUrl() { if (!attached) return; btn.style.display = CHAT_RE.test(location.pathname) ? "block" : "none"; }

  function ensureBySetting() {
    chrome.storage.local.get({ showBackupButton: true }, (cfg) => {
      if (cfg.showBackupButton) { attachBtn(); syncByUrl(); } else { detachBtn(); }
    });
  }
  chrome.storage.onChanged.addListener((changes, area) => {
    if (area === "local" && changes.showBackupButton) {
      changes.showBackupButton.newValue ? (attachBtn(), syncByUrl()) : detachBtn();
    }
  });

  let lastHref = location.href;
  setInterval(() => { if (location.href !== lastHref) { lastHref = location.href; syncByUrl(); } }, 500);

  ensureBySetting();
})();