/* MatchPlan.ai — UI primitives on the MatchIQ design system. Exposed on window. */

// ---- Lucide icon (UMD global `lucide`); line icons, ~1.75 stroke to match MatchIQ ----
function Icon({ name, size = 18, strokeWidth = 1.85, className = "", style }) {
  const node = (window.lucide && (window.lucide[name] || (window.lucide.icons && window.lucide.icons[name]))) || null;
  if (!node) return null;
  const children = Array.isArray(node) && Array.isArray(node[2]) ? node[2] : (node.children || []);
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round"
      className={className} style={style} aria-hidden="true">
      {children.map((c, i) => {
        const tag = c[0]; const raw = c[1] || {}; const attrs = { key: i };
        for (const k in raw) {
          if (k === "stroke-width") attrs.strokeWidth = raw[k];
          else if (k === "stroke-linecap") attrs.strokeLinecap = raw[k];
          else if (k === "stroke-linejoin") attrs.strokeLinejoin = raw[k];
          else if (k === "fill-rule") attrs.fillRule = raw[k];
          else if (k === "clip-rule") attrs.clipRule = raw[k];
          else attrs[k] = raw[k];
        }
        return React.createElement(tag, attrs);
      })}
    </svg>
  );
}

// ---- Button (.tm-btn) ----
function Button({ children, variant = "primary", size = "md", icon, iconRight, className = "", block, ...rest }) {
  const sizeCls = size === "sm" ? " tm-btn--sm" : size === "lg" ? " tm-btn--lg" : "";
  const iconSize = size === "lg" ? 19 : size === "sm" ? 15 : 17;
  return (
    <button className={`tm-btn tm-btn--${variant}${sizeCls}${block ? " tm-btn--block" : ""} ${className}`} {...rest}>
      {icon && <Icon name={icon} size={iconSize} />}
      {children}
      {iconRight && <Icon name={iconRight} size={iconSize} />}
    </button>
  );
}

// ---- Chip (.tm-chip) ----
function Chip({ tone = "neutral", children, icon, dot, className = "" }) {
  return (
    <span className={`tm-chip tm-chip--${tone}${icon ? " tm-chip--has-icon" : ""} ${className}`}>
      {dot && <span style={{ width: 8, height: 8, borderRadius: 99, background: "currentColor", opacity: .8 }}></span>}
      {icon && <Icon name={icon} size={14} />}
      {children}
    </span>
  );
}

// ---- Accent bar ----
function AccentBar({ color = "blue" }) { return <div className={`tm-accent-bar tm-accent-bar--${color}`}></div>; }

// ---- Card ----
function Card({ children, className = "", pad, accent, ...rest }) {
  return (
    <div className={`mp-card ${className}`} {...rest}>
      {accent && <AccentBar color={accent} />}
      {pad ? <div className="mp-card__pad">{children}</div> : children}
    </div>
  );
}

// ---- Section card with icon header ----
function Section({ icon, title, subtitle, children, accent }) {
  return (
    <Card accent={accent}>
      <div className="mp-card__pad">
        <div className="mp-section__head">
          <span className="mp-section__icon"><Icon name={icon} size={17} /></span>
          <h3 className="text-heading-3 mp-section__title">{title}</h3>
        </div>
        {subtitle && <p className="mp-section__sub">{subtitle}</p>}
        <div className="mp-section__body">{children}</div>
      </div>
    </Card>
  );
}

// ---- Field ----
function Field({ label, hint, optional, children }) {
  return (
    <label className="mp-field">
      <div className="mp-field__label">
        <span>{label}</span>
        {optional && <span className="mp-field__opt">optional</span>}
      </div>
      {children}
      {hint && <p className="mp-field__hint">{hint}</p>}
    </label>
  );
}

function Input(props) { return <input className={`tm-input ${props.className || ""}`} {...props} />; }
function Textarea(props) { return <textarea className={`mp-textarea ${props.className || ""}`} {...props} />; }
function Select({ children, className = "", ...rest }) {
  return (
    <div className="mp-select-wrap">
      <select className={`mp-select ${className}`} {...rest}>{children}</select>
      <Icon name="ChevronDown" size={16} />
    </div>
  );
}

// ---- Avatar (initials over brand-family color, or a user's STORED colour) ----
const AV_FAMILIES = ["blue", "purple", "green", "gold", "orange", "pink", "gray"];
// The neutral, non-palette mark: an avatar with no family and no stored colour.
const AV_NEUTRAL = "gray";
function avFamily(key) {
  // #107 (ELI-023): no name hash. A USER's colour is the platform's stored key (see Avatar's
  // `colorKey`); anything without an explicit family draws the neutral mark.
  return AV_FAMILIES.indexOf(key) !== -1 ? key : AV_NEUTRAL;
}
// #107: a user's colour key → the shell's hex, the ONE source of the User Color palette
// (window.EvolveShell, web/index.html). No key (null) or an unrecognised one paints the shell's
// NEUTRAL_USER_COLOR (#a2b0b7) — the same "not coloured yet" mark the shell and Coach paint.
// `undefined` only while the shell script has not loaded; the avatar then draws the app's gray mark.
function userColorHex(colorKey) {
  const shell = window.EvolveShell;
  if (!shell || !shell.userColorForKey) return undefined;
  return (colorKey && shell.userColorForKey(colorKey)) || shell.NEUTRAL_USER_COLOR;
}
// Initials type size as a share of the avatar's diameter.
const AV_INITIALS_RATIO = 0.36;
// `color` = a brand family for a NON-user avatar (prospect, company). `colorKey` = a platform USER's
// stored colour key (null = none assigned yet), painted with the shell's hex.
function Avatar({ name, color, colorKey, size = 36, soft }) {
  const initials = (name || "?").replace(/[^A-Za-z ]/g, "").split(" ").filter(Boolean).slice(0, 2).map(w => w[0]).join("").toUpperCase() || "?";
  const fontSize = size * AV_INITIALS_RATIO;
  const userHex = colorKey === undefined ? undefined : userColorHex(colorKey);
  if (soft) {
    return (
      <span className="mp-av-soft" style={{ width: size, height: size, fontSize, display: "inline-flex", alignItems: "center", justifyContent: "center", borderRadius: 999, flexShrink: 0, fontFamily: "var(--font-primary)", fontWeight: 900, background: "var(--accent-soft)", color: "var(--accent)" }}>
        {initials}
      </span>
    );
  }
  // A user with the shell's hex paints it inline; anything else takes its brand-family class.
  const className = userHex ? "tm-avatar" : `tm-avatar tm-avatar--${avFamily(color)}`;
  const background = userHex ? { background: userHex } : {};
  return <span className={className} title={name} style={{ width: size, height: size, fontSize, border: "none", ...background }}>{initials}</span>;
}

