/* lti-launch.jsx — launch an external LTI 1.1 course from LearnALot.

   We are the Tool Consumer. The actual OAuth-1.0 signing happens server-side
   (/api/lti/launch) so the shared secret never reaches the browser; this
   component only points at that endpoint. Two ways to launch, per the provider:

   - New tab (reliable): opens /api/lti/launch?target=window, which returns an
     auto-submitting signed form that POSTs the learner into the provider. Most
     providers block being framed (X-Frame-Options / frame-ancestors), so this
     is the default, safe path.
   - Embedded iframe (fallback view): the same launch with target=iframe shown
     inline. If the provider refuses to be framed the panel stays blank, so a
     clear "open in a new tab" affordance is always present.

   Content-independent: nothing about any provider or course is hardcoded; it
   only carries the LTI source id, which the server resolves. */

function LtiLaunch({ ltiId, title, accent, onClose }) {
  const color = accent || "#1281c4";
  const [framed, setFramed] = useState(false);   // has the user chosen to embed?
  const [loaded, setLoaded] = useState(false);   // iframe fired onload
  const [slow, setSlow] = useState(false);       // iframe hasn't loaded in time
  const openedRef = useRef(false);

  const winUrl = "/api/lti/launch?id=" + encodeURIComponent(ltiId) + "&target=window";
  const frameUrl = "/api/lti/launch?id=" + encodeURIComponent(ltiId) + "&target=iframe";

  function openTab() { window.open(winUrl, "_blank", "noopener"); }

  // Default action: open in a new tab once on mount (the reliable path).
  useEffect(() => {
    if (!openedRef.current) { openedRef.current = true; openTab(); }
  }, []);

  // If the embedded view is chosen but never loads, surface the fallback.
  useEffect(() => {
    if (!framed || loaded) return;
    const to = setTimeout(() => setSlow(true), 6000);
    return () => clearTimeout(to);
  }, [framed, loaded]);

  return ReactDOM.createPortal(
    <div style={{ position: "fixed", inset: 0, zIndex: 720, background: "rgba(13,26,52,.62)", backdropFilter: "blur(3px)", display: "grid", placeItems: "center", padding: "2vh 2vw" }} onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div style={{ width: "100%", height: "100%", maxWidth: 1500, borderRadius: 14, overflow: "hidden", background: "#fff", display: "flex", flexDirection: "column", boxShadow: "0 24px 70px rgba(0,0,0,.35)" }}>
        {/* header */}
        <div style={{ flex: "none", display: "flex", alignItems: "center", gap: 12, padding: "10px 16px", borderBottom: "1px solid var(--line)", background: "var(--surface)" }}>
          <span style={{ width: 30, height: 30, borderRadius: 8, background: color, display: "grid", placeItems: "center", flexShrink: 0 }}><Icon name="link" size={16} style={{ color: "#fff" }} /></span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontWeight: 800, fontSize: 14.5, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", color: "var(--ink)" }}>{title || "LTI course"}</div>
            <div style={{ fontSize: 11.5, color: "var(--ink-3)" }}>External course · launched securely over LTI</div>
          </div>
          <button className="btn btn-pri btn-sm" onClick={openTab} style={{ background: color, borderColor: color, flexShrink: 0 }}><Icon name="external" size={13} />Open in new tab</button>
          <button className="btn btn-ghost btn-sm" onClick={onClose} style={{ flexShrink: 0 }}><Icon name="x" size={14} />Close</button>
        </div>

        {/* body */}
        {framed ?
        <div style={{ flex: 1, minHeight: 0, position: "relative", background: "#f4f5f8" }}>
          <iframe key={frameUrl} src={frameUrl} title={title || "LTI course"} onLoad={() => setLoaded(true)}
            style={{ width: "100%", height: "100%", border: "none", display: "block", background: "#fff" }} />
          {slow && !loaded &&
          <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", background: "rgba(244,245,248,.96)", padding: 30, textAlign: "center" }}>
            <div>
              <div style={{ fontSize: 15, fontWeight: 700, color: "var(--ink)", marginBottom: 8 }}>This course can't be shown inside LearnALot</div>
              <div style={{ fontSize: 13, color: "var(--ink-2)", lineHeight: 1.55, maxWidth: 440, margin: "0 auto 16px" }}>The provider only allows it to open in its own window. Use the button below — you're already signed in to it.</div>
              <button className="btn btn-pri" onClick={openTab} style={{ background: color, borderColor: color }}><Icon name="external" size={15} />Open the course in a new tab</button>
            </div>
          </div>}
        </div> :
        <div style={{ flex: 1, display: "grid", placeItems: "center", padding: 30, textAlign: "center" }}>
          <div>
            <span style={{ width: 54, height: 54, borderRadius: 14, background: color + "18", display: "grid", placeItems: "center", margin: "0 auto 16px" }}><Icon name="external" size={26} style={{ color: color }} /></span>
            <div style={{ fontFamily: "var(--display)", fontWeight: 800, fontSize: 19, color: "var(--ink)", marginBottom: 8 }}>Opening in a new tab…</div>
            <div style={{ fontSize: 13.5, color: "var(--ink-2)", lineHeight: 1.6, maxWidth: 460, margin: "0 auto 20px" }}>The course opens securely in a new tab — you're signed in automatically, no separate password needed. If your browser blocked the pop-up, use the button below.</div>
            <div style={{ display: "flex", gap: 10, justifyContent: "center", flexWrap: "wrap" }}>
              <button className="btn btn-pri" onClick={openTab} style={{ background: color, borderColor: color }}><Icon name="external" size={15} />Open in new tab</button>
              <button className="btn btn-ghost" onClick={() => { setSlow(false); setLoaded(false); setFramed(true); }}><Icon name="grid" size={15} />Show it here instead</button>
            </div>
          </div>
        </div>}
      </div>
    </div>,
    document.body
  );
}

window.LtiLaunch = LtiLaunch;
