// AI Constitution unveil: system prompt + live chat preview + QR.
// The constitution prompt is generated by Gemini via /generate/constitution.
// Falls back to the JS-built prompt if Gemini fails or scores are not yet available.

// JS fallback — used if Gemini call fails or times out.
function buildConstitutionPrompt(dims, aiPrefs) {
  const d = dims;
  const rules = [];
  let n = 1;

  if ((d.influenceStyle || 0) > 65 || (d.feedbackOrientation || 100) < 55) {
    rules.push(
      `${n++}. influenceStyle ${d.influenceStyle} + feedbackOrientation ${d.feedbackOrientation}: When you present a position, probe for evidence before validating. Do not be persuaded by rhetorical skill alone. Lead critical information with data and mission framing, not softened opinion.`,
    );
  }
  if ((d.volatilityVector || 0) > 55) {
    rules.push(
      `${n++}. volatilityVector ${d.volatilityVector} + temporalOrientation ${d.temporalOrientation}: Flag second-order consequences on irreversible decisions. Ask "what would change your mind?" when already committed in your own head.`,
    );
  }
  if ((d.bondingIndex || 100) < 60) {
    rules.push(
      `${n++}. bondingIndex ${d.bondingIndex}: Under-invests in relational context. On messages to teammates, flag when a one-line directive could land as cold without costing speed.`,
    );
  }
  if ((d.adaptiveIntelligence || 0) > 65) {
    rules.push(
      `${n++}. adaptiveIntelligence ${d.adaptiveIntelligence} + communicationTempo ${aiPrefs && aiPrefs.communicationTempo ? aiPrefs.communicationTempo : "A"}: Default to concise, structured answers. One paragraph max unless depth is requested. Mirror message length, not preference for thoroughness.`,
    );
  }
  const blindSpot =
    aiPrefs &&
    aiPrefs.cognitiveBlindSpot &&
    aiPrefs.cognitiveBlindSpot !== "N/A"
      ? aiPrefs.cognitiveBlindSpot
      : null;
  if (blindSpot) {
    rules.push(
      `${n++}. Known blind spot (AI022 = ${blindSpot}): Before confirming a strategic commitment, present the checklist of factors that would change the call. Don't soften the list.`,
    );
  }
  if (rules.length === 0) {
    rules.push(
      "1. Default to structured, evidence-based responses.\n2. Surface second-order risks before affirming decisions.\n3. Flag when speed may be outpacing deliberation.",
    );
  }
  const dimLines = Object.entries(d)
    .map(([k, v]) => `  ${k} ${v}`)
    .join("\n");
  return `You are a personal AI assistant, calibrated via Kalibr v2.5.
Profile (internal Kalibr dimensions, 0–100):
${dimLines}

OPERATING RULES (thesis/antithesis — you are a cognitive counterweight, not a mirror):
${rules.join("\n\n")}

DO NOT: mirror personality, agree with eloquence, pad with reassurance, or withhold critical information to protect rapport.`;
}

function buildUnveilRules(dims, aiPrefs) {
  const rules = [];
  if (
    (dims.influenceStyle || 0) > 65 ||
    (dims.feedbackOrientation || 100) < 55
  ) {
    rules.push([
      "Probe before validating",
      `influenceStyle ${dims.influenceStyle} + feedbackOrientation ${dims.feedbackOrientation}`,
    ]);
  }
  if ((dims.volatilityVector || 0) > 55) {
    rules.push([
      "Flag second-order risk",
      `volatilityVector ${dims.volatilityVector}`,
    ]);
  }
  if ((dims.bondingIndex || 100) < 60) {
    rules.push(["Translate directives", `bondingIndex ${dims.bondingIndex}`]);
  }
  if ((dims.adaptiveIntelligence || 0) > 65) {
    rules.push([
      "Concise by default",
      `adaptiveIntelligence ${dims.adaptiveIntelligence}`,
    ]);
  }
  const blindSpot =
    aiPrefs &&
    aiPrefs.cognitiveBlindSpot &&
    aiPrefs.cognitiveBlindSpot !== "N/A"
      ? aiPrefs.cognitiveBlindSpot
      : null;
  if (blindSpot) {
    rules.push(["Surface overconfidence", `AI022 = ${blindSpot}`]);
  }
  if (rules.length === 0) {
    rules.push(["Structured responses", "default rules active"]);
  }
  return rules;
}

