/* global React */
// ============================================================
//  Pro / monetization — entitlement store, AI quota, upgrade modal
// ============================================================
const { useState: useStatePro, useEffect: useEffectPro } = React;

const PRO_KEY = "rb_pro_v1";
const AI_KEY = "rb_ai_used_v1";
const AI_LIMIT = 3;
const PRO_PRICE = "₹" + (((window.RB_CONFIG && window.RB_CONFIG.PRO_PRICE_INR) || 599));

// curated "premium" template set — shown with a PRO badge in the gallery
const PRO_TEMPLATES = new Set([
  "spectrum", "onyx", "atlas", "prism", "vertex", "summit",
  "quill", "meridian", "ember", "terminal", "canvas", "globe",
]);
function isProTemplate(id) { return PRO_TEMPLATES.has(id); }

const Pro = {
  // Entitlement: in live mode it's the Supabase-backed flag; otherwise localStorage (demo).
  is() {
    if (window.RB_LIVE) return window.__rbProActive === true;
    try { return localStorage.getItem(PRO_KEY) === "1"; } catch (e) { return false; }
  },
  // Demo-only local activation (used when no backend is configured).
  activate() { try { localStorage.setItem(PRO_KEY, "1"); } catch (e) {} this._emit(); },
  cancel() { try { localStorage.removeItem(PRO_KEY); } catch (e) {} this._emit(); },
  price: PRO_PRICE,
  aiLimit: AI_LIMIT,
  aiUsed() { try { return parseInt(localStorage.getItem(AI_KEY) || "0", 10) || 0; } catch (e) { return 0; } },
  aiRemaining() { return this.is() ? Infinity : Math.max(0, AI_LIMIT - this.aiUsed()); },
  canUseAI() { return this.is() || this.aiUsed() < AI_LIMIT; },
  recordAI() { if (this.is()) return; try { localStorage.setItem(AI_KEY, String(this.aiUsed() + 1)); } catch (e) {} this._emit(); },
  // central gate: returns true if AI may run; otherwise opens the paywall
  guardAI() { if (this.canUseAI()) return true; this.requestUpgrade("ai"); return false; },
  requestUpgrade(reason) { window.dispatchEvent(new CustomEvent("rb-upgrade", { detail: { reason: reason || "default" } })); },
  _emit() { window.dispatchEvent(new Event("rb-pro-change")); },

  // ---- call a Supabase edge function -----------------------
  async _invoke(fn, body) {
    const { data, error } = await window.sb.functions.invoke(fn, { body: body || {} });
    if (error) throw error;
    if (data && data.error) throw new Error(data.error);
    return data;
  },

  // ---- Razorpay recurring subscription checkout ------------
  // Demo mode (no keys): instantly activate locally.
  // Live mode: sign-in → create subscription → Razorpay mandate → verify → refresh.
  async startCheckout(reason) {
    if (!window.RB_LIVE || !window.sb) { this.activate(); return { demo: true }; }
    if (!window.RBAuth || !window.RBAuth.user()) {
      window.requestAuth({ mode: "signup", next: () => Pro.startCheckout(reason) });
      return { needAuth: true };
    }
    if (!window.Razorpay) { window.alert("Payment library failed to load. Check your connection."); return { error: true }; }
    let sub;
    try { sub = await this._invoke("razorpay-create-subscription", { reason: reason || "default" }); }
    catch (e) { window.alert("Couldn't start checkout: " + (e.message || e)); return { error: true }; }
    return new Promise((resolve) => {
      const rzp = new window.Razorpay({
        key: window.RB_CONFIG.RAZORPAY_KEY_ID,
        subscription_id: sub.subscription_id,
        name: "get-resume.com",
        description: "Pro subscription — " + Pro.price + "/mo",
        prefill: { email: (window.RBAuth.user() || {}).email || "" },
        theme: { color: "#111111" },
        handler: async (resp) => {
          try {
            await Pro._invoke("razorpay-verify", {
              razorpay_payment_id: resp.razorpay_payment_id,
              razorpay_subscription_id: resp.razorpay_subscription_id,
              razorpay_signature: resp.razorpay_signature,
            });
            await window.refreshEntitlement();
            resolve({ ok: true });
          } catch (e) { window.alert("Payment verification failed: " + (e.message || e)); resolve({ ok: false }); }
        },
        modal: { ondismiss: () => resolve({ dismissed: true }) },
      });
      rzp.open();
    });
  },

  // Cancel: server-side in live mode, local in demo mode.
  async cancelRemote() {
    if (window.RB_LIVE && window.sb) {
      try { await Pro._invoke("razorpay-cancel", {}); } catch (e) { window.alert("Couldn't cancel: " + (e.message || e)); }
      await window.refreshEntitlement();
    } else { this.cancel(); }
  },
};

