/* global React, Icon, CAT, CATEGORIES, isNewVideo */
// LPE Learning Center — shared primitives + the VideoCard / list row.

function cx(...a) { return a.filter(Boolean).join(" "); }

// ---- Button ----
function Button({ variant = "primary", size = "md", children, icon, iconRight, onClick, type = "button", className = "", style, ...rest }) {
  const sz = size === "sm" ? "btn-sm" : size === "lg" ? "btn-lg" : "";
  const variants = { primary: "btn-primary", navy: "btn-navy", secondary: "btn-secondary", ghost: "btn-ghost", "outline-light": "btn-outline-light" };
  return (
    <button type={type} className={cx("btn", variants[variant], sz, className)} onClick={onClick} style={style} {...rest}>
      {icon ? <Icon name={icon} size={14} /> : null}
      {children ? <span>{children}</span> : null}
      {iconRight ? <Icon name={iconRight} size={14} /> : null}
    </button>
  );
}

// ---- Tag (category) ----
function CatTag({ id }) {
  const c = CAT[id];
  if (!c) return null;
  const tone = c.tone === "default" ? "" : c.tone;
  return <span className={cx("tag", tone)}>{c.label}</span>;
}

// ---- Avatar ----
function Av({ initials, color = "navy", size = 28 }) {
  const colorClass = color === "teal" ? "teal" : color === "gold" ? "gold" : "";
  return (
    <span className={cx("av", colorClass)} style={{ width: size, height: size, fontSize: size * 0.38 }}>
      {initials}
    </span>
  );
}

// ---- Stat tile ----
function Stat({ label, value, sub, accent = false, icon }) {
  return (
    <div className="stat">
      <div className="stat-label">{label}</div>
      <div className={cx("stat-value", accent && "accent")}>{value}</div>
      {sub ? <div className="stat-meta">{sub}</div> : null}
      {icon ? <div className="stat-corner"><Icon name={icon} size={16} /></div> : null}
    </div>
  );
}

// ---- Section header ----
function SectionHead({ title, meta, more, onMore }) {
  return (
    <div className="lc-section-head">
      <h2>{title}</h2>
      {meta ? <span className="meta">{meta}</span> : null}
      {more ? <a className="more" onClick={onMore}>{more}<Icon name="arrowRight" size={12} /></a> : null}
    </div>
  );
}

// ---- CLE flag ----
function CleFlag({ cle }) {
  if (window.APP_TWEAKS && window.APP_TWEAKS.hideCle) return null;
  if (!cle || !cle.eligible) return null;
  const ethics = cle.type === "Ethics";
  return (
    <span className={cx("cle-flag", ethics && "ethics")}>
      <Icon name="award" size={11} />
      {cle.credits.toFixed(1)} CLE{ethics ? " · Ethics" : ""}
    </span>
  );
}

// ---- Format label ----
function fmtLabel(f) { return f === "webinar" ? "Webinar" : f === "tutorial" ? "Tutorial" : "Recorded session"; }

