/* global React, Icon, Button, Chip, Avatar, AgentAvatar, Panel, TONES */
// ============================================================
// Get introduced — reusable pieces (atoms / molecules / organisms),
// specified against the component library so engineering can build them:
//   ScoreMeter · ProofChip · PathChain · WayInBadge · PersonaPathCard ·
//   SequenceStatusRow  (+ PersonChip, StatusSteps, degree/score helpers)
// ============================================================
const { useState: useNB } = React;

// ---- Score bands. Village's full range, rendered as a labelled bar. ----
const SCORE_BANDS = [
  { min: 90, label: "Excellent", tone: "sage" },
  { min: 80, label: "Very good", tone: "sage" },
  { min: 70, label: "Good", tone: "slate" },
  { min: 55, label: "Okay", tone: "ochre" },
  { min: 1, label: "Maybe", tone: "ochre" },
  { min: 0, label: "No path", tone: "neutral" },
];
const scoreBand = (n) => SCORE_BANDS.find(b => (n || 0) >= b.min) || SCORE_BANDS[SCORE_BANDS.length - 1];

// ---- Degree → strength label + the action it implies (cases C1–C4) ----
const DEGREE = {
  1: { label: "Direct", tone: "sage", action: "Message directly" },
  2: { label: "Warm intro", tone: "slate", action: "Request intro" },
  3: { label: "Warm intro", tone: "slate", action: "Request intro" },
  0: { label: "No path", tone: "neutral", action: "See options" },
};

const avColors = (tone) => { const t = TONES[tone] || TONES.neutral; return { color: t.tint, textColor: t.text }; };

// Build an Offerroom draft for a path when the data doesn't hand-author one.
// Calm, candid, plain; leads with the real tie; one easy ask; nothing gushy.
function makeDraft(path) {
  const t = path.target, first = t.name.split(" ")[0];
  const introName = path.introducer ? path.introducer.name : (path.bridge || null);
  const proofText = (path.proof && path.proof[0]) ? path.proof[0].text : "a shared connection";
  if (path.degree === 1) return { channel: `Direct message to ${t.name}`, note: `Hi ${first}, I'm looking hard at senior payments PM roles and ${t.co}'s team is high on my list. ${proofText}. Could I borrow 15 minutes to hear how you're finding it? No pressure either way.` };
  if (!path.degree) return { channel: `Cold note to ${t.name}`, note: `Hi ${first}, I've been following ${t.co}'s work and I'm exploring senior PM roles in the space. We haven't met, but we share a focus on payments. Would you be open to a short call? Happy to keep it brief.` };
  return { channel: `Intro request to ${introName}`, note: `Hi ${(introName || "there").split(" ")[0]}, hope you're well. I'm focused on senior payments roles and would value an intro to ${t.name} at ${t.co}. Would you be up for it? Happy to send a short blurb you can forward.`, blurb: `Maya is a senior PM with six years on checkout conversion, ex-Plaid. She's exploring ${t.co} and would value 15 minutes with ${first}.` };
}

// ---- ScoreMeter: a 0-100 strength bar with its word label ----
function ScoreMeter({ score, width = 132, compact = false }) {
  const b = scoreBand(score);
  const t = TONES[b.tone];
  if (!score) {
    return (
      <div style={{ width }}>
        <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 5 }}>
          <span style={{ fontSize: 11, fontWeight: 600, color: "var(--fg-3)" }}>No path</span>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--fg-3)" }}>—</span>
        </div>
        <div style={{ height: 6, borderRadius: 999, background: "repeating-linear-gradient(90deg, var(--ink-100) 0 5px, transparent 5px 10px)" }}/>
      </div>
    );
  }
  return (
    <div style={{ width }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 5 }}>
        <span style={{ fontSize: compact ? 10.5 : 11, fontWeight: 600, color: t.text, letterSpacing: "0.01em" }}>{b.label}</span>
        <span style={{ fontFamily: "var(--font-mono)", fontSize: compact ? 10.5 : 11, color: "var(--fg-2)", fontVariantNumeric: "tabular-nums" }}>{score}</span>
      </div>
      <div style={{ height: 6, borderRadius: 999, background: "var(--ink-100)", overflow: "hidden" }}>
        <div style={{ height: "100%", width: `${score}%`, borderRadius: 999, background: t.color, transition: "width 320ms cubic-bezier(0.2,0.7,0.1,1)" }}/>
      </div>
    </div>
  );
}

