// Billing UI: upgrade modal, post-checkout welcome toast, settings panel.
// Real state comes from ForgeDB.getBilling(); checkout/portal redirects via
// ForgeBilling. Mirrors the high-fidelity prototype in the design handoff.

const { useState: useStateBill, useEffect: useEffectBill } = React;

// 1 tailoring ≈ 33¢. Display math throughout the panel uses these constants.
const TAILORING_COST = 33;
const MONTHLY_BUDGET_TAILORINGS = 15; // = $5.00 / 33¢

// Reason → header copy. The same modal handles all four entry points
// (top-bar pill, "+ New base resume", "Buy credits", out-of-tailorings gate).
const UPGRADE_REASONS = {
  general: {
    eyebrow: "Upgrade",
    title: "Get five base resumes\nand monthly credits.",
    context: null,
  },
  addResume: {
    eyebrow: "Free limit reached",
    title: "Keep up to five\nbase resumes on Pro.",
    context: "You're using your one Free base resume. Pro lets you keep separate masters per role-shape — useful for career-changers and consultants.",
  },
  addCredits: {
    eyebrow: "Credits are a Pro thing",
    title: "Top-up credits\nrequire Pro.",
    context: "On Free, you can use the 2 signup tailorings or bring your own API key. Pro includes $5 of credits each month and unlocks $10 top-up packs.",
  },
  outOfTailorings: {
    eyebrow: "0 tailorings left",
    title: "Nice work —\nfancy a few more?",
    context: "You've used your signup tailorings. Add your own API key to keep going on Free, or upgrade to Pro for $5 of credits each month and room for 5 masters.",
  },
};

