/* global React */

// ===== Bug reports store =====
const BUGS_KEY = "mayster-bug-reports-v1";

const _ico = (d, extra) => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">{extra}<path d={d}/></svg>;

const BUG_CATEGORIES = [
  // Zła odpowiedź AI: mowa dymek
  { id: "ai", label: "Zła odpowiedź AI", icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><circle cx="9" cy="10" r="0.8" fill="currentColor"/><circle cx="12" cy="10" r="0.8" fill="currentColor"/><circle cx="15" cy="10" r="0.8" fill="currentColor"/></svg> },
  // Błąd w diagramie: kwadrat z przekątnymi (schemat)
  { id: "diagram", label: "Błąd w diagramie", icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 3v18"/></svg> },
  // Błędne dane części: klucz nasadowy
  { id: "part", label: "Błędne dane części", icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="3"/><path d="M12 2v4M12 18v4M4.9 4.9l2.8 2.8M16.3 16.3l2.8 2.8M2 12h4M18 12h4M4.9 19.1l2.8-2.8M16.3 7.7l2.8-2.8"/></svg> },
  // Problem z interfejsem: monitor
  { id: "ui", label: "Problem z interfejsem", icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/></svg> },
  // Wydajność: stoper
  { id: "performance", label: "Wydajność / wolne działanie", icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="13" r="8"/><path d="M12 9v4l2 2M9 2h6M12 5V3"/></svg> },
  // Sugestia / żarówka
  { id: "feature", label: "Sugestia / brakująca funkcja", icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M9 18h6M10 22h4M12 2a7 7 0 0 0-4 12.7c.6.5 1 1.2 1 2V17h6v-.3c0-.8.4-1.5 1-2A7 7 0 0 0 12 2z"/></svg> },
  // Inne: trzy kropki
  { id: "other", label: "Inne", icon: <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="1.2" fill="currentColor"/><circle cx="19" cy="12" r="1.2" fill="currentColor"/><circle cx="5" cy="12" r="1.2" fill="currentColor"/></svg> },
];

const BUG_PRIORITIES = [
  { id: "low", label: "Niski — drobiazg" },
  { id: "normal", label: "Normalny" },
  { id: "high", label: "Wysoki — blokuje pracę" },
];

function loadBugs() {
  try {
    const stored = JSON.parse(localStorage.getItem(BUGS_KEY) || "null");
    if (stored) return stored;
    return SEED_BUGS;
  } catch (e) { return SEED_BUGS; }
}
function saveBugs(list) {
  try { localStorage.setItem(BUGS_KEY, JSON.stringify(list)); } catch (e) {}
  window.dispatchEvent(new CustomEvent("mayster-bugs-changed"));
}

// Seed so user sees history immediately
const SEED_BUGS = [
  {
    id: "BUG-0142",
    title: "Czasem brakuje numeru diagramu przy częściach z D-35",
    category: "part",
    priority: "normal",
    status: "in_progress",
    description: "Dla niektórych części z diagramu D-35 (instalacja elektryczna) w wynikach chatu nie pojawia się etykieta diagramu — trzeba ręcznie wyszukiwać. Widziałem to przy akumulatorze i prądnicy.",
    context: { tab: "chat", machine: "Komatsu PC210LC-8K" },
    createdAt: Date.now() - 86400000 * 3 - 3600000 * 2,
    updatedAt: Date.now() - 86400000 * 1,
    responses: [
      { from: "support", author: "Support Mayster", text: "Dzięki za zgłoszenie — potwierdzamy, dotyczy też diagramu D-32. Pracujemy nad poprawką, planowany termin: ten tydzień.", time: Date.now() - 86400000 * 1 }
    ],
  },
  {
    id: "BUG-0137",
    title: "Sugestia: wyszukiwanie po numerze OEM konkurenta",
    category: "feature",
    priority: "low",
    status: "backlog",
    description: "Fajnie byłoby wpisać numer Volvo i dostać polecone odpowiedniki Komatsu. Klienci czasem podają numer z innej maszyny.",
    context: { tab: "chat", machine: "Komatsu PC210LC-8K" },
    createdAt: Date.now() - 86400000 * 8,
    updatedAt: Date.now() - 86400000 * 6,
    responses: [
      { from: "support", author: "Support Mayster", text: "Zgadzamy się, ciekawy pomysł. Dodaliśmy do backlogu — ocenimy w następnym sprincie.", time: Date.now() - 86400000 * 6 }
    ],
  },
  {
    id: "BUG-0121",
    title: "Dark mode — słaby kontrast w karcie części",
    category: "ui",
    priority: "low",
    status: "resolved",
    description: "W trybie ciemnym numer katalogowy jest trudny do odczytania — za ciemny.",
    context: { tab: "chat", machine: "Komatsu PC210LC-8K" },
    createdAt: Date.now() - 86400000 * 14,
    updatedAt: Date.now() - 86400000 * 10,
    responses: [
      { from: "support", author: "Support Mayster", text: "Poprawione w wersji z 12.03 — daj znać czy teraz OK.", time: Date.now() - 86400000 * 11 },
      { from: "user", author: "Jakub K.", text: "Teraz super, dzięki.", time: Date.now() - 86400000 * 10 }
    ],
  },
];

const STATUS_META = {
  new:         { label: "Nowe",       cls: "status-new" },
  in_progress: { label: "W toku",     cls: "status-progress" },
  backlog:     { label: "W backlogu", cls: "status-backlog" },
  resolved:    { label: "Rozwiązane", cls: "status-resolved" },
  closed:      { label: "Zamknięte",  cls: "status-closed" },
};

// ===== Bug Report Modal =====
const BUG_DRAFT_KEY = "glimat-bug-report-draft";
function loadBugDraft() {
  try { return JSON.parse(localStorage.getItem(BUG_DRAFT_KEY) || "null"); } catch { return null; }
}
function saveBugDraft(d) {
  try { localStorage.setItem(BUG_DRAFT_KEY, JSON.stringify(d)); } catch {}
}
function clearBugDraft() {
  try { localStorage.removeItem(BUG_DRAFT_KEY); } catch {}
}

function BugReportModal({ initial, onClose }) {
  const draft = !initial?.aiMessage ? loadBugDraft() : null;
  const [category, setCategory] = React.useState(initial?.category || draft?.category || "ui");
  const [priority, setPriority] = React.useState(initial?.priority || draft?.priority || "normal");
  const [title, setTitle] = React.useState(initial?.title || draft?.title || "");
  const [description, setDescription] = React.useState(initial?.description || draft?.description || "");
  const [submitted, setSubmitted] = React.useState(false);
  const [bugId, setBugId] = React.useState(null);
  const [attachments, setAttachments] = React.useState(initial?.attachments || draft?.attachments || []);
  const fileInputRef = React.useRef(null);

  const onPickFiles = (e) => {
    const files = Array.from(e.target.files || []);
    if (!files.length) return;
    files.forEach((f) => {
      if (!f.type.startsWith("image/")) return;
      if (f.size > 5 * 1024 * 1024) return; // 5MB cap
      const reader = new FileReader();
      reader.onload = (ev) => {
        setAttachments((prev) => [...prev, { name: f.name, size: f.size, type: f.type, dataUrl: ev.target.result }]);
      };
      reader.readAsDataURL(f);
    });
    e.target.value = "";
  };
  const removeAttachment = (i) => setAttachments((prev) => prev.filter((_, idx) => idx !== i));
  const onPaste = (e) => {
    const items = Array.from(e.clipboardData?.items || []);
    const imgs = items.filter((it) => it.type.startsWith("image/"));
    if (!imgs.length) return;
    imgs.forEach((it) => {
      const f = it.getAsFile();
      if (!f) return;
      const reader = new FileReader();
      reader.onload = (ev) => {
        setAttachments((prev) => [...prev, { name: f.name || "zrzut.png", size: f.size, type: f.type, dataUrl: ev.target.result }]);
      };
      reader.readAsDataURL(f);
    });
  };

  // Persist draft on every change (only for generic reports, not AI-message-tied ones)
  React.useEffect(() => {
    if (initial?.aiMessage) return;
    if (submitted) return;
    if (!description.trim() && !title.trim() && category === "ui" && priority === "normal") {
      clearBugDraft();
      return;
    }
    saveBugDraft({ category, priority, title, description, attachments });
  }, [category, priority, title, description, attachments, submitted, initial]);

  // Context attached to the ticket. Read DYNAMICALLY from localStorage
  // (machine label + active tab) — the previous version hard-coded
  // "Komatsu PC210LC-8K" so every handlowiec submission claimed to be about
  // that machine, even when they were on Profile / Browser or on a different
  // machine in chat. Now: read whatever the user actually has selected; if
  // there's nothing concrete, render no context chip at all.
  const onAppSurface = typeof window !== "undefined" && window.location.pathname.startsWith("/app");
  const currentContext = (() => {
    if (initial?.context) return initial.context;
    if (!onAppSurface) return null;
    const tab = (typeof window !== "undefined" && (localStorage.getItem("mayster-active-tab") || localStorage.getItem("glimat-tab"))) || null;
    const machine = (typeof window !== "undefined" && localStorage.getItem("mayster-machine-label")) || null;
    if (!tab && !machine) return null;
    return { tab, machine };
  })();

  // Map widget category ids → backend ticket enum
  const CATEGORY_TO_API = {
    ai: "bad_ai_answer",
    diagram: "diagram_error",
    part: "wrong_part_data",
    ui: "ui_problem",
    performance: "performance",
    feature: "suggestion",
    other: "other",
  };

  const submit = () => {
    if (!description.trim()) return;
    // Auto-derive a title from the first line of description (first 80 chars)
    const autoTitle = description.trim().split(/\n/)[0].slice(0, 80).trim() || "Bez tytułu";
    const list = loadBugs();
    const nextNum = Math.max(142, ...list.map((b) => parseInt(b.id.replace("BUG-", ""), 10) || 0)) + 1;
    const finalTitle = (initial?.title && initial.title.trim()) || autoTitle;
    const newBug = {
      id: "BUG-" + String(nextNum).padStart(4, "0"),
      title: finalTitle,
      category,
      priority,
      status: "new",
      description: description.trim(),
      context: currentContext,
      aiMessage: initial?.aiMessage,
      attachments,
      createdAt: Date.now(),
      updatedAt: Date.now(),
      responses: [],
    };
    const next = [newBug, ...list];
    saveBugs(next);
    clearBugDraft();

    // Post to backend so the ticket lands in tenant_admin / superadmin Zgłoszenia.
    // localStorage entry stays as user's personal cache regardless of API result.
    // Screenshots <= 5 sent inline as data URLs (cap mirrors backend zod
    // schema; if a user attaches more, only the first 5 go to the server —
    // local cache keeps everything for the user's own profile view).
    const payloadShots = (attachments || []).slice(0, 5).map((a) => ({
      name: a.name || "zrzut.png",
      type: a.type || "image/png",
      dataUrl: a.dataUrl,
    }));
    const techContext = {
      url: typeof window !== "undefined" ? window.location.pathname : undefined,
      userAgent: typeof navigator !== "undefined" ? navigator.userAgent.slice(0, 480) : undefined,
      viewport:
        typeof window !== "undefined"
          ? `${window.innerWidth}×${window.innerHeight}`
          : undefined,
      machine: currentContext?.machine,
    };
    // Link the active conversation (chat tab) so admin's TicketDetailView
    // can inline-render the rozmowa-poprzedzająca-zgłoszenie + jump from
    // ticket → conversation. Skip when there's no active conv or when the
    // reporter is on admin (no chat session in flight).
    const activeConv =
      typeof localStorage !== "undefined" ? localStorage.getItem("mayster-active-conv") : null;
    fetch("/api/tickets", {
      method: "POST",
      credentials: "include",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        category: CATEGORY_TO_API[category] || "other",
        title: finalTitle,
        description: description.trim(),
        priority,
        screenshots: payloadShots,
        techContext,
        ...(activeConv ? { conversationId: activeConv } : {}),
      }),
    }).catch(() => { /* offline / unauth — local copy is enough */ });

    setBugId(newBug.id);
    setSubmitted(true);
  };

  const cancel = () => {
    clearBugDraft();
    onClose();
  };

  if (submitted) {
    return (
      <div className="bug-modal-overlay" onClick={onClose}>
        <div className="bug-modal bug-modal-success" onClick={(e) => e.stopPropagation()}>
          <div className="bug-success-ico">
            <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6 9 17l-5-5"/></svg>
          </div>
          <h2>Zgłoszenie wysłane</h2>
          <p>Twoje zgłoszenie <b>{bugId}</b> trafiło do zespołu Mayster. Zobaczysz je w sekcji <b>Moje zgłoszenia</b> w profilu — tam dostaniesz też odpowiedź.</p>
          <div className="bug-modal-actions">
            <button className="iconbtn primary" onClick={onClose}>Wróć do pracy</button>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="bug-modal-overlay" onClick={onClose}>
      <div className="bug-modal" onClick={(e) => e.stopPropagation()} onPaste={onPaste}>
        <div className="bug-modal-head">
          <div>
            <div className="bug-modal-eyebrow">Zgłoś problem</div>
            <h2>Co poszło nie tak?</h2>
          </div>
          <button className="bug-modal-close" onClick={onClose} aria-label="Zamknij">
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
          </button>
        </div>

        <div className="bug-modal-body">
          <div className="bug-field">
            <label>Kategoria</label>
            <div className="bug-cat-grid">
              {BUG_CATEGORIES.map((c) => (
                <button key={c.id} className={`bug-cat ${category === c.id ? "active" : ""}`} onClick={() => setCategory(c.id)}>
                  <span className="bug-cat-ico">{c.icon}</span>
                  <span>{c.label}</span>
                </button>
              ))}
            </div>
          </div>

          <div className="bug-field">
            <label htmlFor="bug-desc">Opis problemu</label>
            <textarea id="bug-desc" className="bug-textarea" placeholder={initial?.aiMessage ? "Co w tej odpowiedzi było nie tak? Co powinno być zamiast tego?" : "Co się stało? Co powinno się stać? Jak to odtworzyć?"} value={description} onChange={(e) => setDescription(e.target.value)} rows={5} autoFocus />
          </div>

          {initial?.aiMessage && (
            <div className="bug-ai-ref">
              <div className="bug-ai-ref-label">🤖 Odpowiedź AI której dotyczy zgłoszenie</div>
              <div className="bug-ai-ref-text">{initial.aiMessage.slice(0, 220)}{initial.aiMessage.length > 220 ? "…" : ""}</div>
            </div>
          )}

          <div className="bug-field">
            <label>Priorytet</label>
            <div className="bug-prio-row">
              {BUG_PRIORITIES.map((p) => (
                <button key={p.id} className={`bug-prio bug-prio-${p.id} ${priority === p.id ? "active" : ""}`} onClick={() => setPriority(p.id)}>
                  {p.label}
                </button>
              ))}
            </div>
          </div>

          <div className="bug-field">
            <label>Załączniki <span style={{color:"var(--text-2)", fontWeight:400}}>(opcjonalne — screenshoty)</span></label>
            <div className="bug-attach-row">
              <button type="button" className="bug-attach-btn" onClick={() => fileInputRef.current?.click()}>
                <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-5-5L5 21"/></svg>
                <span>Dodaj obraz</span>
              </button>
              <input ref={fileInputRef} type="file" accept="image/*" multiple style={{display:"none"}} onChange={onPickFiles} />
              <span className="bug-attach-hint">lub wklej zrzut (Ctrl+V)</span>
            </div>
            {attachments.length > 0 && (
              <div className="bug-attach-grid">
                {attachments.map((a, i) => (
                  <div key={i} className="bug-attach-thumb">
                    <img src={a.dataUrl} alt={a.name} />
                    <button type="button" className="bug-attach-remove" onClick={() => removeAttachment(i)} aria-label="Usuń">
                      <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                    </button>
                    <div className="bug-attach-name">{a.name}</div>
                  </div>
                ))}
              </div>
            )}
          </div>

          {currentContext && (currentContext.machine || currentContext.tab) && (
            <div className="bug-field bug-attach">
              <div className="bug-context-chip">
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18"/></svg>
                <span>
                  Kontekst dołączony:
                  {currentContext.machine && <> <b>{currentContext.machine}</b></>}
                  {currentContext.machine && currentContext.tab && " · "}
                  {currentContext.tab && <>zakładka <b>{currentContext.tab}</b></>}
                </span>
              </div>
            </div>
          )}
        </div>

        <div className="bug-modal-foot">
          <div className="bug-modal-actions" style={{marginLeft:"auto"}}>
            <button className="iconbtn" onClick={cancel}>Anuluj</button>
            <button className="iconbtn primary" disabled={!description.trim()} onClick={submit}>Wyślij zgłoszenie</button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ===== FAB (floating action button) shown app-wide =====
function BugFab() {
  const [open, setOpen] = React.useState(false);
  const handleOpen = () => {
    setOpen(true);
    // Rain that only collides with the popup + FAB, not the whole app underneath.
    // Wait for the modal to actually render before spawning so logos hit it.
    if (window.__maysterLogoRain) {
      window.__maysterLogoRain.trigger({
        sources: "parts",
        collideWith: [".bug-modal", ".bug-fab"],
        waitFor: ".bug-modal",
      });
    }
  };
  const handleClose = () => {
    if (window.__maysterLogoRain) window.__maysterLogoRain.clear();
    setOpen(false);
  };
  return (
    <>
      <button className="bug-fab" onClick={handleOpen} title="Zgłoś problem">
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="m8 2 1.88 1.88"/><path d="M14.12 3.88 16 2"/><path d="M9 7.13v-1a3.003 3.003 0 1 1 6 0v1"/><path d="M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6"/><path d="M12 20v-9"/><path d="M6.53 9C4.6 8.8 3 7.1 3 5"/><path d="M6 13H2"/><path d="M3 21c0-2.1 1.7-3.9 3.8-4"/><path d="M20.97 5c0 2.1-1.6 3.8-3.5 4"/><path d="M22 13h-4"/><path d="M17.2 17c2.1.1 3.8 1.9 3.8 4"/>
        </svg>
        <span>Zgłoś problem</span>
      </button>
      {open && <BugReportModal onClose={handleClose} />}
    </>
  );
}

// ===== Thumbs down button for Chat messages =====
function ChatFeedback({ aiMessage }) {
  const [thumbsDown, setThumbsDown] = React.useState(false);
  const [modalOpen, setModalOpen] = React.useState(false);

  const handleDown = () => {
    setThumbsDown(true);
    setModalOpen(true);
  };

  return (
    <>
      <div className="chat-feedback">
        <button className="chat-fb-btn" title="Przydatne">
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M7 10v12"/><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H7l-4-4V10a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"/></svg>
        </button>
        <button className={`chat-fb-btn ${thumbsDown ? "active" : ""}`} onClick={handleDown} title="Zgłoś problem z odpowiedzią">
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M17 14V2"/><path d="M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H17l4 4v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z"/></svg>
        </button>
      </div>
      {modalOpen && (
        <BugReportModal
          initial={{
            category: "ai",
            title: "Problem z odpowiedzią AI",
            description: "",
            aiMessage: aiMessage,
            context: { tab: "chat", machine: "Komatsu PC210LC-8K" },
          }}
          onClose={() => setModalOpen(false)}
        />
      )}
    </>
  );
}

// ===== My Reports (inside Profile) =====
function MyReports() {
  const [bugs, setBugs] = React.useState(() => loadBugs());
  const [selectedId, setSelectedId] = React.useState(null);
  const [filter, setFilter] = React.useState("open");

  React.useEffect(() => {
    const handler = () => setBugs(loadBugs());
    window.addEventListener("mayster-bugs-changed", handler);
    return () => window.removeEventListener("mayster-bugs-changed", handler);
  }, []);

  const filtered = bugs.filter((b) => {
    if (filter === "open") return b.status !== "resolved" && b.status !== "closed";
    if (filter === "resolved") return b.status === "resolved" || b.status === "closed";
    return true;
  });

  const selected = bugs.find((b) => b.id === selectedId);
  const openCount = bugs.filter((b) => b.status !== "resolved" && b.status !== "closed").length;

  return (
    <div className="my-reports">
      <div className="my-reports-layout">
        <div className="my-reports-list">
          <div className="my-reports-filters">
            <button className={`mr-filter ${filter === "open" ? "active" : ""}`} onClick={() => setFilter("open")}>
              Otwarte <span className="mr-count">{openCount}</span>
            </button>
            <button className={`mr-filter ${filter === "resolved" ? "active" : ""}`} onClick={() => setFilter("resolved")}>
              Zamknięte <span className="mr-count">{bugs.length - openCount}</span>
            </button>
          </div>

          {filtered.length === 0 ? (
            <div className="mr-empty">Brak zgłoszeń w tej kategorii</div>
          ) : filtered.map((b) => {
            const cat = BUG_CATEGORIES.find((c) => c.id === b.category);
            const st = STATUS_META[b.status];
            const hasUnread = b.responses.some((r) => r.from === "support" && r.time > (b.lastSeen || 0));
            return (
              <button key={b.id} className={`mr-item ${selectedId === b.id ? "active" : ""}`} onClick={() => setSelectedId(b.id)}>
                <div className="mr-item-head">
                  <span className="mr-item-id">{b.id}</span>
                  <span className={`mr-status ${st.cls}`}>{st.label}</span>
                </div>
                <div className="mr-item-title">{b.title}</div>
                <div className="mr-item-meta">
                  <span>{cat?.icon} {cat?.label}</span>
                  <span>·</span>
                  <span>{formatDate(b.updatedAt)}</span>
                  {b.responses.length > 0 && (
                    <>
                      <span>·</span>
                      <span className={hasUnread ? "mr-unread" : ""}>
                        <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
                        {b.responses.length}
                      </span>
                    </>
                  )}
                </div>
              </button>
            );
          })}
        </div>

        <div className="my-reports-detail">
          {selected ? <BugDetail bug={selected} /> : (
            <div className="mr-detail-empty">
              <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="m8 2 1.88 1.88"/><path d="M14.12 3.88 16 2"/><path d="M9 7.13v-1a3.003 3.003 0 1 1 6 0v1"/><path d="M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6"/></svg>
              <h3>Wybierz zgłoszenie</h3>
              <p>Kliknij na liście po lewej, żeby zobaczyć szczegóły, odpowiedzi Supportu i historię.</p>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

function BugDetail({ bug }) {
  const cat = BUG_CATEGORIES.find((c) => c.id === bug.category);
  const st = STATUS_META[bug.status];
  const prio = BUG_PRIORITIES.find((p) => p.id === bug.priority);
  const [reply, setReply] = React.useState("");

  const sendReply = () => {
    if (!reply.trim()) return;
    const list = loadBugs();
    const updated = list.map((b) => b.id === bug.id ? {
      ...b,
      responses: [...b.responses, { from: "user", author: "Jakub K.", text: reply.trim(), time: Date.now() }],
      updatedAt: Date.now(),
    } : b);
    saveBugs(updated);
    setReply("");
  };

  return (
    <div className="bug-detail">
      <div className="bug-detail-head">
        <div>
          <div className="bug-detail-id">{bug.id}</div>
          <h2>{bug.title}</h2>
        </div>
        <span className={`mr-status ${st.cls} lg`}>{st.label}</span>
      </div>

      <div className="bug-detail-meta">
        <div className="bd-meta-item"><span>Kategoria</span><b>{cat?.icon} {cat?.label}</b></div>
        <div className="bd-meta-item"><span>Priorytet</span><b className={`bd-prio bd-prio-${bug.priority}`}>{prio?.label.split(" — ")[0]}</b></div>
        <div className="bd-meta-item"><span>Utworzono</span><b>{formatDateTime(bug.createdAt)}</b></div>
        <div className="bd-meta-item"><span>Aktualizacja</span><b>{formatDateTime(bug.updatedAt)}</b></div>
      </div>

      <div className="bug-detail-section">
        <div className="bd-section-label">Opis</div>
        <div className="bd-description">{bug.description}</div>
      </div>

      {bug.attachments && bug.attachments.length > 0 && (
        <div className="bug-detail-section">
          <div className="bd-section-label">Załączniki ({bug.attachments.length})</div>
          <div className="bd-attachments">
            {bug.attachments.map((a, i) => (
              <a key={i} href={a.dataUrl} target="_blank" rel="noopener noreferrer" className="bd-attach-thumb" title={a.name}>
                <img src={a.dataUrl} alt={a.name} />
              </a>
            ))}
          </div>
        </div>
      )}

      {bug.context && bug.context.machine && (
        <div className="bug-detail-section">
          <div className="bd-section-label">Kontekst</div>
          <div className="bd-context">
            <span className="bd-ctx-chip">🚜 {bug.context.machine}</span>
            <span className="bd-ctx-chip">📍 zakładka: {bug.context.tab}</span>
            {bug.hasScreenshot && <span className="bd-ctx-chip">📷 zrzut ekranu dołączony</span>}
          </div>
        </div>
      )}

      {bug.aiMessage && (
        <div className="bug-detail-section">
          <div className="bd-section-label">Odpowiedź AI której dotyczy zgłoszenie</div>
          <div className="bd-ai-quote">{bug.aiMessage}</div>
        </div>
      )}

      <div className="bug-detail-section">
        <div className="bd-section-label">Konwersacja ({bug.responses.length})</div>
        {bug.responses.length === 0 ? (
          <div className="bd-empty-thread">Czekamy na odpowiedź Supportu — zwykle do 1 dnia roboczego.</div>
        ) : (
          <div className="bd-thread">
            {bug.responses.map((r, i) => (
              <div key={i} className={`bd-msg bd-msg-${r.from}`}>
                <div className="bd-msg-ava">{r.from === "support" ? "M" : "JK"}</div>
                <div className="bd-msg-body">
                  <div className="bd-msg-who">{r.author} <span>· {formatDateTime(r.time)}</span></div>
                  <div className="bd-msg-text">{r.text}</div>
                </div>
              </div>
            ))}
          </div>
        )}

        {bug.status !== "resolved" && bug.status !== "closed" && (
          <div className="bd-reply">
            <textarea placeholder="Dodaj odpowiedź lub uzupełnij opis…" value={reply} onChange={(e) => setReply(e.target.value)} rows={2}/>
            <button className="iconbtn primary" disabled={!reply.trim()} onClick={sendReply}>Wyślij</button>
          </div>
        )}
      </div>
    </div>
  );
}

function formatDate(ts) {
  const d = new Date(ts);
  const today = new Date();
  const diff = Math.floor((today - d) / 86400000);
  if (diff === 0) return "dziś";
  if (diff === 1) return "wczoraj";
  if (diff < 7) return `${diff} dni temu`;
  return d.toLocaleDateString("pl-PL", { day: "2-digit", month: "short" });
}
function formatDateTime(ts) {
  const d = new Date(ts);
  return d.toLocaleDateString("pl-PL", { day: "2-digit", month: "short" }) + " · " + d.toTimeString().slice(0, 5);
}

window.BugFab = BugFab;
window.ChatFeedback = ChatFeedback;
window.MyReports = MyReports;
window.loadBugs = loadBugs;