// ---- Logos (evolve-suite#1409) — they replaced TechnologyMatch's blue diamond ----
// Two lockups, one layout: a mark + a wordmark. Both are drawn from the Suite's lockup component, which
// sets its wordmark at 16.579px; `size` is that wordmark's font size here, and every other measure in
// kit.css's `.mp-logo` rules is in em, so either lockup keeps the Figma proportions at any size.
const LOGO_WORDMARK_PX = 16.579;

// The Evolve Suite lockup: black double-diamond mark + "EVOLVE | SUITE". Drawn as the Suite app draws it
// (evolve-suite apps/suite/src/components/evolve-suite-logo.tsx; Figma "Evolve Suite"
// `fYvRupTfIiOEBXYGOcvZZZ` node `4:3494`). Used on the sign-in page.
function EvolveSuiteLogo({ size = LOGO_WORDMARK_PX }) {
  return (
    <span className="mp-logo" style={{ fontSize: size }}>
      <img className="mp-logo__mark" src="app/assets/evolve-suite-mark.svg" alt="" />
      <span className="mp-logo__word">
        <span className="mp-logo__evolve">EVOLVE</span>
        <span className="mp-logo__rule" aria-hidden="true" />
        <span className="mp-logo__product">SUITE</span>
      </span>
    </span>
  );
}

// The Edge lockup for the in-app top bars (nav.jsx MobileTop, pages-newbrief.jsx CreateTopBar): the same
// double-diamond mark with a gold solid diamond + "EDGE". Figma "Evolve Edge" `T51wh9ODKWVeqS1lLXRmkb`
// node `52:12646` (the mobile Tool Bar's Logo Container): the Suite lockup with EVOLVE and the divider
// hidden, and the product word in its bold style.
function Logo({ size = LOGO_WORDMARK_PX, mono }) {
  return (
    <span className="mp-logo" style={{ fontSize: size }}>
      <img className="mp-logo__mark" src="app/assets/edge-mark.svg" alt="" />
      <span className="mp-logo__word">
        <span className="mp-logo__product">EDGE</span>
      </span>
    </span>
  );
}

// ---- Toast system ----
// The shared toast from the shell's global build (window.EvolveShell, web/index.html), under the two names every
// file here already uses. The shell draws it: top centre, a close button on every toast, in its own
// `.evsh-toast-container` portalled into <body>, above the Switching Loader and outside its inert sweep.
// useToast() returns the shell's toast object: toast.success(message), toast.error(message), toast.warning(message),
// each with an optional `{ duration }` in ms. Success dismisses itself; error and warning stay until closed.
//
// pitchiq#471 — ONE RULE FOR EVERY CALLER: while the app is showing a refusal page (`MP.refusal()`), no
// error and no warning is raised. A request in an open tab that answers "your session has no workspace"
// flips the app to that page (api.js `noteSessionRefusal`), but the caller's own `catch` still runs and
// toasts its "…try again" — and the toast layer wraps App, so the sentence landed on top of the page
// that had just said why trying again cannot work. Held back HERE, the one place every toast in
// web/app passes through, rather than in each of those catches. Read when the toast is RAISED, not
// when the hook ran: the refusal is set before the request rejects, long after the page took its toast.
// Success is untouched. Still the shell's toast underneath, so it still draws in the shell's layer.
function appIsRefused() {
  return !!(window.MP && typeof window.MP.refusal === "function" && window.MP.refusal());
}
// One wrapper per shell toast object, so `useToast()` keeps returning the SAME object across renders
// (pages hold it in hook dependency arrays).
const quietToasts = new WeakMap();
function useToast() {
  const toast = window.EvolveShell.useToast();
  let quiet = quietToasts.get(toast);
  if (!quiet) {
    quiet = Object.assign({}, toast, {
      error: function () { if (!appIsRefused()) return toast.error.apply(toast, arguments); },
      warning: function () { if (!appIsRefused()) return toast.warning.apply(toast, arguments); },
    });
    quietToasts.set(toast, quiet);
  }
  return quiet;
}
// No `routeKey`: a toast stays up across in-app navigation (several are raised right before one).
function ToastProvider({ children }) {
  return <window.EvolveShell.ToastProvider>{children}</window.EvolveShell.ToastProvider>;
}

Object.assign(window, {
  Icon, Button, Chip, AccentBar, Card, Section, Field, Input, Textarea, Select, Avatar, Logo, EvolveSuiteLogo,
  useToast, ToastProvider
});