// keep the <body> class in sync so CSS can hide the watermark for Pro users
function syncProBodyClass() { try { document.body.classList.toggle("rb-pro", Pro.is()); } catch (e) {} }
window.addEventListener("rb-pro-change", syncProBodyClass);
setTimeout(syncProBodyClass, 0);

// hook: re-render a component when Pro state / AI usage changes
function useProState() {
  const [, force] = useStatePro(0);
  useEffectPro(() => {
    const h = () => force((x) => x + 1);
    window.addEventListener("rb-pro-change", h);
    return () => window.removeEventListener("rb-pro-change", h);
  }, []);
  return {
    isPro: Pro.is(), aiUsed: Pro.aiUsed(), aiRemaining: Pro.aiRemaining(), aiLimit: Pro.aiLimit,
    status: window.__rbProStatus || null,         // active | pending | halted | cancelled | …
    until: window.__rbProUntil || null,            // current period end (ISO)
    nextCharge: window.__rbProNextCharge || null,  // next auto-debit (ISO)
  };
}

// ---- plain-text résumé export (the free tier) ------------------------------
function resumeToText(r) {
  if (!r) return "";
  const L = [];
  const rule = () => L.push("─".repeat(46));
  const nm = (s) => (window.skillName ? window.skillName(s) : (s && s.name) || s);
  L.push((r.name || "").toUpperCase());
  if (r.title) L.push(r.title);
  const contact = [r.email, r.phone, r.location, r.website].filter(Boolean).join("  ·  ");
  if (contact) L.push(contact);
  L.push("");
  if (r.summary && r.summary.trim()) { L.push("SUMMARY"); rule(); L.push(r.summary.trim()); L.push(""); }
  if ((r.experience || []).length) {
    L.push("EXPERIENCE"); rule();
    r.experience.forEach((e) => {
      const dates = [e.start, e.end].filter(Boolean).join(" – ");
      const head = [e.role, e.company].filter(Boolean).join(" · ");
      L.push(dates ? `${head}   (${dates})` : head);
      if (e.location) L.push(e.location);
      (e.bullets || []).filter((b) => b && b.trim()).forEach((b) => L.push("  • " + b.trim()));
      L.push("");
    });
  }
  if ((r.skills || []).length) {
    L.push("SKILLS"); rule();
    L.push(r.skills.map(nm).filter(Boolean).join(", "));
    L.push("");
  }
  if ((r.education || []).length) {
    L.push("EDUCATION"); rule();
    r.education.forEach((e) => {
      const dates = [e.start, e.end].filter(Boolean).join(" – ");
      const head = [e.degree, e.school].filter(Boolean).join(" · ");
      L.push(dates ? `${head}   (${dates})` : head);
    });
    L.push("");
  }
  // any extra array-based sections (projects, awards, certifications, languages, interests…)
  const handled = new Set(["name", "title", "email", "phone", "location", "website", "summary", "experience", "skills", "education", "photo", "order"]);
  Object.keys(r).forEach((k) => {
    if (handled.has(k)) return;
    const v = r[k];
    if (!Array.isArray(v) || !v.length) return;
    L.push(k.toUpperCase()); rule();
    v.forEach((item) => {
      if (typeof item === "string") L.push("  • " + item);
      else if (item && typeof item === "object") {
        const t = item.title || item.name || item.label || "";
        const d = item.detail || item.org || item.issuer || item.level || "";
        L.push("  • " + [t, d].filter(Boolean).join(" — "));
      }
    });
    L.push("");
  });
  return L.join("\n").replace(/\n{3,}/g, "\n\n").trim() + "\n";
}

