// SQSEO Link Opportunities — deterministic internal-linking recommender.
// Reads the site scan's profile.linkGraph (server/internallinks.ts): for each
// page, the topically-nearest pages it does NOT already link to, each with a
// drop-in anchor that already appears in the copy — plus orphan pages with too
// little internal linking. 100% software, no LLM/tokens. Registered on
// window.LTQ.LinkOpportunities.
(function init() {
  if (!window.LongtailIQDesignSystem_ae8f12 || !window.LTQ || !window.LTQ.useApi || !window.LTQ.SectionTitle) { return setTimeout(init, 30); }
  const React = window.React;
  const DS = window.LongtailIQDesignSystem_ae8f12;
  const { Card, Icon, Badge } = DS;
  const { SectionTitle, useApi, EmptyState } = window.LTQ;
  const t = (k, v) => (window.LTQ.t ? window.LTQ.t(k, v) : k);

  // Short, readable path (drop protocol + host) for a crawled URL.
  const pathOf = (u) => { try { const x = new URL(u); return (x.pathname + x.search) || "/"; } catch (e) { return u; } };

  function Stat({ icon, label, value }) {
    const Odometer = window.LTQ.Odometer;
    const ns = { fontFamily: "var(--font-mono)", fontSize: 24, fontWeight: 700, letterSpacing: "-0.02em", color: "var(--text-strong)" };
    return (
      <Card pad={16} className="lt-card-3d" style={{ display: "flex", flexDirection: "column", gap: 9 }}>
        <span style={{ width: 30, height: 30, borderRadius: 9, display: "grid", placeItems: "center", background: "var(--ink-50)", color: "var(--text-muted)" }}>
          <Icon name={icon} size={16} />
        </span>
        <div>
          {Odometer ? <Odometer value={Number(value) || 0} className="lt-num" style={ns} /> : <div className="lt-num" style={ns}>{value}</div>}
          <div style={{ fontSize: 12.5, color: "var(--text-muted)", fontWeight: 600 }}>{label}</div>
        </div>
      </Card>
    );
  }

  // Match strength bar (0..1) — GPU-friendly scaleX spring fill on mount.
  function MatchBar({ score, delay }) {
    const pct = Math.round(score * 100);
    const reduced = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const [grown, setGrown] = React.useState(reduced);
    React.useEffect(() => {
      if (reduced) return;
      const id = setTimeout(() => setGrown(true), (delay || 0) + 80);
      return () => clearTimeout(id);
    }, []);
    return (
      <span style={{ display: "inline-flex", alignItems: "center", gap: 8, flex: "none" }}>
        <span style={{ width: 52, height: 5, borderRadius: 999, background: "var(--ink-100)", overflow: "hidden" }}>
          <span style={{ display: "block", height: "100%", width: pct + "%", borderRadius: 999, background: "var(--ink-900)",
            transformOrigin: "left", transform: grown ? "scaleX(1)" : "scaleX(0)", transition: reduced ? "none" : "transform 0.8s var(--ease-spring)" }} />
        </span>
        <span className="lt-num" style={{ width: 30, textAlign: "right", fontFamily: "var(--font-mono)", fontSize: 11.5, fontWeight: 600, color: "var(--text-muted)" }}>{pct}%</span>
      </span>
    );
  }

  function AnchorChip({ text, live }) {
    return (
      <span style={{ display: "inline-flex", alignItems: "center", gap: 6, padding: "3px 9px", borderRadius: 7,
        border: "1px solid " + (live ? "var(--accent-200,var(--accent-100))" : "var(--border-subtle)"),
        background: live ? "var(--accent-50,#ecfdf5)" : "var(--ink-50)", maxWidth: 260, overflow: "hidden" }}>
        {live && <span style={{ width: 5, height: 5, borderRadius: 999, background: "var(--accent-500)", flex: "none" }} />}
        <span style={{ fontSize: 12.5, fontWeight: 600, color: live ? "var(--accent-700,var(--accent-600))" : "var(--text-body)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{text}</span>
      </span>
    );
  }

  function Suggestion({ s, delay }) {
    return (
      <div style={{ display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap", padding: "11px 0", borderTop: "1px solid var(--border-subtle)" }}>
        <AnchorChip text={s.anchor} live={s.anchorInSource} />
        <Icon name="arrow-right" size={14} style={{ color: "var(--text-faint)", flex: "none" }} />
        <a href={s.target} target="_blank" rel="noopener noreferrer" title={s.target}
          style={{ flex: 1, minWidth: 160, display: "inline-flex", flexDirection: "column", gap: 1, textDecoration: "none" }}>
          <span style={{ fontSize: 13.5, fontWeight: 600, color: "var(--text-strong)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{s.targetTitle}</span>
          <span className="lt-num" style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--text-faint)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{pathOf(s.target)}</span>
        </a>
        {s.sharedTerms && s.sharedTerms.length > 0 && (
          <span style={{ fontSize: 11.5, color: "var(--text-faint)", maxWidth: 220, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
            {t("links.shared")}: {s.sharedTerms.slice(0, 3).join(", ")}
          </span>
        )}
        <MatchBar score={s.score} delay={delay} />
      </div>
    );
  }

  function PageCard({ r, delay }) {
    return (
      <Card pad={0} className="lt-card-3d fx-enter" style={{ overflow: "hidden", "--enter-delay": (delay || 0) + "ms" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap", padding: "14px 18px", background: "var(--ink-50)", borderBottom: "1px solid var(--border-subtle)" }}>
          <Icon name="file-text" size={15} style={{ color: "var(--text-faint)", flex: "none" }} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13.5, fontWeight: 700, color: "var(--text-strong)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{r.title}</div>
            <a href={r.url} target="_blank" rel="noopener noreferrer" className="lt-num" style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--text-faint)", textDecoration: "none" }}>{pathOf(r.url)}</a>
          </div>
          <Badge tone="neutral" variant="soft">{t("links.inbound", { n: r.inbound })}</Badge>
          <Badge tone="neutral" variant="soft">{t("links.outbound", { n: r.outbound })}</Badge>
        </div>
        <div style={{ padding: "2px 18px 12px" }}>
          {r.suggestions.map((s, i) => <Suggestion key={s.target} s={s} delay={i * 45} />)}
        </div>
      </Card>
    );
  }

  function OrphanCard({ o, delay }) {
    return (
      <Card pad={16} className="lt-card-3d fx-enter" style={{ display: "flex", flexDirection: "column", gap: 10, "--enter-delay": (delay || 0) + "ms" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <span style={{ width: 30, height: 30, borderRadius: 9, flex: "none", display: "grid", placeItems: "center", background: "var(--amber-50,#fffbeb)", color: "var(--amber-600,#d97706)" }}>
            <Icon name="unlink" size={15} />
          </span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13.5, fontWeight: 700, color: "var(--text-strong)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{o.title}</div>
            <a href={o.url} target="_blank" rel="noopener noreferrer" className="lt-num" style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--text-faint)", textDecoration: "none" }}>{pathOf(o.url)}</a>
          </div>
          <Badge tone={o.inbound === 0 ? "amber" : "neutral"} variant="soft" dot>{t("links.inbound", { n: o.inbound })}</Badge>
        </div>
        {o.linkFrom && o.linkFrom.length > 0 && (
          <div style={{ borderTop: "1px solid var(--border-subtle)", paddingTop: 10 }}>
            <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: "0.05em", textTransform: "uppercase", color: "var(--text-faint)", marginBottom: 8 }}>{t("links.link_from")}</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
              {o.linkFrom.map((lf) => (
                <div key={lf.url} style={{ display: "flex", alignItems: "center", gap: 9, flexWrap: "wrap" }}>
                  <a href={lf.url} target="_blank" rel="noopener noreferrer" style={{ fontSize: 12.5, fontWeight: 600, color: "var(--text-body)", textDecoration: "none", maxWidth: 240, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{lf.title}</a>
                  <Icon name="arrow-right" size={13} style={{ color: "var(--text-faint)", flex: "none" }} />
                  <AnchorChip text={lf.anchor} live />
                </div>
              ))}
            </div>
          </div>
        )}
      </Card>
    );
  }

  const Skel = ({ h = 88 }) => <span className="lt-shimmer" style={{ display: "block", height: h, borderRadius: 12, background: "var(--ink-100)" }} />;

  function LinkOpportunities() {
    const { loading, data } = useApi("/api/site-intel/profile");
    const profile = data && data.profile;
    const g0 = profile && profile.linkGraph;
    // Profiles scanned before this feature may carry a partial linkGraph.
    const g = g0 ? { ...g0, reports: g0.reports || [], orphans: g0.orphans || [] } : g0;

    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
        <SectionTitle eyebrow={t("links.eyebrow")} title={t("nav.links")} sub={t("links.sub")} />

        {loading && (
          <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 12 }}>{[0, 1, 2, 3].map((i) => <Skel key={i} h={92} />)}</div>
            <Skel h={140} /><Skel h={140} />
          </div>
        )}

        {!loading && !g && (
          <Card pad={0}>
            <EmptyState icon="link" sq="search" title={t("links.empty_title")} body={t("links.empty_body")} />
          </Card>
        )}

        {!loading && g && (
          <>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 12 }} className="lt-stat-grid">
              <Stat icon="file-search" label={t("links.stat_pages")} value={g.pages} />
              <Stat icon="link" label={t("links.stat_links")} value={g.totalInternalLinks} />
              <Stat icon="git-compare" label={t("links.stat_ops")} value={g.opportunityCount} />
              <Stat icon="unlink" label={t("links.stat_orphans")} value={g.orphanCount} />
            </div>

            {g.reports.length > 0 ? (
              <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
                <div>
                  <h3 style={{ fontSize: 15, fontWeight: 700, color: "var(--text-strong)" }}>{t("links.ops_title")}</h3>
                  <p style={{ fontSize: 12.5, color: "var(--text-muted)", marginTop: 3 }}>{t("links.ops_hint")}</p>
                </div>
                {g.reports.map((r, i) => <PageCard key={r.url} r={r} delay={Math.min(i, 8) * 40} />)}
              </div>
            ) : (
              <Card pad={0}><EmptyState icon="check-circle-2" sq="idle" title={t("links.none_title")} body={t("links.none_body")} /></Card>
            )}

            {g.orphans.length > 0 && (
              <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
                <div>
                  <h3 style={{ fontSize: 15, fontWeight: 700, color: "var(--text-strong)" }}>{t("links.orphans_title")}</h3>
                  <p style={{ fontSize: 12.5, color: "var(--text-muted)", marginTop: 3 }}>{t("links.orphans_hint")}</p>
                </div>
                <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill,minmax(340px,1fr))", gap: 12 }}>
                  {g.orphans.map((o, i) => <OrphanCard key={o.url} o={o} delay={Math.min(i, 8) * 40} />)}
                </div>
              </div>
            )}
          </>
        )}
      </div>
    );
  }
  window.LTQ.LinkOpportunities = LinkOpportunities;
})();
