/*
 VariableHintPanel — Mevcut {değişken} adlarını gösteren ortak yardımcı panel.

 Kullanım:
   const inputRef = useRef(null);
   <VariableHintPanel
     context="qc_end"         // "ivr" | "qc_end"
     onInsert={(name) => insertAtCursor(inputRef.current, `{${name}}`)}
   />
   <textarea ref={inputRef} ... />

 Backend: GET /api/ws/variables?context=ivr|qc_end
   { reserved: [...], dynamic: [{name, source, default}] }

 - Rezerve değişkenler sabittir (kaynak kod tarafından).
 - Dinamik değişkenler tenant'ın trigger_on_call_start servislerinin
   response_mappings.variable alanlarının birleşimidir. Böylece çağrı başı
   servisten aldığın "sozlesme_no" bitiş webhook'u ayarlanırken görünür.
*/

/* global React, authFetch */
const VariableHintPanel = ({ context = "ivr", onInsert, compact = false }) => {
  const { useState, useEffect } = React;
  const [data, setData] = useState({ reserved: [], dynamic: [] });
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState("");
  const [open, setOpen] = useState(!compact);
  const [filter, setFilter] = useState("");

  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    setErr("");
    authFetch(`/api/ws/variables?context=${encodeURIComponent(context)}`)
      .then((r) => (r.ok ? r.json() : Promise.reject(r.statusText)))
      .then((d) => { if (!cancelled) setData({ reserved: d.reserved || [], dynamic: d.dynamic || [] }); })
      .catch((e) => { if (!cancelled) setErr(String(e || "Yüklenemedi")); })
      .finally(() => { if (!cancelled) setLoading(false); });
    return () => { cancelled = true; };
  }, [context]);

  const f = filter.trim().toLowerCase();
  const reservedShown = f ? data.reserved.filter((n) => n.toLowerCase().includes(f)) : data.reserved;
  const dynamicShown  = f ? data.dynamic.filter((v) => v.name.toLowerCase().includes(f)) : data.dynamic;

  const chipStyle = {
    display: "inline-flex", alignItems: "center", gap: 4,
    padding: "2px 8px", borderRadius: 6, fontSize: 11,
    fontFamily: "var(--mono, monospace)", cursor: "pointer",
    border: "1px solid var(--border)", background: "var(--surface)",
    userSelect: "none",
  };

  const doInsert = (name) => { if (onInsert) onInsert(name); };

  return (
    <div style={{
      padding: 10, border: "1px solid var(--border)", borderRadius: 8,
      background: "var(--surface2)", fontSize: 12,
    }}>
      <div
        style={{ display: "flex", alignItems: "center", gap: 8, cursor: compact ? "pointer" : "default" }}
        onClick={() => compact && setOpen((v) => !v)}
      >
        <span style={{ fontWeight: 700 }}>Mevcut değişkenler</span>
        <span style={{ fontSize: 11, color: "var(--text-dim)" }}>
          {context === "qc_end" ? "(çağrı sonu)" : "(IVR)"}
        </span>
        {compact && (
          <span style={{ marginLeft: "auto", color: "var(--text-dim)" }}>{open ? "▾" : "▸"}</span>
        )}
      </div>

      {open && (
        <div style={{ marginTop: 8, display: "flex", flexDirection: "column", gap: 8 }}>
          <input
            className="form-input"
            style={{ fontSize: 11, padding: "4px 8px" }}
            placeholder="Ara…"
            value={filter}
            onChange={(e) => setFilter(e.target.value)}
          />
          {loading && <div style={{ color: "var(--text-dim)" }}>Yükleniyor…</div>}
          {err && <div style={{ color: "var(--red)" }}>Hata: {err}</div>}

          {!loading && !err && (
            <>
              <div>
                <div style={{ fontSize: 10, color: "var(--text-dim)", marginBottom: 4, textTransform: "uppercase", letterSpacing: 0.5 }}>
                  Sabit ({reservedShown.length})
                </div>
                <div style={{ display: "flex", flexWrap: "wrap", gap: 4 }}>
                  {reservedShown.length === 0 && (
                    <span style={{ fontSize: 11, color: "var(--text-dim)" }}>—</span>
                  )}
                  {reservedShown.map((name) => (
                    <span
                      key={`r-${name}`}
                      style={chipStyle}
                      onClick={() => doInsert(name)}
                      title={`{${name}} ekle`}
                    >
                      {"{" + name + "}"}
                    </span>
                  ))}
                </div>
              </div>

              <div>
                <div style={{ fontSize: 10, color: "var(--text-dim)", marginBottom: 4, textTransform: "uppercase", letterSpacing: 0.5 }}>
                  Dinamik — çağrı başı WS yanıtları ({dynamicShown.length})
                </div>
                {dynamicShown.length === 0 ? (
                  <div style={{ fontSize: 11, color: "var(--text-dim)" }}>
                    Bu tenant'ta çağrı başı servisi yok veya response_mapping tanımlı değil.
                  </div>
                ) : (
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 4 }}>
                    {dynamicShown.map((v) => (
                      <span
                        key={`d-${v.name}`}
                        style={{ ...chipStyle, borderColor: "var(--blue)" }}
                        onClick={() => doInsert(v.name)}
                        title={`${v.source} — {${v.name}} ekle`}
                      >
                        {"{" + v.name + "}"}
                      </span>
                    ))}
                  </div>
                )}
              </div>

              <div style={{ fontSize: 10, color: "var(--text-dim)", lineHeight: 1.4 }}>
                Bir değişkene tıkla → imleç konumuna <code>{"{ad}"}</code> olarak eklenir.
              </div>
            </>
          )}
        </div>
      )}
    </div>
  );
};

const insertAtCursor = (el, text) => {
  if (!el || typeof el.selectionStart !== "number") return;
  const start = el.selectionStart;
  const end   = el.selectionEnd;
  const cur   = el.value || "";
  const next  = cur.slice(0, start) + text + cur.slice(end);
  // React controlled component için native setter ile tetikle
  const setter = Object.getOwnPropertyDescriptor(
    el.tagName === "TEXTAREA" ? window.HTMLTextAreaElement.prototype : window.HTMLInputElement.prototype,
    "value"
  )?.set;
  if (setter) setter.call(el, next); else el.value = next;
  el.dispatchEvent(new Event("input", { bubbles: true }));
  const pos = start + text.length;
  requestAnimationFrame(() => {
    try { el.setSelectionRange(pos, pos); el.focus(); } catch (_) {}
  });
};

window.VariableHintPanel = VariableHintPanel;
window.insertAtCursor = insertAtCursor;