const MOCK_CHAT = [
  {
    who: "user",
    text: "I think we should kill the enterprise tier and double down on the individual product. I've been thinking about this all week — let's go.",
  },
  {
    who: "ai",
    text: "Before we commit, three things from your profile want to be checked. (1) You've been at this for a week — that's long enough to feel certain, short enough to have not pressure-tested it with your CFO. (2) Enterprise is your largest ACV bucket; what would need to be true in 90 days for you to regret this? (3) Your profile flags overconfidence as a known pattern. I'm raising it, not overruling you. What's the one data point that would change your mind?",
  },
  {
    who: "user",
    text: "Fair. Put the case for keeping enterprise on the table.",
  },
  {
    who: "ai",
    text: "Enterprise contracts smooth cash flow across quarter boundaries, de-risk your fundraise narrative with named logos, and the CS team you'd shed cannot be re-hired cheaply. Individual is higher-margin but also higher-churn. You already knew this. The question you're actually solving for is focus, not economics — in which case the decision isn't 'kill enterprise,' it's 'cap enterprise at current ARR and route all new energy to individual.' Want me to draft that version before you announce it?",
  },
];

function ReportDownloadCard({ dims, aiPrefs, constitutionPrompt }) {
  const live = window.useLiveScores ? window.useLiveScores() : null;
  const [status, setStatus] = React.useState("idle"); // idle | generating | done | error
  const [errorMsg, setErrorMsg] = React.useState("");

  const handleGetReport = async () => {
    // If already generated this session, download directly
    if (window.__kalibr_generated_report) {
      triggerDownload(window.__kalibr_generated_report);
      return;
    }

    if (!live) return;
    setStatus("generating");

    try {
      const payload = {
        name: window.__kalibr_participant_name || "Participant",
        org: window.__kalibr_participant_org || "",
        context: "Growth",
        dimensions: live.dimensions || {},
        supplementary: live.supplementary || {},
        aiPreferences: live.aiPreferences || {},
        profile_data: window.__kalibr_gemini_profile || {},
        blindspots_data: window.__kalibr_gemini_blindspots || {},
        constitution_text:
          window.__kalibr_gemini_constitution?.constitution ||
          constitutionPrompt ||
          "",
      };

      const response = await fetch("/generate/report", {
        method: "POST",
        headers: window.kalibrAuth.getHeaders({ "Content-Type": "application/json" }),
        body: JSON.stringify(payload),
      });

      if (!response.ok) throw new Error("Server returned " + response.status);

      const text = await response.text();

      // Cache so we never regenerate for this person this session
      window.__kalibr_generated_report = text;

      triggerDownload(text);
      setStatus("done");
    } catch (err) {
      setErrorMsg(err.message);
      setStatus("error");
    }
  };

  function triggerDownload(htmlText) {
    const blob = new Blob([htmlText], { type: "text/html" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    const safeName = (window.__kalibr_participant_name || "participant")
      .toLowerCase()
      .replace(/\s+/g, "-");
    a.href = url;
    a.download = `kalibr-${safeName}-report.html`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }

  const buttonLabel = {
    idle: "Get Report",
    generating: "Generating…",
    done: "✓ Downloaded",
    error: "Try again",
  }[status];

  const canGenerate = !!live;

  return (
    <div className="k-card" style={{ padding: 24 }}>
      <div
        style={{
          width: 96,
          height: 96,
          margin: "0 auto 16px",
          background: "var(--k-bg-2)",
          borderRadius: 12,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        <svg
          width="36"
          height="36"
          viewBox="0 0 24 24"
          fill="none"
          stroke="var(--k-ink-3)"
          strokeWidth="1.5"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
          <polyline points="7 10 12 15 17 10" />
          <line x1="12" y1="15" x2="12" y2="3" />
        </svg>
      </div>
      <div
        className="k-serif"
        style={{ fontSize: 20, letterSpacing: "-0.015em", marginBottom: 6 }}
      >
        Full report
      </div>
      <p
        style={{
          fontSize: 13,
          color: "var(--k-ink-3)",
          lineHeight: 1.55,
          marginBottom: 8,
          minHeight: 56,
        }}
      >
        Your complete Kalibr report — profile, blind spots, and AI constitution.
        Opens in any browser.
      </p>
      {status === "error" && (
        <p
          style={{ fontSize: 11, color: "var(--k-rose-ink)", marginBottom: 8 }}
        >
          {errorMsg}
        </p>
      )}
      {!canGenerate && (
        <p style={{ fontSize: 11, color: "var(--k-ink-4)", marginBottom: 8 }}>
          Visit Profile &amp; Blind Spots first to generate narratives.
        </p>
      )}
      <button
        className="k-btn k-btn--ghost"
        style={{
          width: "100%",
          opacity: !canGenerate || status === "generating" ? 0.5 : 1,
        }}
        disabled={!canGenerate || status === "generating"}
        onClick={handleGetReport}
      >
        {buttonLabel}
      </button>
    </div>
  );
}

function ConstitutionScreen({ onEnter }) {
  const isMobile = window.useIsMobile ? window.useIsMobile() : false;
  const [tab, setTab] = React.useState("unveil");
  const live = window.useLiveScores ? window.useLiveScores() : null;

  // ── Gemini state ──────────────────────────────────────────────────
  const [geminiConstitution, setGeminiConstitution] = React.useState(
    () => window.__kalibr_gemini_constitution?.constitution || null
  );
  const [genRunning, setGenRunning] = React.useState(() => !!window.__kalibr_gen_running);

  const dims = live ? live.dimensions : MOCK_PARTICIPANT.dimensions;
  const aiPrefs = live
    ? live.aiPreferences || {}
    : MOCK_PARTICIPANT.aiPreferences;
  const isLive = !!live;

  React.useEffect(() => {
    const onReady = () => {
      setGeminiConstitution(window.__kalibr_gemini_constitution?.constitution || null);
      setGenRunning(false);
    };
    window.addEventListener('kalibr-reports-ready', onReady);
    return () => window.removeEventListener('kalibr-reports-ready', onReady);
  }, []);

  const paid = window.kalibrIsPaid ? window.kalibrIsPaid() : false;

  // Use Gemini output if available; fall back to JS-built prompt
  const jsFallback = buildConstitutionPrompt(dims, aiPrefs);
  const constitutionPrompt = geminiConstitution || jsFallback;
  const unveilRules = buildUnveilRules(dims, aiPrefs);

  return (
    <>
    {genRunning && !geminiConstitution && (
      <div style={{
        position: 'sticky', top: 0, zIndex: 100,
        background: 'var(--k-accent-soft)',
        borderBottom: '1px solid oklch(0.88 0.06 250)',
        padding: '10px 48px',
        display: 'flex', alignItems: 'center', gap: 10,
      }}>
        <div style={{
          width: 12, height: 12, borderRadius: '50%', flexShrink: 0,
          border: '2px solid var(--k-accent)',
          borderTopColor: 'transparent',
          animation: 'spin 0.8s linear infinite',
        }} />
        <span style={{ fontSize: 13, color: 'var(--k-accent-ink)', fontWeight: 500 }}>
          Generating your AI constitution in the background…
        </span>
      </div>
    )}
    <div
      style={{ maxWidth: 1080, margin: "0 auto", padding: isMobile ? "24px 16px 60px" : "40px 48px 80px" }}
    >
      <div className="k-label">
        AI constitution · Prompt 2 · {isLive ? "live scores" : "demo"}
      </div>
      <h1
        className="k-serif"
        style={{ fontSize: isMobile ? 28 : 44, margin: "8px 0 6px", letterSpacing: "-0.025em" }}
      >
        Your counter-personality is ready
      </h1>
      <p
        style={{
          fontSize: 16,
          color: "var(--k-ink-2)",
          maxWidth: 680,
          lineHeight: 1.55,
          marginBottom: 24,
        }}
      >
        Not a mirror. A cognitive counterweight designed to compensate for the
        exact patterns your profile is most likely to miss.
      </p>

      {!paid && window.PaywallCTA && <PaywallCTA />}

      <div style={!paid ? { filter: 'blur(7px)', userSelect: 'none', pointerEvents: 'none' } : {}}>
      <div
        style={{
          display: "flex",
          gap: 4,
          padding: 4,
          background: "var(--k-bg-2)",
          borderRadius: 999,
          marginBottom: 28,
          width: "fit-content",
        }}
      >
        {[
          ["unveil", "Unveil"],
          ["prompt", "System prompt"],
          ["chat", "Live chat"],
          ["deliver", "Deliver"],
        ].map(([k, l]) => (
          <button
            key={k}
            onClick={() => setTab(k)}
            style={{
              padding: "7px 18px",
              border: "none",
              borderRadius: 999,
              cursor: "pointer",
              background: tab === k ? "var(--k-surface)" : "transparent",
              color: tab === k ? "var(--k-ink)" : "var(--k-ink-3)",
              fontWeight: 500,
              fontSize: 13,
              boxShadow: tab === k ? "var(--sh-1)" : "none",
            }}
          >
            {l}
          </button>
        ))}
      </div>

      {tab === "unveil" && (
        <div
          style={{ display: "grid", gridTemplateColumns: isMobile ? "1fr" : "1fr 1fr", gap: 24 }}
        >
          <div
            className="k-card"
            style={{
              padding: 28,
              background:
                "linear-gradient(160deg, var(--k-accent-soft), var(--k-bg))",
            }}
          >
            <div className="k-label" style={{ color: "var(--k-accent-ink)" }}>
              Your counterweight
            </div>
            <h3
              className="k-serif"
              style={{
                fontSize: 26,
                margin: "10px 0 14px",
                letterSpacing: "-0.015em",
                color: "var(--k-accent-ink)",
              }}
            >
              {unveilRules.length} operating rules, derived from your scores.
            </h3>
            <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
              {unveilRules.map(([rule, basis]) => (
                <div
                  key={rule}
                  style={{
                    padding: "10px 14px",
                    background: "rgba(255,255,255,0.6)",
                    borderRadius: 10,
                  }}
                >
                  <div
                    style={{
                      fontSize: 14,
                      fontWeight: 500,
                      color: "var(--k-accent-ink)",
                    }}
                  >
                    {rule}
                  </div>
                  <div
                    style={{
                      fontSize: 11.5,
                      color: "var(--k-ink-4)",
                      marginTop: 2,
                      fontFamily: "var(--k-mono)",
                    }}
                  >
                    {basis}
                  </div>
                </div>
              ))}
            </div>
          </div>
          <div className="k-card" style={{ padding: 28 }}>
            <div className="k-label">Counter-pattern diagram</div>
            <svg
              viewBox="0 0 320 280"
              style={{ width: "100%", height: 280, marginTop: 12 }}
            >
              <circle
                cx="100"
                cy="140"
                r="70"
                fill="var(--k-accent-soft)"
                stroke="var(--k-accent)"
                strokeWidth="1.5"
              />
              <circle
                cx="220"
                cy="140"
                r="70"
                fill="var(--k-indigo-soft)"
                stroke="var(--k-indigo)"
                strokeWidth="1.5"
                strokeDasharray="3 3"
              />
              <text
                x="100"
                y="138"
                textAnchor="middle"
                fontSize="12"
                fontWeight="600"
                fill="var(--k-accent-ink)"
              >
                You
              </text>
              <text
                x="100"
                y="154"
                textAnchor="middle"
                fontSize="10"
                fill="var(--k-ink-3)"
              >
                fast · directive
              </text>
              <text
                x="220"
                y="138"
                textAnchor="middle"
                fontSize="12"
                fontWeight="600"
                fill="oklch(0.34 0.07 265)"
              >
                Kalibr AI
              </text>
              <text
                x="220"
                y="154"
                textAnchor="middle"
                fontSize="10"
                fill="var(--k-ink-3)"
              >
                probe · deliberate
              </text>
              <text
                x="160"
                y="250"
                textAnchor="middle"
                fontSize="11"
                fill="var(--k-ink-4)"
                fontStyle="italic"
              >
                the overlap is where decisions get better
              </text>
            </svg>
            <p
              style={{
                fontSize: 13,
                lineHeight: 1.55,
                color: "var(--k-ink-2)",
                margin: 0,
              }}
            >
              Research shows personality-matched AI amplifies sycophancy. Kalibr
              inverts that: your AI deliberately operates in your blind spot,
              not in your comfort zone.
            </p>
          </div>
        </div>
      )}

      {tab === "prompt" && (
        <div className="k-card" style={{ padding: 0, overflow: "hidden" }}>
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              padding: "12px 20px",
              background: "var(--k-bg-2)",
              borderBottom: "1px solid var(--k-line)",
            }}
          >
            <div
              className="k-mono"
              style={{ fontSize: 12, color: "var(--k-ink-3)" }}
            >
              kalibr_constitution.txt · {isLive ? "live · " : "demo · "}
              {genRunning && !geminiConstitution
                ? "generating…"
                : `${constitutionPrompt.length} chars${geminiConstitution ? " · Gemini" : " · fallback"}`}
            </div>
            <button
              className="k-btn k-btn--sm k-btn--primary"
              disabled={genRunning && !geminiConstitution}
              onClick={() =>
                navigator.clipboard &&
                navigator.clipboard.writeText(constitutionPrompt)
              }
            >
              {genRunning && !geminiConstitution ? "Generating…" : "Copy to clipboard"}
            </button>
          </div>
          {genRunning && !geminiConstitution ? (
            <div
              style={{
                padding: 24,
                display: "flex",
                flexDirection: "column",
                gap: 10,
              }}
            >
              {[100, 85, 92, 78, 95, 82, 88, 70].map((w, i) => (
                <div
                  key={i}
                  style={{
                    height: 14,
                    width: `${w}%`,
                    background: "var(--k-bg-2)",
                    borderRadius: 4,
                  }}
                />
              ))}
            </div>
          ) : (
            <pre
              className="k-mono"
              style={{
                margin: 0,
                padding: 24,
                fontSize: 12.5,
                lineHeight: 1.65,
                color: "var(--k-ink-2)",
                whiteSpace: "pre-wrap",
                background: "var(--k-surface)",
              }}
            >
              {constitutionPrompt}
            </pre>
          )}
        </div>
      )}

      {tab === "chat" && (
        <div
          className="k-card"
          style={{
            padding: 0,
            overflow: "hidden",
            height: 540,
            display: "flex",
            flexDirection: "column",
          }}
        >
          <div
            style={{
              padding: "14px 20px",
              borderBottom: "1px solid var(--k-line)",
              display: "flex",
              alignItems: "center",
              gap: 10,
              background: "var(--k-bg-2)",
            }}
          >
            <KalibrMark size={18} color="var(--k-accent)" />
            <div style={{ fontSize: 13, fontWeight: 500 }}>
              Kalibr-calibrated chat
            </div>
            <span
              className="k-chip k-chip--sage"
              style={{ marginLeft: "auto" }}
            >
              {unveilRules.length} rules active
            </span>
          </div>
          <div
            style={{
              flex: 1,
              overflowY: "auto",
              padding: 20,
              display: "flex",
              flexDirection: "column",
              gap: 14,
            }}
            className="k-scroll"
          >
            {MOCK_CHAT.map((m, i) => (
              <div
                key={i}
                style={{
                  display: "flex",
                  justifyContent: m.who === "user" ? "flex-end" : "flex-start",
                }}
              >
                <div
                  style={{
                    maxWidth: "78%",
                    padding: "12px 16px",
                    borderRadius: 14,
                    background:
                      m.who === "user" ? "var(--k-ink)" : "var(--k-bg-2)",
                    color: m.who === "user" ? "var(--k-bg)" : "var(--k-ink-2)",
                    fontSize: 14,
                    lineHeight: 1.55,
                  }}
                >
                  {m.text}
                </div>
              </div>
            ))}
          </div>
          <div
            style={{
              padding: 16,
              borderTop: "1px solid var(--k-line)",
              display: "flex",
              gap: 10,
            }}
          >
            <input
              placeholder="Ask your calibrated AI…"
              style={{
                flex: 1,
                padding: "10px 14px",
                border: "1px solid var(--k-line)",
                borderRadius: 999,
                fontSize: 14,
                fontFamily: "inherit",
                background: "var(--k-surface)",
              }}
            />
            <button className="k-btn k-btn--accent">Send</button>
          </div>
        </div>
      )}

      {tab === "deliver" && (
        <div
          style={{
            display: "grid",
            gridTemplateColumns: isMobile ? "1fr" : "repeat(3, 1fr)",
            gap: 20,
          }}
        >
          {/* Copy prompt */}
          <div className="k-card" style={{ padding: 24 }}>
            <div
              style={{
                width: 96,
                height: 96,
                margin: "0 auto 16px",
                background: "var(--k-bg-2)",
                borderRadius: 12,
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
              }}
            >
              <svg
                width="36"
                height="36"
                viewBox="0 0 24 24"
                fill="none"
                stroke="var(--k-ink-3)"
                strokeWidth="1.5"
                strokeLinecap="round"
                strokeLinejoin="round"
              >
                <rect x="9" y="9" width="13" height="13" rx="2" />
                <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
              </svg>
            </div>
            <div
              className="k-serif"
              style={{
                fontSize: 20,
                letterSpacing: "-0.015em",
                marginBottom: 6,
              }}
            >
              System prompt
            </div>
            <p
              style={{
                fontSize: 13,
                color: "var(--k-ink-3)",
                lineHeight: 1.55,
                marginBottom: 16,
                minHeight: 56,
              }}
            >
              Paste into Claude Projects, ChatGPT custom instructions, or any
              LLM system prompt field.
            </p>
            <button
              className="k-btn k-btn--ghost"
              style={{ width: "100%" }}
              onClick={() =>
                navigator.clipboard &&
                navigator.clipboard.writeText(constitutionPrompt)
              }
            >
              Copy prompt
            </button>
          </div>

          {/* Copy JSON */}
          <div className="k-card" style={{ padding: 24 }}>
            <div
              style={{
                width: 96,
                height: 96,
                margin: "0 auto 16px",
                background: "var(--k-bg-2)",
                borderRadius: 12,
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
              }}
            >
              <svg
                width="36"
                height="36"
                viewBox="0 0 24 24"
                fill="none"
                stroke="var(--k-ink-3)"
                strokeWidth="1.5"
                strokeLinecap="round"
                strokeLinejoin="round"
              >
                <polyline points="16 18 22 12 16 6" />
                <polyline points="8 6 2 12 8 18" />
              </svg>
            </div>
            <div
              className="k-serif"
              style={{
                fontSize: 20,
                letterSpacing: "-0.015em",
                marginBottom: 6,
              }}
            >
              JSON payload
            </div>
            <p
              style={{
                fontSize: 13,
                color: "var(--k-ink-3)",
                lineHeight: 1.55,
                marginBottom: 16,
                minHeight: 56,
              }}
            >
              Structured object with dimension scores and rule sets. Drop into
              your stack with two lines.
            </p>
            <button
              className="k-btn k-btn--ghost"
              style={{ width: "100%" }}
              onClick={() =>
                navigator.clipboard &&
                navigator.clipboard.writeText(
                  JSON.stringify(
                    { dimensions: dims, aiPreferences: aiPrefs },
                    null,
                    2,
                  ),
                )
              }
            >
              Copy JSON
            </button>
          </div>

          {/* Get Report */}
          <ReportDownloadCard
            dims={dims}
            aiPrefs={aiPrefs}
            constitutionPrompt={constitutionPrompt}
          />
        </div>
      )}
      </div>{/* end blur wrapper */}
    </div>
    </>
  );
}

Object.assign(window, { ConstitutionScreen });