function UpgradeModal({ open, reason = "general", onClose }) {
  const [period, setPeriod] = useStateBill("monthly");
  const [loading, setLoading] = useStateBill(false);
  const [error, setError] = useStateBill(null);
  const r = UPGRADE_REASONS[reason] || UPGRADE_REASONS.general;

  useEffectBill(() => {
    if (!open) return;
    setError(null);
    setLoading(false);
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, onClose]);

  if (!open) return null;

  const price = period === "monthly" ? "15" : "12.50";
  const sub = period === "monthly" ? "per month, billed monthly" : "per month, billed $150/yr";

  const onContinue = async () => {
    setError(null);
    setLoading(true);
    try {
      await window.ForgeBilling.startCheckout(period);
      // Page is redirecting to Stripe; nothing else to do here.
    } catch (e) {
      setLoading(false);
      setError(e.message || "Couldn't start checkout");
    }
  };

  return (
    <div
      onClick={onClose}
      style={{
        position: "fixed", inset: 0, zIndex: 200,
        background: "rgba(7,8,6,0.66)",
        backdropFilter: "blur(6px)",
        WebkitBackdropFilter: "blur(6px)",
        display: "flex", alignItems: "center", justifyContent: "center",
        padding: 24,
        animation: "fadeIn 160ms ease",
      }}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        style={{
          width: "100%",
          maxWidth: 520,
          background: "var(--paper-3)",
          border: "1px solid var(--border)",
          borderRadius: 16,
          padding: "36px 36px 28px",
          boxShadow: "0 30px 80px rgba(0,0,0,0.55), 0 0 0 1px rgba(0,0,0,0.4)",
          position: "relative",
          fontFamily: "Inter, sans-serif",
          color: "var(--ink)",
        }}
      >
        <button
          onClick={onClose}
          aria-label="Close"
          style={{
            position: "absolute", top: 14, right: 14,
            width: 28, height: 28, borderRadius: 6,
            border: "1px solid var(--border)",
            background: "transparent", color: "var(--ink)",
            cursor: "pointer", display: "flex",
            alignItems: "center", justifyContent: "center",
          }}
        >
          {Icon.x}
        </button>

        <Eyebrow color="var(--accent)" style={{ marginBottom: 14 }}>— {r.eyebrow}</Eyebrow>
        <h2
          style={{
            fontFamily: "'Instrument Serif', Newsreader, serif",
            fontWeight: 400,
            fontSize: 38,
            lineHeight: 1.04,
            letterSpacing: "-0.015em",
            margin: "0 0 14px",
            whiteSpace: "pre-line",
            textWrap: "balance",
          }}
        >
          {r.title.split("\n").map((line, i, arr) => (
            <span key={i}>{line}{i < arr.length - 1 && <br />}</span>
          ))}
        </h2>
        {r.context && (
          <p style={{ fontSize: 14, color: "var(--muted)", lineHeight: 1.55, margin: "0 0 24px", maxWidth: 440 }}>
            {r.context}
          </p>
        )}

        <div style={{
          display: "inline-flex", padding: 3, borderRadius: 999,
          border: "1px solid var(--border)",
          background: "rgba(242,239,227,0.03)",
          marginBottom: 18,
        }}>
          {["monthly", "yearly"].map((p) => (
            <button
              key={p}
              onClick={() => setPeriod(p)}
              style={{
                appearance: "none", border: 0, cursor: "pointer",
                padding: "7px 14px", borderRadius: 999,
                background: period === p ? "var(--ink)" : "transparent",
                color: period === p ? "var(--paper-2)" : "var(--muted)",
                fontFamily: "Inter, sans-serif", fontSize: 12, fontWeight: 500,
                display: "inline-flex", alignItems: "center", gap: 6,
                transition: "all .15s",
              }}
            >
              {p === "monthly" ? "Monthly" : "Yearly"}
              {p === "yearly" && (
                <span style={{
                  fontFamily: "'JetBrains Mono', monospace",
                  fontSize: 9, letterSpacing: "0.08em",
                  background: "var(--accent)", color: "#14180A",
                  padding: "1px 5px", borderRadius: 3,
                  whiteSpace: "nowrap",
                }}>2&nbsp;MO&nbsp;FREE</span>
              )}
            </button>
          ))}
        </div>

        <div style={{
          display: "flex", alignItems: "baseline", gap: 8,
          padding: "14px 0", borderTop: "1px solid var(--border)", borderBottom: "1px solid var(--border)",
          marginBottom: 20,
        }}>
          <span style={{ fontFamily: "'Instrument Serif', serif", fontSize: 22, color: "var(--muted)", lineHeight: 1 }}>$</span>
          <span style={{ fontFamily: "'Instrument Serif', serif", fontSize: 52, lineHeight: 0.9, letterSpacing: "-0.02em" }}>{price}</span>
          <span style={{ fontSize: 13, color: "var(--muted)" }}>{sub}</span>
        </div>

        <ul style={{ listStyle: "none", padding: 0, margin: "0 0 24px", display: "grid", gridTemplateColumns: "1fr 1fr", gap: "10px 18px" }}>
          {[
            "5 base resumes",
            "$5 in credits each month",
            "Unlimited tailored versions",
            "$10 top-up packs, no expiry",
            "BYOK supported",
            "Cover letters + letterhead",
          ].map((f) => (
            <li key={f} style={{ display: "flex", gap: 9, alignItems: "center", fontSize: 13, color: "var(--ink)" }}>
              <span style={{
                width: 14, height: 14, borderRadius: 999,
                background: "color-mix(in oklab, var(--accent) 18%, transparent)",
                color: "var(--accent)",
                display: "inline-flex", alignItems: "center", justifyContent: "center",
                flexShrink: 0,
              }}>
                <svg width="8" height="8" viewBox="0 0 10 10" fill="none">
                  <path d="M2 5l2 2 4-5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </span>
              {f}
            </li>
          ))}
        </ul>

        {error && (
          <div style={{
            fontSize: 12, color: "#ff8e8e",
            background: "rgba(255,80,80,0.08)",
            border: "1px solid rgba(255,80,80,0.25)",
            borderRadius: 6, padding: "8px 10px", marginBottom: 10,
          }}>{error}</div>
        )}

        <button
          onClick={onContinue}
          disabled={loading}
          style={{
            width: "100%",
            padding: "13px 16px",
            border: "1px solid var(--accent)",
            borderRadius: 8,
            background: "var(--accent)",
            color: "#14180A",
            fontFamily: "Inter, sans-serif",
            fontSize: 14, fontWeight: 500,
            cursor: loading ? "wait" : "pointer",
            opacity: loading ? 0.7 : 1,
            display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 10,
            marginBottom: 14,
          }}
        >
          {loading ? "Redirecting…" : "Continue to checkout"}
          {!loading && (
            <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
              <path d="M2.5 7h9m0 0L8 3.5M11.5 7L8 10.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          )}
        </button>

        <div style={{
          display: "flex", alignItems: "center", justifyContent: "center", gap: 12,
          fontSize: 11, color: "var(--muted)", flexWrap: "wrap",
        }}>
          <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
            Secured by
            <svg width="40" height="16" viewBox="0 0 60 25" fill="none" style={{ opacity: 0.7 }}>
              <path d="M59.64 14.28h-8.06c.19 1.93 1.6 2.55 3.2 2.55 1.64 0 2.96-.37 4.05-.95v3.32a8.33 8.33 0 0 1-4.56 1.1c-4.01 0-6.83-2.5-6.83-7.48 0-4.19 2.39-7.52 6.3-7.52 3.92 0 5.96 3.28 5.96 7.5 0 .4-.04 1.26-.06 1.48zm-5.92-5.62c-1.03 0-2.17.73-2.17 2.58h4.25c0-1.85-1.07-2.58-2.08-2.58zM40.95 20.3c-1.44 0-2.32-.6-2.9-1.04l-.02 4.63-4.12.87V5.57h3.63l.21 1.03c.56-.52 1.58-1.3 3.18-1.3 2.85 0 5.53 2.56 5.53 7.3 0 5.18-2.65 7.7-5.51 7.7zM39.99 9.32c-.93 0-1.51.34-1.93.81l.02 6.41c.39.43.96.78 1.91.78 1.51 0 2.52-1.64 2.52-4.02 0-2.31-1.03-3.98-2.52-3.98zM30.83 5.84h4.14V20.3h-4.14V5.84zM30.83 1.27h4.14v3.36h-4.14V1.27zM26.27 20.3h-3.81V5.84h3.81v1.06c.96-.77 2.05-1.46 3.42-1.46v3.94c-1.31 0-3.42 1.13-3.42 2.69v8.23zM18.32 16.42c0 .96.33 1.36 1.07 1.36.5 0 1.32-.19 1.78-.43v3.46c-.65.32-1.96.71-3.32.71-2.81 0-4.4-1.45-4.4-4.15V4.96l4.04-.86.04 1.04h2.83v3.39h-2.83v6.95l.79-.06zM7.43 19.07c1.13 0 1.5-.43 1.5-.96 0-1.94-9.06-.86-9.06-7.36 0-2.89 2.46-5.6 6.78-5.6 1.84 0 3.79.36 5.16.78v3.91a13.7 13.7 0 0 0-5.16-1.27c-1.5 0-2.06.55-2.06 1.18 0 1.7 8.78.86 8.78 7.27 0 3.41-2.69 6.04-7.6 6.04-2.34 0-4.85-.5-6.55-1.16v-3.94a16.86 16.86 0 0 0 6.21 1.3z" fill="currentColor"/>
            </svg>
          </span>
          <span style={{ width: 3, height: 3, borderRadius: 999, background: "var(--border)" }} />
          <span>Cancel anytime</span>
          <span style={{ width: 3, height: 3, borderRadius: 999, background: "var(--border)" }} />
          <span>14-day refund</span>
        </div>
      </div>
    </div>
  );
}

function WelcomeToast({ show, onDismiss }) {
  const [vis, setVis] = useStateBill(show);

  useEffectBill(() => {
    if (show) {
      setVis(true);
      const t = setTimeout(() => {
        setVis(false);
        setTimeout(() => onDismiss && onDismiss(), 300);
      }, 5400);
      return () => clearTimeout(t);
    }
  }, [show, onDismiss]);

  if (!show) return null;

  return (
    <div
      style={{
        position: "fixed",
        bottom: 28, left: "50%",
        transform: `translateX(-50%) translateY(${vis ? 0 : 12}px)`,
        opacity: vis ? 1 : 0,
        transition: "transform 260ms cubic-bezier(.2,.8,.2,1), opacity 260ms",
        zIndex: 300,
        background: "var(--paper-3)",
        border: "1px solid var(--border)",
        borderRadius: 12,
        boxShadow: "0 20px 50px rgba(0,0,0,0.45)",
        padding: "14px 18px 14px 14px",
        display: "flex", alignItems: "center", gap: 14,
        fontFamily: "Inter, sans-serif",
        maxWidth: 520,
      }}
    >
      <div style={{
        width: 32, height: 32, borderRadius: 8,
        background: "var(--accent)",
        display: "flex", alignItems: "center", justifyContent: "center",
        flexShrink: 0,
      }}>
        <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
          <path d="M3 8l3.5 3.5L13 4.5" stroke="#14180A" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </div>
      <div style={{ flex: 1 }}>
        <div style={{
          fontFamily: "'Instrument Serif', serif",
          fontSize: 19, lineHeight: 1.1,
          color: "var(--ink)", letterSpacing: "-0.01em",
        }}>
          Welcome to <span style={{ fontStyle: "italic", color: "var(--accent)" }}>Pro</span>.
        </div>
        <div style={{ fontSize: 12.5, color: "var(--muted)", marginTop: 2, lineHeight: 1.4 }}>
          5 base resumes, monthly credits, cover letters — all unlocked.
        </div>
      </div>
      <button
        onClick={() => { setVis(false); setTimeout(() => onDismiss && onDismiss(), 200); }}
        style={{
          width: 26, height: 26, borderRadius: 6,
          border: "1px solid var(--border)",
          background: "transparent", color: "var(--muted)",
          cursor: "pointer", display: "flex",
          alignItems: "center", justifyContent: "center",
          flexShrink: 0,
        }}
      >
        {Icon.x}
      </button>
    </div>
  );
}

function formatRenewDate(iso) {
  if (!iso) return null;
  const d = new Date(iso);
  if (isNaN(d.getTime())) return null;
  return d.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" });
}

function BillingPanel({ billing, onUpgrade, onAddCreditsFree, onManage, onTopUp }) {
  const isPro = billing && billing.plan === "pro";
  const monthlyTailoringsLeft = Math.floor((billing?.monthly_credits_remaining ?? 0) / TAILORING_COST);
  const freeTailoringsLeft = Math.floor((billing?.signup_credits_remaining ?? 0) / TAILORING_COST);
  const topupTailoringsLeft = Math.floor((billing?.topup_credits_remaining ?? 0) / TAILORING_COST);
  const renewLabel = formatRenewDate(billing?.subscription_renews_at);
  const periodPriceLabel = billing?.subscription_period === "yearly"
    ? "$150/year"
    : "$15/month";

  return (
    <div>
      <Eyebrow style={{ marginBottom: 12 }}>Plan & billing</Eyebrow>

      <div style={{
        border: "1px solid var(--border)",
        borderRadius: 10,
        padding: "16px 18px",
        marginBottom: 8,
        background: isPro
          ? "linear-gradient(180deg, color-mix(in oklab, var(--accent) 8%, transparent), transparent 70%)"
          : "transparent",
      }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 12 }}>
          <div>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 4 }}>
              <span style={{
                fontFamily: "'Instrument Serif', serif",
                fontSize: 22, lineHeight: 1, color: "var(--ink)",
                letterSpacing: "-0.01em",
              }}>{isPro ? "Pro" : "Free"}</span>
              {isPro && (
                <span style={{
                  fontFamily: "'JetBrains Mono', monospace",
                  fontSize: 9, letterSpacing: "0.14em", textTransform: "uppercase",
                  background: "var(--accent)", color: "#14180A",
                  padding: "2px 6px", borderRadius: 3, fontWeight: 500,
                }}>Active</span>
              )}
            </div>
            <div style={{ fontSize: 12, color: "var(--muted)", lineHeight: 1.5 }}>
              {isPro
                ? `${periodPriceLabel}${renewLabel ? ` · next bill ${renewLabel}` : ""}`
                : "1 base resume · BYOK or signup credits"}
            </div>
          </div>
          {isPro ? (
            <button
              onClick={onManage}
              style={{
                padding: "7px 12px", border: "1px solid var(--border)",
                borderRadius: 6, background: "transparent",
                color: "var(--ink)", fontSize: 12, fontWeight: 500,
                cursor: "pointer", fontFamily: "Inter, sans-serif",
                whiteSpace: "nowrap",
                display: "inline-flex", alignItems: "center", gap: 6,
              }}
            >
              Manage
              <svg width="10" height="10" viewBox="0 0 10 10" fill="none">
                <path d="M2 8l6-6M3 2h5v5" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" />
              </svg>
            </button>
          ) : (
            <button
              onClick={onUpgrade}
              style={{
                padding: "7px 14px",
                border: "1px solid var(--accent)",
                borderRadius: 6, background: "var(--accent)",
                color: "#14180A", fontSize: 12, fontWeight: 500,
                cursor: "pointer", fontFamily: "Inter, sans-serif",
                whiteSpace: "nowrap",
              }}
            >
              Upgrade to Pro
            </button>
          )}
        </div>

        <div style={{ paddingTop: 12, borderTop: "1px solid var(--border)" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 4 }}>
            <span style={{ fontSize: 12.5, color: "var(--ink)", fontWeight: 500 }}>
              {isPro ? "Monthly credits" : "Free tailorings"}
            </span>
            <span style={{
              fontFamily: "'JetBrains Mono', monospace",
              fontSize: 11, letterSpacing: "0.06em", color: "var(--muted)",
              whiteSpace: "nowrap",
            }}>
              {isPro
                ? `${monthlyTailoringsLeft}/${MONTHLY_BUDGET_TAILORINGS} LEFT`
                : `${freeTailoringsLeft}/2 LEFT`}
            </span>
          </div>
          {isPro && renewLabel && (
            <div style={{
              fontFamily: "'JetBrains Mono', monospace",
              fontSize: 10, letterSpacing: "0.06em",
              color: "var(--muted)", marginBottom: 8,
              opacity: 0.75,
            }}>Resets {renewLabel} · no rollover</div>
          )}

          <div style={{ display: "flex", gap: 4, marginBottom: 12, marginTop: isPro ? 0 : 8 }}>
            {Array.from({ length: isPro ? MONTHLY_BUDGET_TAILORINGS : 2 }).map((_, i) => {
              const used = isPro ? i >= monthlyTailoringsLeft : i >= freeTailoringsLeft;
              return (
                <div key={i} style={{
                  flex: 1, height: 4, borderRadius: 2,
                  background: used ? "var(--border)" : "var(--accent)",
                  opacity: used ? 0.5 : 1,
                }} />
              );
            })}
          </div>

          {isPro && topupTailoringsLeft > 0 && (
            <div style={{
              fontSize: 11.5, color: "var(--muted)", marginBottom: 10,
              display: "flex", justifyContent: "space-between",
            }}>
              <span>Top-up balance</span>
              <span style={{ fontFamily: "'JetBrains Mono', monospace", letterSpacing: "0.06em" }}>
                ~{topupTailoringsLeft} TAILORINGS
              </span>
            </div>
          )}

          <button
            onClick={isPro ? onTopUp : onAddCreditsFree}
            style={{
              width: "100%",
              padding: "9px 12px",
              border: "1px solid var(--border)",
              borderRadius: 6,
              background: "transparent",
              color: "var(--ink)",
              fontSize: 12, fontWeight: 500,
              cursor: "pointer", fontFamily: "Inter, sans-serif",
              display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8,
            }}
          >
            <span style={{ color: "var(--accent)" }}>+</span>
            {isPro ? "Top up $10 (~30 tailorings, no expiry)" : "Buy credits — requires Pro"}
          </button>
        </div>
      </div>

      <div style={{ fontSize: 11, color: "var(--muted)", lineHeight: 1.5, padding: "4px 2px" }}>
        {isPro
          ? "Monthly credits reset each billing cycle. Top-up packs stack on top and never expire."
          : "Free includes 2 ResumeForge-credit tailorings on signup. After that, paste your own API key or upgrade to Pro for monthly credits + 5 masters."}
      </div>
    </div>
  );
}

Object.assign(window, { UpgradeModal, WelcomeToast, BillingPanel, UPGRADE_REASONS });