// Shared editor primitives: ScoreRing, Chip, IssueUnderline, IconBtn, buttons.
// These are used by all three variants.

const { useState, useEffect, useRef, useMemo, useCallback, Fragment } = React;

// ---------- SVG icon helper ----------
function Icon({ name, size = 20, color, style }) {
  return (
    <img
      src={`assets/icons/${name}`}
      width={size}
      height={size}
      style={{ display: "block", ...(color ? { filter: color === "white" ? "invert(1)" : "none" } : {}), ...style }}
      alt=""
    />
  );
}
window.Icon = Icon;

// ---------- Score ring ----------
function ScoreRing({ value, size = 44, stroke = 4 }) {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const off = c - (value / 100) * c;
  const color =
    value >= 85 ? "#0E9638" :
    value >= 65 ? "#F6AA1C" : "#C20216";
  return (
    <div style={{ position: "relative", width: size, height: size }}>
      <svg width={size} height={size} style={{ transform: "rotate(-90deg)" }}>
        <circle cx={size/2} cy={size/2} r={r} stroke="#E6E2DC" strokeWidth={stroke} fill="none" />
        <circle
          cx={size/2} cy={size/2} r={r}
          stroke={color} strokeWidth={stroke} fill="none"
          strokeDasharray={c} strokeDashoffset={off}
          strokeLinecap="round"
          style={{ transition: "stroke-dashoffset .5s cubic-bezier(.22,.61,.36,1), stroke .3s" }}
        />
      </svg>
      <div style={{
        position:"absolute", inset:0, display:"grid", placeItems:"center",
        fontFamily:"var(--font-heading)", fontWeight:500, fontSize: size > 40 ? 15 : 12,
        color:"var(--fg-1)", letterSpacing:"-.01em",
      }}>{value}</div>
    </div>
  );
}
window.ScoreRing = ScoreRing;

// ---------- Severity dot ----------
function SeverityDot({ severity }) {
  const map = { high: "#C20216", med: "#F6AA1C", low: "#92908C" };
  return <span style={{ width: 8, height: 8, borderRadius: 999, background: map[severity], display: "inline-block", flexShrink: 0 }} />;
}
window.SeverityDot = SeverityDot;

// ---------- Type chip ----------
function TypeChip({ type }) {
  const meta = window.ISSUE_META[type];
  const tint = window.TINTS[meta.tint];
  return (
    <span style={{
      display:"inline-flex", alignItems:"center", gap:5,
      fontFamily:"var(--font-body)", fontSize:11, fontWeight:500,
      color:tint.fg, background:tint.bg, border:`1px solid ${tint.border}`,
      padding:"2px 8px", borderRadius:999, letterSpacing:".01em",
    }}>
      {meta.label}
    </span>
  );
}
window.TypeChip = TypeChip;

// ---------- Dotted underline for an issue span ----------
// Renders the text with a wavy/dotted underline keyed off issue type.
function IssueSpan({ issueId, children, onClick, state, active, variantStyle }) {
  const issue = window.ISSUES[issueId];
  if (!issue) return <span>{children}</span>;
  const meta = window.ISSUE_META[issue.type];
  const tint = window.TINTS[meta.tint];

  if (state === "accepted") {
    return (
      <span style={{
        background: "rgba(232,255,99,.45)", // lime flash
        borderRadius: 3, padding: "0 2px",
        transition: "background 1.2s ease",
      }}>
        {children}
      </span>
    );
  }
  if (state === "dismissed") return <span>{children}</span>;

  // base style — dotted underline using linear-gradient for precise color/rhythm
  const baseStyle = {
    cursor: "pointer",
    backgroundImage: `linear-gradient(90deg, ${tint.underline} 60%, transparent 60%)`,
    backgroundSize: "5px 2px",
    backgroundRepeat: "repeat-x",
    backgroundPosition: "0 100%",
    paddingBottom: 2,
    borderRadius: 2,
    transition: "background-color .15s ease",
    backgroundColor: active ? `${tint.underline}22` : "transparent",
  };

  // variantStyle override: "chip" = soft pill around the text
  const chipStyle = {
    cursor: "pointer",
    background: active ? tint.underline + "33" : tint.bg,
    border: `1px dashed ${tint.underline}`,
    borderRadius: 4,
    padding: "0 3px",
    margin: "0 -1px",
    transition: "all .15s",
  };

  return (
    <span
      data-issue={issueId}
      onClick={(e) => { e.stopPropagation(); onClick && onClick(issueId, e.currentTarget); }}
      style={variantStyle === "chip" ? chipStyle : baseStyle}
    >
      {children}
    </span>
  );
}
window.IssueSpan = IssueSpan;