// ---- ProofChip: the "why this works" angle, human copy (case D) ----
const PROOF_ICON = { overlap: "layers", alumni: "graduation", connection: "link", meetings: "calendar", group: "route" };
function ProofChip({ proof, full = false }) {
  return (
    <span style={{
      display: "inline-flex", alignItems: full ? "flex-start" : "center", gap: 7,
      padding: full ? "8px 11px" : "4px 9px", borderRadius: full ? 8 : 999,
      background: "var(--paper-sunken)", border: "1px solid var(--ink-50)",
      fontSize: 12, color: "var(--ink-700)", lineHeight: 1.4, maxWidth: "100%",
    }}>
      <Icon name={PROOF_ICON[proof.type] || "link"} size={13} style={{ color: "var(--slate)", flexShrink: 0, marginTop: full ? 1 : 0 }}/>
      <span style={{ minWidth: 0 }}>{proof.text}</span>
    </span>
  );
}

// ---- PersonChip / PersonRow: a person with avatar + title ----
function PersonNode({ p, size = 38, sub }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 10, minWidth: 0 }}>
      <Avatar name={p.name} {...avColors(p.tone)} size={size}/>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 13.5, fontWeight: 600, color: "var(--fg-1)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{p.name}</div>
        <div style={{ fontSize: 12, color: "var(--fg-2)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{sub || `${p.title}${p.co ? " · " + p.co : ""}`}</div>
      </div>
    </div>
  );
}

// ---- PathChain: you -> introducer? -> target (the full chain, case C/D) ----
function PathChain({ path, vertical = false }) {
  const you = { name: "Maya Okonkwo", title: "You", tone: "cardinal" };
  const chain = (path.chain && path.chain.length)
    ? path.chain.map(c => ({ name: c.name, title: c.title || "Your connection", tone: "slate" }))
    : path.introducer ? [{ name: path.introducer.name, title: path.introducer.title || "Your connection", tone: "slate" }]
    : path.bridge ? [{ name: path.bridge, title: "Your connection", tone: "slate" }] : [];
  const nodes = [you, ...chain, { ...path.target }];

  return (
    <div style={{ display: "flex", flexDirection: vertical ? "column" : "row", alignItems: vertical ? "stretch" : "center", gap: vertical ? 0 : 4 }}>
      {nodes.map((n, i) => (
        <React.Fragment key={i}>
          <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 7, textAlign: "center", flex: vertical ? "none" : 1, padding: vertical ? "10px 0" : 0 }}>
            <Avatar name={n.name} {...avColors(n.tone)} size={i === nodes.length - 1 ? 46 : 40}/>
            <div>
              <div style={{ fontSize: 12.5, fontWeight: 600, lineHeight: 1.2 }}>{n.name}</div>
              <div style={{ fontSize: 11, color: "var(--fg-2)", marginTop: 2, maxWidth: 130, lineHeight: 1.3 }}>{n.title}{n.co ? ` · ${n.co}` : ""}</div>
            </div>
          </div>
          {i < nodes.length - 1 && (
            <div style={{ display: "flex", flexDirection: vertical ? "row" : "column", alignItems: "center", justifyContent: "center", gap: 6, padding: vertical ? "0 0 0 19px" : "0 2px", flexShrink: 0 }}>
              {vertical
                ? <div style={{ width: 2, height: 22, background: "repeating-linear-gradient(180deg, var(--ink-300) 0 4px, transparent 4px 8px)" }}/>
                : <>
                    <div style={{ height: 2, width: 34, background: "repeating-linear-gradient(90deg, var(--ink-300) 0 4px, transparent 4px 8px)", marginTop: -18 }}/>
                  </>}
            </div>
          )}
        </React.Fragment>
      ))}
    </div>
  );
}

// ---- Avatar stack (overlapping faces for the way-in badge / company rows) ----
function AvatarStack({ avatars, size = 22 }) {
  return (
    <div style={{ display: "flex", alignItems: "center" }}>
      {avatars.map((a, i) => (
        <span key={i} style={{ marginLeft: i === 0 ? 0 : -8, borderRadius: 999, border: "2px solid #fff", display: "inline-flex" }}>
          <Avatar name={a.i} {...avColors(a.tone)} size={size}/>
        </span>
      ))}
    </div>
  );
}