async function copyText(text) {
  try { await navigator.clipboard.writeText(text); return true; }
  catch (e) {
    try {
      const ta = document.createElement("textarea");
      ta.value = text; ta.style.position = "fixed"; ta.style.opacity = "0";
      document.body.appendChild(ta); ta.focus(); ta.select();
      const ok = document.execCommand("copy"); ta.remove(); return ok;
    } catch (_) { return false; }
  }
}

// ============================================================
//  Upgrade modal — reason-aware headline, ₹999/mo, benefit list
// ============================================================
const UP_COPY = {
  pdf: { badge: "Pro feature", h: "Download your résumé as a polished PDF", p: "Your résumé is free to build and edit. Upgrade to Pro to download the print-ready, branding-free PDF — exactly as you see it." },
  cover: { badge: "Pro feature", h: "Download your cover letter as a PDF", p: "Cover-letter PDF export is part of Pro — beautifully matched to your résumé template and ready to send." },
  ai: { badge: "You're out of free AI", h: "Keep writing with unlimited AI", p: "You've used your free AI rewrites. Go Pro for unlimited AI on every bullet, summary and cover letter." },
  template: { badge: "Premium template", h: "Unlock every premium template", p: "This design is part of the Pro collection. Upgrade to use and download all premium templates, branding-free." },
  nav: { badge: "get-resume.com Pro", h: "Everything you need to land the role", p: "Unlimited AI, print-ready PDFs, premium templates and more — for one simple monthly price." },
  default: { badge: "get-resume.com Pro", h: "Go Pro and get the full studio", p: "Unlock PDF downloads, unlimited AI and every premium template." },
};

const PRO_BENEFITS = [
  ["download", "Unlimited PDF downloads", "Résumés & cover letters, print-ready"],
  ["infinity", "Unlimited AI writing", "Rewrite, quantify & draft as much as you like"],
  ["layers", "All premium templates", "Every design in the studio"],
  ["mail", "Cover-letter PDF export", "Matched to your résumé, on one document"],
  ["star", "Branding-free exports", "Nothing but your résumé on the page"],
  ["folder", "Multiple saved résumés", "Tailor a version for every application"],
];

const STATUS_LABEL = {
  active: "Active", authenticated: "Active", pending: "Payment pending",
  halted: "Paused — payment failed", cancelled: "Cancelling at period end",
  completed: "Completed", expired: "Expired", created: "Awaiting first payment",
};
function fmtDate(iso) {
  if (!iso) return null;
  try { return new Date(iso).toLocaleDateString(undefined, { day: "numeric", month: "short", year: "numeric" }); }
  catch (e) { return null; }
}