// ---------- Render a fragment array ----------
function RenderFragments({ fragments, onIssue, issueStates, activeId, variantStyle }) {
  return (
    <>
      {fragments.map((f, i) =>
        f.issue ? (
          <IssueSpan
            key={i}
            issueId={f.issue}
            state={issueStates[f.issue]?.state}
            active={activeId === f.issue}
            onClick={onIssue}
            variantStyle={variantStyle}
          >
            {issueStates[f.issue]?.state === "accepted"
              ? issueStates[f.issue].replaced
              : f.text}
          </IssueSpan>
        ) : (
          <Fragment key={i}>{f.text}</Fragment>
        )
      )}
    </>
  );
}
window.RenderFragments = RenderFragments;

// ---------- Resume body (shared layout) ----------
function ResumeBody({ onIssue, issueStates, activeId, variantStyle }) {
  const R = window.RESUME;
  const renderFrags = (frags) => (
    <RenderFragments
      fragments={frags}
      onIssue={onIssue}
      issueStates={issueStates}
      activeId={activeId}
      variantStyle={variantStyle}
    />
  );
  return (
    <div style={{ padding: "20px 20px 160px", fontFamily: "var(--font-body)", color: "var(--fg-1)" }}>
      {/* Header */}
      <div style={{ marginBottom: 18 }}>
        <h1 style={{
          fontFamily: "var(--font-heading)", fontWeight: 500, fontSize: 28,
          margin: 0, letterSpacing: "-.01em", lineHeight: 1.15, color: "var(--fg-1)",
        }}>{R.name}</h1>
        <div style={{ fontSize: 14, color: "var(--fg-2)", marginTop: 2 }}>{R.title}</div>
        <div style={{ fontSize: 12, color: "var(--fg-3)", marginTop: 6, display: "flex", gap: 10, flexWrap: "wrap" }}>
          <span>{R.email}</span><span>·</span><span>{R.phone}</span><span>·</span><span>{R.location}</span>
        </div>
      </div>

      <Section label="Summary">
        <p style={{ margin: 0, fontSize: 14, lineHeight: 1.6, color: "var(--fg-1)", textWrap: "pretty" }}>
          {renderFrags(R.summary.fragments)}
        </p>
      </Section>

      <Section label="Experience">
        {R.experience.map(exp => (
          <div key={exp.id} style={{ marginBottom: 16 }}>
            <div style={{ display: "flex", justifyContent: "space-between", gap: 8, alignItems: "baseline" }}>
              <div style={{ fontFamily:"var(--font-heading)", fontWeight:500, fontSize:15, color:"var(--fg-1)" }}>{exp.role}</div>
              <div style={{ fontSize: 11, color: "var(--fg-3)", whiteSpace: "nowrap" }}>{exp.dates}</div>
            </div>
            <div style={{ fontSize: 13, color: "var(--fg-2)", marginBottom: 8 }}>{exp.company}</div>
            <ul style={{ paddingLeft: 16, margin: 0, fontSize: 13.5, lineHeight: 1.6, color: "var(--fg-1)" }}>
              {exp.bullets.map(b => (
                <li key={b.id} data-bullet={b.id} style={{ marginBottom: 4, textWrap: "pretty" }}>
                  {renderFrags(b.fragments)}
                </li>
              ))}
            </ul>
          </div>
        ))}
      </Section>

      <Section label="Skills">
        <p style={{ margin: 0, fontSize: 13.5, lineHeight: 1.6, color: "var(--fg-1)" }}>
          {renderFrags(R.skills.fragments)}
        </p>
      </Section>

      <Section label="Education">
        {R.education.lines.map((l, i) => (
          <div key={i} style={{ fontSize: 13.5, color: "var(--fg-1)", lineHeight: 1.6 }}>{l}</div>
        ))}
      </Section>
    </div>
  );
}
window.ResumeBody = ResumeBody;