// ---- Video card (grid) ----
function VideoCard({ v, saved, onSave, onOpen, openSpeaker }) {
    const thumbUrl = v.thumbnailUrl || (v.youtubeId ? `https://img.youtube.com/vi/${v.youtubeId}/0.jpg` : null);
    return (
      <article className="vcard" onClick={() => onOpen(v.id)}>
        <div className="vthumb" style={thumbUrl ? { backgroundImage: `url(${thumbUrl})`, backgroundSize: "cover", backgroundPosition: "center" } : undefined}>
          {!thumbUrl ? <div className="glyph">{v.title}</div> : null}
        <span className="code-tag">{v.code}</span>
        {typeof isNewVideo === "function" && isNewVideo(v) ? <span className="new-badge" style={{ position: "absolute", top: 34, left: 10 }}>New</span> : null}
        <span className={cx("fmt-tag", v.format === "webinar" && "live")}>{fmtLabel(v.format)}</span>
        <button
          className={cx("save", saved && "on")}
          title={saved ? "Saved" : "Save"}
          onClick={(e) => { e.stopPropagation(); onSave(v.id); }}
        >
          <Icon name={saved ? "bookmarkFill" : "bookmark"} size={14} />
        </button>
        {v.transcript ? <span className="cc-badge cc-corner">CC</span> : null}
        <span className="dur-tag">{v.durLabel}</span>
        <div className="play-pill"><Icon name="playFill" size={16} /></div>
        {v.progress > 0 && v.progress < 100 ? (
          <div className="progress"><div className="fill" style={{ width: v.progress + "%" }} /></div>
        ) : null}
      </div>
      <div className="vbody">
        <div className="vmeta">
          <span>{v.date}</span>
          <span className="dot" />
          {v.progress === 100 ? (
            <span className="done"><Icon name="check" size={11} /> Completed</span>
          ) : v.progress > 0 ? (
            <span className="resume">Resume · {v.progress}%</span>
          ) : (
            <span>{Number(v.views).toLocaleString()} views</span>
          )}
        </div>
        <h3 className="vtitle">{v.title}</h3>
        <p className="vsub">{v.sub}</p>
        <div className="vtags">
          {v.cats.slice(0, 2).map((c) => <CatTag key={c} id={c} />)}
        </div>
        <div className="vfoot">
          <div className={cx("who", openSpeaker && "name-link")} onClick={openSpeaker ? (e) => { e.stopPropagation(); openSpeaker(v.speaker.name); } : undefined}>
            <Av initials={v.speaker.initials} color={v.speaker.color} />
            <span className="nm">{v.speaker.name}</span>
          </div>
          {v.cle.eligible && !(window.APP_TWEAKS && window.APP_TWEAKS.hideCle) ? <CleFlag cle={v.cle} /> : <span className="small" style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.04em" }}>{v.durLabel}</span>}
        </div>
      </div>
    </article>
  );
}

// ---- Video list row ----
function VideoRow({ v, onOpen, openSpeaker }) {
  const thumbUrl = v.thumbnailUrl || (v.youtubeId ? `https://img.youtube.com/vi/${v.youtubeId}/0.jpg` : null);
  return (
    <div className="lrow" onClick={() => onOpen(v.id)}>
      <div className="lthumb" style={thumbUrl ? { backgroundImage: `url(${thumbUrl})`, backgroundSize: "cover", backgroundPosition: "center" } : undefined}>
        {!thumbUrl ? <Icon name="playFill" size={18} /> : null}
        <span className="dur-tag">{v.durLabel}</span>
        {v.progress > 0 && v.progress < 100 ? <div className="progress"><div className="fill" style={{ width: v.progress + "%" }} /></div> : null}
      </div>
      <div className="linfo">
        <span className="code">{v.code} · {fmtLabel(v.format)}{typeof isNewVideo === "function" && isNewVideo(v) ? <span className="new-badge" style={{ marginLeft: 8, verticalAlign: "1px" }}>New</span> : null}</span>
        <h4>{v.title}</h4>
        <span className="sub">{v.sub}</span>
        <div className="vtags" style={{ marginTop: 4 }}>{v.cats.slice(0, 2).map((c) => <CatTag key={c} id={c} />)}</div>
      </div>
      <div className="lright">
        <CleFlag cle={v.cle} />
        <div style={{ textAlign: "right" }}>
          <div className={cx("t-title", openSpeaker && "name-link")} style={{ fontSize: 13 }} onClick={openSpeaker ? (e) => { e.stopPropagation(); openSpeaker(v.speaker.name); } : undefined}>{v.speaker.name}</div>
          <div className="small" style={{ fontSize: 11.5 }}>{v.date}</div>
        </div>
        <Icon name="chevRight" size={16} />
      </div>
    </div>
  );
}

// ---- Toast ----
function Toast({ msg }) {
  if (!msg) return null;
  return <div className="lc-toast"><Icon name="checkCircle" size={18} />{msg}</div>;
}

// ---- Accreditation line + popover ----
function AccredLine({ cle }) {
  if (window.APP_TWEAKS && window.APP_TWEAKS.hideCle) return null;
  if (!cle || !cle.eligible) return null;
  return (
    <span className="accred-badge" style={{
      display: 'inline-flex',
      alignItems: 'center',
      gap: 6,
      background: 'rgba(27, 127, 124, 0.1)',
      color: '#1B7F7C',
      padding: '4px 10px',
      borderRadius: '100px',
      fontSize: '11px',
      fontWeight: '600',
      textTransform: 'uppercase',
      letterSpacing: '0.05em'
    }}>
      <Icon name="checkCircle" size={12} />
      CLE Eligible ({cle.credits.toFixed(1)} Hours)
    </span>
  );
}

// ---- Welcome Tour (Interactive Spotlight Product Tour) ----
function WelcomeTour({ onClose, isAdmin = false }) {
  const [step, setStep] = React.useState(1);
  const [rect, setRect] = React.useState(null);

  const steps = isAdmin ? [
    {
      target: ".search",
      title: "Search Webinars & Topics",
      desc: "Type keywords, speakers, or topics (e.g. 'valuation', 'financing', 'PE') to search the entire video library.",
      position: "bottom"
    },
    {
      target: ".sidebar",
      title: "Administrative Portal Navigation",
      desc: "Manage member registrations, review CLE approval requests, edit video catalog items, and view live event registrations.",
      position: "right"
    },
    {
      target: ".topbar-actions",
      title: "Admin Controls & System Options",
      desc: "Click the 'Hide CLE' button in the top bar to toggle CLE features system-wide, check notifications, or manage portal settings.",
      position: "left"
    },
    {
      target: ".lc-grid, .page-header",
      title: "System Overview & Catalog",
      desc: "Monitor verified members, pending applications, and manage course catalog details in real-time.",
      position: "bottom"
    },
    {
      target: ".platform-tour-card, .sidebar",
      title: "You're All Set!",
      desc: "You can restart this guided administrator walkthrough anytime from the bottom of your sidebar or your profile menu.",
      position: "right"
    }
  ] : [
    {
      target: ".search",
      title: "Search Webinars & Topics",
      desc: "Type keywords, speakers, or topics (e.g. 'valuation', 'financing', 'PE') to instantly search our catalog of webinars and guides.",
      position: "bottom"
    },
    {
      target: ".sidebar",
      title: "Sidebar & Navigation",
      desc: "Switch between the Webinar Library, Upcoming Live Events, Saved Bookmarks, Resources, and your My Learning progress dashboard.",
      position: "right"
    },
    {
      target: ".topbar-actions",
      title: "Notifications & Account",
      desc: "Check your live event notifications, view saved webinars, or update your member profile and preferences.",
      position: "left"
    },
    {
      target: ".lc-grid, .page-header",
      title: "Webinar Catalog & Masterclasses",
      desc: "Click any webinar card to watch video lessons, view speaker details, or track your completion status.",
      position: "bottom"
    },
    {
      target: ".platform-tour-card, .sidebar",
      title: "You're All Set!",
      desc: "Whenever you want to take this tour again, simply click 'Platform Tour' at the bottom of your sidebar or in your profile menu!",
      position: "right"
    }
  ];

  const current = steps[step - 1];

  React.useEffect(() => {
    const updateRect = () => {
      if (!current || !current.target) return;
      const el = document.querySelector(current.target);
      if (el) {
        const r = el.getBoundingClientRect();
        setRect({
          top: r.top,
          left: r.left,
          width: r.width,
          height: r.height
        });
      } else {
        setRect(null);
      }
    };
    updateRect();
    const tid = setTimeout(updateRect, 100);
    window.addEventListener("resize", updateRect);
    window.addEventListener("scroll", updateRect);
    return () => {
      clearTimeout(tid);
      window.removeEventListener("resize", updateRect);
      window.removeEventListener("scroll", updateRect);
    };
  }, [step, current]);

  // Position calculation for tooltip callout bubble
  let popStyle = {};
  if (rect) {
    if (current.position === "bottom") {
      popStyle = {
        top: Math.min(window.innerHeight - 260, rect.top + rect.height + 16),
        left: Math.max(16, Math.min(window.innerWidth - 370, rect.left + (rect.width / 2) - 180))
      };
    } else if (current.position === "right") {
      popStyle = {
        top: Math.max(16, Math.min(window.innerHeight - 260, rect.top + 20)),
        left: Math.min(window.innerWidth - 370, rect.left + rect.width + 16)
      };
    } else if (current.position === "left") {
      popStyle = {
        top: Math.max(16, Math.min(window.innerHeight - 260, rect.top)),
        left: Math.max(16, rect.left - 370)
      };
    } else {
      popStyle = {
        top: Math.max(16, rect.top - 240),
        left: Math.max(16, Math.min(window.innerWidth - 370, rect.left))
      };
    }
  } else {
    // Fallback centered modal if target element not found
    popStyle = {
      top: "50%",
      left: "50%",
      transform: "translate(-50%, -50%)"
    };
  }

  return (
    <div style={{ position: "fixed", inset: 0, zIndex: 10000, pointerEvents: "auto" }}>
      {/* Spotlight cutout ring */}
      {rect ? (
        <div
          style={{
            position: "fixed",
            top: Math.max(0, rect.top - 6),
            left: Math.max(0, rect.left - 6),
            width: rect.width + 12,
            height: rect.height + 12,
            borderRadius: 12,
            border: "2.5px solid var(--orange)",
            boxShadow: "0 0 0 9999px rgba(10, 30, 54, 0.72), 0 0 25px rgba(228, 116, 37, 0.6)",
            pointerEvents: "none",
            transition: "all 0.3s cubic-bezier(0.16, 1, 0.3, 1)"
          }}
        />
      ) : (
        <div style={{ position: "fixed", inset: 0, background: "rgba(10, 30, 54, 0.75)" }} />
      )}

      {/* Tooltip callout bubble */}
      <div
        style={{
          position: "fixed",
          width: 350,
          background: "#ffffff",
          borderRadius: 16,
          padding: "22px 20px 18px",
          boxShadow: "0 15px 40px rgba(0, 0, 0, 0.35)",
          border: "1.5px solid rgba(228, 116, 37, 0.35)",
          zIndex: 10001,
          transition: "all 0.3s cubic-bezier(0.16, 1, 0.3, 1)",
          ...popStyle
        }}
      >
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 8 }}>
          <span
            style={{
              padding: "4px 10px",
              borderRadius: 100,
              background: "rgba(228, 116, 37, 0.12)",
              color: "var(--orange)",
              fontSize: 11,
              fontWeight: 700,
              textTransform: "uppercase",
              letterSpacing: "0.05em"
            }}
          >
            Step {step} of {steps.length}
          </span>
          <button
            onClick={onClose}
            style={{
              background: "none",
              border: "none",
              cursor: "pointer",
              color: "var(--grey)",
              fontSize: 20,
              lineHeight: 1,
              padding: "2px 6px"
            }}
          >
            &times;
          </button>
        </div>

        <h3 style={{ margin: "6px 0", color: "var(--navy)", fontWeight: 700, fontSize: 16.5 }}>
          {current.title}
        </h3>
        <p style={{ fontSize: 13, color: "var(--grey-700)", margin: "8px 0 16px", lineHeight: "1.55", whiteSpace: "pre-line" }}>
          {current.desc}
        </p>

        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", paddingTop: 12, borderTop: "1px solid var(--grey-200)" }}>
          <div style={{ display: "flex", gap: 5 }}>
            {steps.map((_, idx) => (
              <span
                key={idx}
                style={{
                  width: step === idx + 1 ? 16 : 6,
                  height: 6,
                  borderRadius: 3,
                  background: step === idx + 1 ? "var(--orange)" : "var(--grey-300)",
                  transition: "all 0.2s ease"
                }}
              />
            ))}
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            {step > 1 ? (
              <button
                onClick={() => setStep((s) => s - 1)}
                style={{
                  display: "inline-flex",
                  alignItems: "center",
                  gap: 4,
                  padding: "7px 15px",
                  borderRadius: "8px",
                  border: "none",
                  background: "var(--navy, #0A1E36)",
                  color: "#ffffff",
                  fontSize: 12.5,
                  fontWeight: 600,
                  cursor: "pointer",
                  boxShadow: "0 2px 8px rgba(10, 30, 54, 0.25)",
                  transition: "all 0.2s ease"
                }}
              >
                <Icon name="chevLeft" size={14} /> Back
              </button>
            ) : null}
            {step < steps.length ? (
              <button
                onClick={() => setStep((s) => s + 1)}
                style={{
                  display: "inline-flex",
                  alignItems: "center",
                  gap: 4,
                  padding: "7px 16px",
                  borderRadius: "8px",
                  border: "none",
                  background: "linear-gradient(135deg, #E47425 0%, #D86315 100%)",
                  color: "#ffffff",
                  fontSize: 12.5,
                  fontWeight: 700,
                  cursor: "pointer",
                  boxShadow: "0 3px 10px rgba(228, 116, 37, 0.3)",
                  transition: "all 0.2s ease"
                }}
              >
                Next <Icon name="arrowRight" size={14} />
              </button>
            ) : (
              <button
                onClick={onClose}
                style={{
                  display: "inline-flex",
                  alignItems: "center",
                  gap: 4,
                  padding: "7px 18px",
                  borderRadius: "8px",
                  border: "none",
                  background: "linear-gradient(135deg, #1B7F7C 0%, #156562 100%)",
                  color: "#ffffff",
                  fontSize: 12.5,
                  fontWeight: 700,
                  cursor: "pointer",
                  boxShadow: "0 3px 10px rgba(27, 127, 124, 0.3)",
                  transition: "all 0.2s ease"
                }}
              >
                Got it! <Icon name="check" size={14} />
              </button>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { cx, Button, CatTag, Av, Stat, SectionHead, CleFlag, fmtLabel, VideoCard, VideoRow, Toast, AccredLine, WelcomeTour });