function UpgradeModal({ reason, onClose }) {
  const manage = reason === "manage";
  const copy = UP_COPY[reason] || UP_COPY.default;
  const [done, setDone] = useStatePro(false);
  const { status, until, nextCharge } = useProState();

  useEffectPro(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, []);

  const [busy, setBusy] = useStatePro(false);
  const subscribe = async () => {
    if (busy) return;
    setBusy(true);
    const r = await Pro.startCheckout(reason);
    setBusy(false);
    if (r && (r.ok || r.demo)) { setDone(true); setTimeout(onClose, 1500); }
    else if (r && r.needAuth) { onClose(); }   // auth modal will resume checkout
  };

  if (manage) {
    return (
      <div className="up-scrim" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
        <div className="up-modal" role="dialog" aria-modal="true">
          <div className="up-head">
            <button className="up-close" onClick={onClose} aria-label="Close"><Icons.close size={16} /></button>
            <span className="up-head-badge"><Icons.crown size={13} /> You're on Pro</span>
            <h3>get-resume.com Pro is active</h3>
            <p>Unlimited PDFs, unlimited AI, every premium template — all unlocked.</p>
          </div>
          <div className="up-body">
            <div className="up-price"><b>{Pro.price}</b><span>/ month</span>
              <span className="up-cancel">{STATUS_LABEL[status] || "Renews monthly"}</span></div>
            {(until || nextCharge) && (
              <div className="up-substatus">
                {status === "cancelled"
                  ? <>Access until <b>{fmtDate(until)}</b> — won't renew.</>
                  : nextCharge
                    ? <>Next charge <b>{fmtDate(nextCharge)}</b>.</>
                    : until ? <>Current period ends <b>{fmtDate(until)}</b>.</> : null}
              </div>
            )}
            <ul className="up-benefits">
              {PRO_BENEFITS.map(([ic, t]) => {
                const Ic = Icons[ic] || Icons.check;
                return <li className="now" key={t}><span className="up-ck"><Icons.check size={13} /></span><span>{t}</span></li>;
              })}
            </ul>
            <div className="up-actions">
              {status !== "cancelled" && (
                <button className="up-secondary" onClick={() => { Pro.cancelRemote(); onClose(); }}>Cancel subscription</button>
              )}
            </div>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="up-scrim" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="up-modal" role="dialog" aria-modal="true">
        {done ? (
          <div className="up-success">
            <div className="up-success-ic"><Icons.crown size={30} /></div>
            <h3>Welcome to Pro</h3>
            <p>Everything's unlocked. Go grab that PDF.</p>
          </div>
        ) : (
          <>
            <div className="up-head">
              <button className="up-close" onClick={onClose} aria-label="Close"><Icons.close size={16} /></button>
              <span className="up-head-badge"><Icons.crown size={13} /> {copy.badge}</span>
              <h3>{copy.h}</h3>
              <p>{copy.p}</p>
            </div>
            <div className="up-body">
              <div className="up-price"><b>{Pro.price}</b><span>/ month</span><span className="up-cancel">Cancel anytime</span></div>
              <ul className="up-benefits">
                {PRO_BENEFITS.map(([ic, t, sub]) => {
                  const Ic = Icons[ic] || Icons.check;
                  return (
                    <li key={t}>
                      <span className="up-ck"><Ic size={12} /></span>
                      <span>{t}{sub && <em>{sub}</em>}</span>
                    </li>
                  );
                })}
              </ul>
              <div className="up-actions">
                <button className="btn btn-primary btn-pro" onClick={subscribe} disabled={busy}>
                  <Icons.crown size={17} /> {busy ? "Opening checkout…" : `Go Pro — ${Pro.price}/mo`}
                </button>
                <button className="up-secondary" onClick={onClose}>Maybe later</button>
              </div>
              <p className="up-foot-note">Free to build, edit & copy as text — always. By subscribing you agree to our <button type="button" className="up-link" onClick={() => { onClose(); window.dispatchEvent(new CustomEvent("rb-goto", { detail: { screen: "refund" } })); }}>Refund & Cancellation Policy</button>.</p>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

// Single gate mounted once at the app root; listens for upgrade requests.
function UpgradeGate() {
  const [state, setState] = useStatePro(null); // { reason } | null
  useEffectPro(() => {
    const h = (e) => setState({ reason: (e.detail && e.detail.reason) || "default" });
    window.addEventListener("rb-upgrade", h);
    return () => window.removeEventListener("rb-upgrade", h);
  }, []);
  if (!state) return null;
  return <UpgradeModal reason={state.reason} onClose={() => setState(null)} />;
}

Object.assign(window, {
  Pro, useProState, UpgradeModal, UpgradeGate,
  resumeToText, copyText, isProTemplate, PRO_TEMPLATES,
});