// ---- WayInBadge: the contextual probe on job cards (cheap check) ----
// Pre-sync it teases (drives sync). Synced + paths -> "N warm paths". No paths -> muted.
function WayInBadge({ company, synced = true, onClick }) {
  if (!synced) {
    return (
      <button onClick={onClick} style={badgeBase("rgba(140,21,21,0.07)", "rgba(140,21,21,0.18)")}>
        <Icon name="route" size={13} style={{ color: "var(--cardinal)" }}/>
        <span style={{ color: "var(--cardinal-700)", fontWeight: 600 }}>See your way in</span>
        <Icon name="arrow" size={12} style={{ color: "var(--cardinal)" }}/>
      </button>
    );
  }
  if (!company || !company.hasPaths) {
    return (
      <span style={{ ...badgeBase("var(--paper-sunken)", "var(--ink-100)"), cursor: "default" }}>
        <Icon name="close" size={12} style={{ color: "var(--fg-3)" }}/>
        <span style={{ color: "var(--fg-2)" }}>No path yet</span>
      </span>
    );
  }
  const b = scoreBand(company.bestScore);
  return (
    <button onClick={onClick} style={badgeBase("#fff", "var(--ink-100)")} title={`${company.count} warm paths into ${company.name}`}>
      <AvatarStack avatars={company.avatars} size={18}/>
      <span style={{ fontWeight: 600, color: "var(--fg-1)" }}>{company.count} warm paths</span>
      <span style={{ width: 5, height: 5, borderRadius: 999, background: TONES[b.tone].color }}/>
      <span style={{ fontSize: 11.5, color: "var(--fg-2)" }}>{b.label}</span>
    </button>
  );
}
const badgeBase = (bg, bc) => ({
  display: "inline-flex", alignItems: "center", gap: 7, padding: "5px 11px 5px 8px",
  borderRadius: 999, background: bg, border: `1px solid ${bc}`, cursor: "pointer",
  fontFamily: "var(--font-sans)", fontSize: 12.5, transition: "background 120ms",
});

// ---- StatusSteps: the F4 status flow as a compact stepper ----
function StatusSteps({ steps, current, size = "md" }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 0, flexWrap: "nowrap" }}>
      {steps.map((s, i) => {
        const done = i < current, active = i === current;
        return (
          <React.Fragment key={s}>
            <div style={{ display: "flex", alignItems: "center", gap: 6, flexShrink: 0 }}>
              <span style={{
                width: size === "sm" ? 16 : 18, height: size === "sm" ? 16 : 18, borderRadius: 999, flexShrink: 0,
                display: "grid", placeItems: "center",
                background: active ? "#8C1515" : done ? "#5A7150" : "#fff",
                color: active || done ? "#fff" : "var(--fg-3)",
                border: active || done ? "1px solid transparent" : "1px solid var(--ink-100)",
              }}>{done ? <Icon name="check" size={10}/> : <span style={{ width: 5, height: 5, borderRadius: 999, background: active ? "#fff" : "var(--ink-300)" }}/>}</span>
              <span style={{ fontSize: size === "sm" ? 11 : 12, fontWeight: active ? 600 : 500, color: active ? "var(--cardinal-700)" : done ? "var(--fg-1)" : "var(--fg-3)", whiteSpace: "nowrap" }}>{s}</span>
            </div>
            {i < steps.length - 1 && <span style={{ width: 18, height: 2, background: done ? "#5A7150" : "var(--ink-100)", margin: "0 8px", flexShrink: 1, minWidth: 10, borderRadius: 2 }}/>}
          </React.Fragment>
        );
      })}
    </div>
  );
}