function Section({ label, children }) {
  return (
    <section style={{ marginBottom: 22 }}>
      <div style={{
        fontFamily: "var(--font-body)", fontSize: 10, fontWeight: 500,
        letterSpacing: ".12em", textTransform: "uppercase",
        color: "var(--fg-3)", marginBottom: 8,
        paddingBottom: 6, borderBottom: "1px solid var(--border-1)",
      }}>{label}</div>
      {children}
    </section>
  );
}
window.Section = Section;

// ---------- Top bar (shared across variants) ----------
function TopBar({ score, issueCount, version, onVersion, onFixAll, onUndo, canUndo, variantLabel }) {
  const [verOpen, setVerOpen] = useState(false);
  const V = window.VERSIONS.find(v => v.id === version) || window.VERSIONS[0];
  return (
    <div style={{
      position: "sticky", top: 0, zIndex: 20, background: "var(--color-neutral-99)",
      borderBottom: "1px solid var(--border-1)",
    }}>
      {/* Row 1: logo + version + undo */}
      <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "10px 14px 6px" }}>
        <button onClick={() => window.history.back?.()} style={btnGhost()} aria-label="Back">
          <Icon name="arrow-left.svg" size={18} />
        </button>
        <div style={{ flex: 1, minWidth: 0 }}>
          <button
            onClick={() => setVerOpen(o => !o)}
            style={{
              display:"flex", alignItems:"center", gap:6, background:"transparent",
              border:0, padding:"4px 6px", borderRadius:6, cursor:"pointer",
              fontFamily:"var(--font-body)", width:"100%", textAlign:"left",
            }}
          >
            <div style={{ minWidth: 0, flex: 1 }}>
              <div style={{ fontSize: 14, fontWeight: 500, color: "var(--fg-1)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                {V.label}
              </div>
              <div style={{ fontSize: 10, color: "var(--fg-3)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                {V.date}
              </div>
            </div>
            <Icon name="chevron.svg" size={14} style={{ opacity: .6, transform: verOpen ? "rotate(180deg)" : "none", transition: "transform .15s" }} />
          </button>

          {verOpen && (
            <div style={{
              position:"absolute", top:"100%", left:14, right:14,
              background:"var(--color-neutral-100)",
              border:"1px solid var(--border-1)", borderRadius:12,
              boxShadow:"var(--shadow-md)", padding:6, zIndex:30,
              marginTop:4,
            }}>
              {window.VERSIONS.map(v => (
                <button key={v.id}
                  onClick={() => { onVersion(v.id); setVerOpen(false); }}
                  style={{
                    display:"flex", alignItems:"center", gap:10, width:"100%",
                    padding:"9px 10px", borderRadius:8, border:0,
                    background: v.id === version ? "var(--color-neutral-95)" : "transparent",
                    cursor:"pointer", textAlign:"left", fontFamily:"var(--font-body)",
                  }}>
                  <div style={{
                    width:22, height:22, borderRadius:999,
                    border: v.id === version ? "none" : "1.5px solid var(--border-1)",
                    background: v.id === version ? "var(--color-neutral-0)" : "transparent",
                    display:"grid", placeItems:"center", flexShrink:0,
                  }}>
                    {v.id === version && <Icon name="check-circle.svg" size={14} color="white" style={{filter:"invert(1)"}}/>}
                  </div>
                  <div style={{ flex:1, minWidth:0 }}>
                    <div style={{ fontSize:13, fontWeight:500, color:"var(--fg-1)" }}>{v.label}</div>
                    <div style={{ fontSize:11, color:"var(--fg-3)" }}>{v.date}</div>
                  </div>
                </button>
              ))}
              <div style={{ borderTop:"1px solid var(--border-1)", margin:"4px 2px" }}/>
              <button style={{
                display:"flex", alignItems:"center", gap:8, width:"100%",
                padding:"9px 10px", borderRadius:8, border:0, background:"transparent",
                cursor:"pointer", fontFamily:"var(--font-body)", fontSize:13, color:"var(--fg-1)",
              }}>
                <span style={{fontSize:16,lineHeight:1}}>+</span> Duplicate as new version
              </button>
            </div>
          )}
        </div>

        <button onClick={onUndo} disabled={!canUndo} style={{ ...btnGhost(), opacity: canUndo ? 1 : .35 }} aria-label="Undo">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none"><path d="M4 10h9a6 6 0 1 1 0 12h-3" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/><path d="m8 6-4 4 4 4" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>
        </button>
      </div>

      {/* Row 2: score + fix all */}
      <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "4px 14px 10px" }}>
        <ScoreRing value={score} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontFamily:"var(--font-heading)", fontWeight:500, fontSize:15, color:"var(--fg-1)", lineHeight:1.15 }}>
            Resume score
          </div>
          <div style={{ fontSize: 11, color: "var(--fg-3)", marginTop: 1 }}>
            {issueCount === 0 ? "All fixes applied" : `${issueCount} issue${issueCount === 1 ? "" : "s"} to review`}
          </div>
        </div>
        <button
          onClick={onFixAll}
          disabled={issueCount === 0}
          style={{
            background: issueCount === 0 ? "var(--color-neutral-90)" : "var(--color-neutral-0)",
            color: issueCount === 0 ? "var(--fg-3)" : "var(--color-neutral-100)",
            border: 0, padding: "9px 14px", borderRadius: 999,
            fontFamily: "var(--font-body)", fontSize: 12.5, fontWeight: 500,
            cursor: issueCount === 0 ? "default" : "pointer",
            display: "inline-flex", alignItems: "center", gap: 6,
            whiteSpace: "nowrap",
          }}
        >
          <span style={{ color: "var(--color-secondary-base)", display: "inline-flex" }}>
            <Icon name="sparkle.svg" size={14} />
          </span>
          Fix all
        </button>
      </div>
    </div>
  );
}
window.TopBar = TopBar;

function btnGhost() {
  return {
    background: "transparent", border: 0, cursor: "pointer",
    width: 36, height: 36, borderRadius: 999, display: "grid", placeItems: "center",
    color: "var(--fg-1)",
  };
}
window.btnGhost = btnGhost;

function fixAllButtonStyle(disabled) {
  return {
    background: disabled ? "var(--color-neutral-95)" : "var(--color-neutral-0)",
    color: disabled ? "var(--fg-3)" : "var(--color-neutral-100)",
    border: disabled ? "1px solid var(--border-1)" : 0,
    padding: "8px 13px",
    borderRadius: 999,
    boxShadow: "none",
    fontFamily: "var(--font-body)",
    fontSize: 12.5,
    fontWeight: 500,
    cursor: disabled ? "default" : "pointer",
    display: "inline-flex",
    alignItems: "center",
    gap: 5,
    whiteSpace: "nowrap",
    transition: "background .15s ease, border-color .15s ease, color .15s ease, transform .15s ease",
  };
}
window.fixAllButtonStyle = fixAllButtonStyle;

Object.assign(window, { Icon, ScoreRing, SeverityDot, TypeChip, IssueSpan, RenderFragments, ResumeBody, Section, TopBar, btnGhost, fixAllButtonStyle });
