/* job-match.jsx — job description keyword analyzer */

var JM_STOP = {};
"a an and are as at be by do does did for from has have he her him his how i if in into is it its me my no not of on or our she so than that the their them then they this to up us was we were what when who will with you your been being also both but can even just like may more most much only other over re same see should since some such there these those through under very was well were which while".split(" ").forEach(function(w) { JM_STOP[w] = true; });

function jmTokenize(text) {
  return (text || "").toLowerCase().match(/[a-z][a-z0-9+#./\-]*/g) || [];
}

function jmExtractKeywords(text) {
  var words = jmTokenize(text);
  var freq = {};
  words.forEach(function(w) {
    if (w.length > 2 && !JM_STOP[w]) freq[w] = (freq[w] || 0) + 1;
  });
  // Bigrams for multi-word phrases
  for (var i = 0; i < words.length - 1; i++) {
    var a = words[i], b = words[i + 1];
    if (a.length > 2 && b.length > 2 && !JM_STOP[a] && !JM_STOP[b]) {
      var bi = a + " " + b;
      freq[bi] = (freq[bi] || 0) + 0.5;
    }
  }
  return Object.entries(freq).sort(function(a, b) { return b[1] - a[1]; }).slice(0, 80).map(function(e) { return e[0]; });
}

function jmResumeText(data) {
  var parts = [];
  var b = data.basics || {};
  [b.name, b.title, b.location, b.summary].forEach(function(x) { if (x) parts.push(x); });
  if (data.summary) parts.push(data.summary);
  (data.experience || []).forEach(function(x) {
    [x.role, x.company, x.location, x.detail].forEach(function(v) { if (v) parts.push(v); });
    (x.bullets || []).forEach(function(bl) { if (bl) parts.push(bl); });
  });
  (data.projects || []).forEach(function(p) {
    [p.name, p.tech, p.detail].forEach(function(v) { if (v) parts.push(v); });
    (p.bullets || []).forEach(function(bl) { if (bl) parts.push(bl); });
  });
  (data.education || []).forEach(function(e) {
    [e.degree, e.school, e.detail].forEach(function(v) { if (v) parts.push(v); });
  });
  (data.skills || []).forEach(function(g) {
    if (g.group) parts.push(g.group);
    (g.items || []).forEach(function(it) { if (it) parts.push(it); });
  });
  (data.certs || []).forEach(function(c) { if (c) parts.push(c); });
  (data.custom || []).forEach(function(c) {
    if (c.heading) parts.push(c.heading);
    if (c.body) parts.push(c.body.replace(/<[^>]*>/g, " "));
  });
  return parts.join(" ").toLowerCase();
}

function jmAnalyze(data, jdText) {
  if (!jdText || !jdText.trim()) return null;
  var keywords = jmExtractKeywords(jdText);
  var rtext = jmResumeText(data);
  var TOP = Math.min(keywords.length, 40);
  var topKw = keywords.slice(0, TOP);
  var matched = topKw.filter(function(kw) { return rtext.indexOf(kw) !== -1; });
  var missing = topKw.filter(function(kw) { return rtext.indexOf(kw) === -1; }).slice(0, 24);
  var score = TOP > 0 ? Math.min(100, Math.round((matched.length / TOP) * 100)) : 0;
  return { score: score, matched: matched.slice(0, 20), missing: missing, total: TOP };
}

function JobMatchDrawer({ data, onClose }) {
  var stateHook = React.useState("");
  var jd = stateHook[0], setJd = stateHook[1];
  var resultHook = React.useState(null);
  var result = resultHook[0], setResult = resultHook[1];
  var busyHook = React.useState(false);
  var busy = busyHook[0], setBusy = busyHook[1];

  var run = function() {
    if (!jd.trim()) return;
    setBusy(true);
    setTimeout(function() {
      setResult(jmAnalyze(data, jd));
      setBusy(false);
    }, 200);
  };

  var sc = result ? result.score : 0;
  var scColor = sc >= 80 ? "#16A36B" : sc >= 60 ? "#1C9BE6" : sc >= 40 ? "#E0A013" : "#E0533D";
  var scLabel = sc >= 80 ? "Excellent match" : sc >= 60 ? "Good match" : sc >= 40 ? "Partial match" : "Low match";

  return (
    <React.Fragment>
      <div className="drawer-back" onClick={onClose} />
      <div className="drawer">
        <div className="drawer-h" style={{ display: "flex", alignItems: "center" }}>
          <div>
            <h3 style={{ margin: 0, fontSize: 16, fontWeight: 700, color: "var(--navy)" }}>Job Match</h3>
            <p style={{ margin: "3px 0 0", fontSize: 12.5, color: "var(--slate-500)" }}>
              Paste a job description to see how well your résumé aligns.
            </p>
          </div>
          <div style={{ flex: 1 }} />
          <button className="x" onClick={onClose}><Icon name="x" size={18} /></button>
        </div>

        <div className="drawer-body scroll" style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          <div>
            <label className="dz-label">Job description</label>
            <textarea className="ta" value={jd} onChange={function(e) { setJd(e.target.value); }}
              style={{ minHeight: 160 }}
              placeholder="Paste the full job description here — responsibilities, required qualifications, preferred skills, tech stack…" />
          </div>

          <button className="btn btn-grad" onClick={run}
            disabled={!jd.trim() || busy}
            style={{ opacity: (!jd.trim() || busy) ? 0.65 : 1 }}>
            {busy
              ? <React.Fragment><span className="spin" /> Analyzing…</React.Fragment>
              : <React.Fragment><Icon name="target" size={16} /> Analyze Match</React.Fragment>}
          </button>

          {result && (
            <React.Fragment>
              {/* Score hero */}
              <div className="score-hero" style={{ alignItems: "center" }}>
                {(function() {
                  var size = 84, stroke = 7, r = (size - stroke) / 2, c = 2 * Math.PI * r;
                  var off = c * (1 - sc / 100);
                  return (
                    <div style={{ position: "relative", width: size, height: size, flexShrink: 0 }}>
                      <svg width={size} height={size} style={{ transform: "rotate(-90deg)" }}>
                        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--slate-200)" strokeWidth={stroke} />
                        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={scColor} strokeWidth={stroke}
                          strokeDasharray={c} strokeDashoffset={off}
                          style={{ strokeLinecap: "round", transition: "stroke-dashoffset .6s cubic-bezier(.2,.8,.2,1)" }} />
                      </svg>
                      <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center" }}>
                        <b style={{ fontSize: 22, fontWeight: 800, color: "var(--navy)", lineHeight: 1 }}>{sc}</b>
                        <span style={{ fontSize: 9.5, fontWeight: 700, color: "var(--slate-400)", letterSpacing: ".06em" }}>/100</span>
                      </div>
                    </div>
                  );
                })()}
                <div>
                  <div style={{ fontSize: 16, fontWeight: 700, color: scColor }}>{scLabel}</div>
                  <p style={{ margin: "5px 0 0", fontSize: 12.5, color: "var(--slate-600)", lineHeight: 1.45 }}>
                    {result.matched.length} of {result.total} top keywords found in your résumé.
                  </p>
                </div>
              </div>

              {result.missing.length > 0 && (
                <div>
                  <div className="cat-h" style={{ marginTop: 0 }}>
                    Missing keywords <span style={{ fontWeight: 500, textTransform: "none", fontSize: 10.5, letterSpacing: 0 }}>— add these where honestly applicable</span>
                  </div>
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 7, marginTop: 8 }}>
                    {result.missing.map(function(kw, i) {
                      return (
                        <span key={i} style={{ padding: "4px 10px", borderRadius: 99, background: "rgba(224,83,61,.09)", color: "var(--bad)", fontSize: 12, fontWeight: 600, border: "1px solid rgba(224,83,61,.2)" }}>
                          {kw}
                        </span>
                      );
                    })}
                  </div>
                </div>
              )}

              {result.matched.length > 0 && (
                <div>
                  <div className="cat-h">Matched keywords</div>
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 7, marginTop: 8 }}>
                    {result.matched.map(function(kw, i) {
                      return (
                        <span key={i} style={{ padding: "4px 10px", borderRadius: 99, background: "rgba(22,163,107,.09)", color: "var(--good)", fontSize: 12, fontWeight: 600, border: "1px solid rgba(22,163,107,.2)" }}>
                          {kw}
                        </span>
                      );
                    })}
                  </div>
                </div>
              )}

              <div className="tip" style={{ marginTop: 4 }}>
                <div className="t"><Icon name="sparkle" size={15} style={{ color: "var(--brand-blue)" }} /> Tips</div>
                <p>Mirror the job description's exact phrasing. ATS systems treat "product design" and "UX design" as different terms — precision matters. Add missing keywords to your Skills section or experience bullets where truthful.</p>
              </div>
            </React.Fragment>
          )}
        </div>
      </div>
    </React.Fragment>
  );
}

window.JobMatchDrawer = JobMatchDrawer;