// ---- PersonaPathCard: one persona slot on the board (the heart) ----
// Handles confident single-target, the uncertain "Department leaders" fallback,
// and the locked/upsell state for the free tier.
function PersonaPathCard({ def, persona, locked = false, onOpen }) {
  const primary = persona.uncertain ? persona.leaders[0] : persona;
  const deg = DEGREE[primary.degree] || DEGREE[0];
  const t = TONES[deg.tone];
  const action = primary.degree === 3 && primary.bridge ? `Request intro` : deg.action;

  return (
    <Panel pad={0} style={{ display: "flex", flexDirection: "column", overflow: "hidden", position: "relative" }}>
      {/* header: persona role */}
      <div style={{ display: "flex", alignItems: "center", gap: 9, padding: "12px 15px", borderBottom: "1px solid var(--ink-50)", background: "var(--paper)" }}>
        <span style={{ width: 28, height: 28, borderRadius: 8, background: "#fff", border: "1px solid var(--ink-100)", display: "grid", placeItems: "center", color: "var(--fg-1)", flexShrink: 0 }}>
          <Icon name={def.icon} size={15}/>
        </span>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 600, lineHeight: 1.2 }}>{persona.uncertain ? "Department leaders" : def.label}</div>
          <div style={{ fontSize: 11, color: "var(--fg-2)" }}>{persona.uncertain ? "Hiring manager unconfirmed" : def.blurb}</div>
        </div>
        <span style={{ display: "inline-flex", alignItems: "center", gap: 5, fontSize: 11, fontWeight: 600, color: t.text, background: t.tint, padding: "3px 9px", borderRadius: 999, flexShrink: 0, whiteSpace: "nowrap" }}>
          {primary.degree === 1 && <Icon name="zap" size={11}/>}{deg.label}
        </span>
      </div>

      {/* body */}
      <div style={{ padding: 15, display: "flex", flexDirection: "column", gap: 13, flex: 1, filter: locked ? "blur(5px)" : "none", userSelect: locked ? "none" : "auto", pointerEvents: locked ? "none" : "auto" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 12 }}>
          <PersonNode p={primary.target}/>
          <ScoreMeter score={primary.score} width={118} compact/>
        </div>
        <ProofChip proof={primary.proof[0]} full/>
        {persona.uncertain && persona.leaders[1] && (
          <div style={{ fontSize: 11.5, color: "var(--fg-2)", display: "flex", alignItems: "center", gap: 6 }}>
            <Avatar name={persona.leaders[1].target.name} {...avColors(persona.leaders[1].target.tone)} size={18}/>
            +1 other leader · {persona.leaders[1].target.name}
          </div>
        )}
      </div>

      {/* footer: action */}
      {!locked && (
        <div style={{ display: "flex", alignItems: "center", gap: 8, padding: "11px 15px", borderTop: "1px solid var(--ink-50)" }}>
          <Button variant={primary.degree === 1 ? "primary" : "secondary"} size="sm" icon={primary.degree === 1 ? "send" : "route"} onClick={() => onOpen(persona, def)}>{action}</Button>
          <span style={{ flex: 1 }}/>
          {primary.alternates > 0 && <button onClick={() => onOpen(persona, def)} style={{ fontSize: 11.5, color: "var(--fg-2)", background: "none", border: "none", cursor: "pointer", fontFamily: "var(--font-sans)" }}>+{primary.alternates} more {primary.alternates === 1 ? "path" : "paths"}</button>}
        </div>
      )}

      {/* locked overlay (upsell) */}
      {locked && (
        <div style={{ position: "absolute", inset: 0, top: 53, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 9, background: "rgba(246,244,239,0.55)", padding: 16, textAlign: "center" }}>
          <span style={{ width: 34, height: 34, borderRadius: 999, background: "#fff", border: "1px solid var(--ink-100)", display: "grid", placeItems: "center", color: "var(--cardinal)" }}><Icon name="lock" size={16}/></span>
          <div style={{ fontSize: 12.5, fontWeight: 600, color: "var(--fg-1)" }}>Unlock this path</div>
          <Button variant="primary" size="sm" icon="sparkles" onClick={() => onOpen(persona, def, true)}>Premium</Button>
        </div>
      )}
    </Panel>
  );
}

// ---- SequenceStatusRow: one outreach thread in the tracker ----
function SequenceStatusRow({ thread, onOpen }) {
  const t = TONES[thread.target.tone] || TONES.neutral;
  return (
    <button onClick={() => onOpen(thread)} style={{
      width: "100%", textAlign: "left", display: "flex", alignItems: "center", gap: 16, padding: "14px 18px",
      background: "#fff", border: "none", borderBottom: "1px solid var(--ink-50)", cursor: "pointer", fontFamily: "var(--font-sans)",
    }}
      onMouseEnter={e => e.currentTarget.style.background = "var(--paper-hover)"}
      onMouseLeave={e => e.currentTarget.style.background = "#fff"}>
      <div style={{ width: 220, flexShrink: 0, display: "flex", alignItems: "center", gap: 11 }}>
        <span style={{ position: "relative" }}>
          <Avatar name={thread.target.name} {...avColors(thread.target.tone)} size={38}/>
          <span style={{ position: "absolute", right: -2, bottom: -2, width: 15, height: 15, borderRadius: 999, background: thread.kind === "direct" ? "#5A7150" : "#4A5868", border: "2px solid #fff", display: "grid", placeItems: "center" }}>
            <Icon name={thread.kind === "direct" ? "send" : "route"} size={8} style={{ color: "#fff" }}/>
          </span>
        </span>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontSize: 13.5, fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{thread.target.name}</div>
          <div style={{ fontSize: 11.5, color: "var(--fg-2)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{thread.target.title} · {thread.target.co}</div>
        </div>
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <StatusSteps steps={thread.steps} current={thread.statusIndex} size="sm"/>
      </div>
      <div style={{ width: 168, flexShrink: 0, display: "flex", alignItems: "center", gap: 8, justifyContent: "flex-end" }}>
        <span style={{ fontSize: 11.5, color: thread.next.includes("reply") ? "var(--cardinal-700)" : "var(--fg-2)", textAlign: "right" }}>{thread.next}</span>
        <Icon name="chevron" size={15} style={{ color: "var(--fg-3)", flexShrink: 0 }}/>
      </div>
    </button>
  );
}

Object.assign(window, {
  SCORE_BANDS, scoreBand, DEGREE, avColors, makeDraft,
  ScoreMeter, ProofChip, PersonNode, PathChain, AvatarStack,
  WayInBadge, StatusSteps, PersonaPathCard, SequenceStatusRow,
});
