// Face Recognition — iframe wrapper with freemium limit enforcement.
//
// Backend lives in tools/photorecognation/ (Python/FastAPI on :8888 by
// default; admin can override via the `photo_finder.backend_url` setting).
//
// Freemium model:
//   - Free users: see all results, but only 2 photos can be downloaded.
//     Results beyond 2 are shown blurred with a paywall CTA.
//   - Premium users: unlimited downloads.
//   - Download count persisted in localStorage (anonymous) and Supabase (signed-in).
//
// postMessage protocol with the iframe:
//   Parent → Iframe:
//     { type: 'mt-theme', theme }       — forward dark/light theme
//     { type: 'mt-limit', freeCount }   — set the free download cap
//     { type: 'mt-unlock' }             — lift the cap (premium)
//   Iframe → Parent:
//     { type: 'mt-iframe-height', height }  — auto-resize
//     { type: 'pf-results', total, maybe }  — result count notification
//     { type: 'pf-download', count, url }   — a download was triggered
//     { type: 'pf-upgrade' }                — user clicked "Unlock" inside iframe

const PF_FREE_LIMIT = 2;
const PF_DL_KEY = 'mm-pf-downloads';

window.TOOL_HANDLERS['photo-finder'] = function PhotoFinderTool({ cat }) {
  const [up, setUp] = React.useState(null);
  const [checking, setChecking] = React.useState(false);
  const [resultCount, setResultCount] = React.useState(0);
  const [downloads, setDownloads] = React.useState(() => {
    try { return parseInt(localStorage.getItem(PF_DL_KEY) || '0', 10) || 0; } catch { return 0; }
  });
  const downloadsRef = React.useRef(downloads);
  React.useEffect(() => { downloadsRef.current = downloads; }, [downloads]);
  const [showPaywall, setShowPaywall] = React.useState(false);
  const iframeRef = React.useRef(null);

  const backendUrl = (window.MM_PHOTO_FINDER_URL || 'http://localhost:8888').replace(/\/+$/, '');
  const theme = document.documentElement.dataset.theme === 'dark' ? 'dark' : 'light';

  const ents = window.MM_USER_ENTITLEMENTS || [];
  const isPremium = ents.includes('premium') || ents.includes('pro');

  // Effective free limit
  const freeLeft = Math.max(0, PF_FREE_LIMIT - downloads);
  const isLimited = !isPremium && downloads >= PF_FREE_LIMIT;

  // ---------- Backend health probe with auto-retry ----------
  React.useEffect(() => {
    let alive = true;
    let timer = null;
    let attempt = 0;
    let warmupKicked = false;
    const next = () => (attempt < 10 ? 1000 : 4000);
    const tick = async () => {
      try {
        const res = await fetch(backendUrl + '/api/health', {
          cache: 'no-store',
          signal: AbortSignal.timeout ? AbortSignal.timeout(2000) : undefined,
        });
        if (!alive) return;
        if (res.ok) {
          setUp(true);
          if (!warmupKicked) {
            warmupKicked = true;
            fetch(backendUrl + '/api/warmup', { method: 'POST' }).catch(() => {});
          }
          return;
        }
        setUp(false);
      } catch {
        if (!alive) return;
        setUp(false);
      }
      if (alive) { attempt++; timer = setTimeout(tick, next()); }
    };
    tick();
    return () => { alive = false; if (timer) clearTimeout(timer); };
  }, [backendUrl]);

  // ---------- Forward theme changes ----------
  React.useEffect(() => {
    if (!up) return;
    const mo = new MutationObserver(() => {
      const t = document.documentElement.dataset.theme === 'dark' ? 'dark' : 'light';
      iframeRef.current?.contentWindow?.postMessage({ type: 'mt-theme', theme: t }, '*');
    });
    mo.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
    return () => mo.disconnect();
  }, [up]);

  // ---------- Send limit to iframe once it loads ----------
  // Respects the admin toggle: window.MM_PF_PAYWALL. When false, no limit is sent.
  React.useEffect(() => {
    if (!up) return;
    const sendLimit = () => {
      const win = iframeRef.current?.contentWindow;
      if (!win) return;
      const paywallOn = window.MM_PF_PAYWALL === true;
      if (isPremium || !paywallOn) {
        win.postMessage({ type: 'mt-unlock' }, '*');
      } else {
        win.postMessage({ type: 'mt-limit', freeCount: PF_FREE_LIMIT }, '*');
      }
    };
    // Send after iframe loads
    const el = iframeRef.current;
    if (el) el.addEventListener('load', sendLimit);
    // Also send immediately in case iframe is already loaded
    setTimeout(sendLimit, 500);
    return () => { if (el) el.removeEventListener('load', sendLimit); };
  }, [up, isPremium]);

  // ---------- Listen to iframe messages ----------
  React.useEffect(() => {
    if (!up) return;
    const onMsg = (e) => {
      if (!e?.data) return;
      // Auto-resize
      if (e.data.type === 'mt-iframe-height') {
        const el = iframeRef.current; if (!el) return;
        const h = Math.max(560, Math.min(4000, Number(e.data.height) || 0));
        if (h) el.style.height = h + 'px';
      }
      // Results arrived
      if (e.data.type === 'pf-results') {
        setResultCount(e.data.total || 0);
      }
      // Download happened inside iframe
      if (e.data.type === 'pf-download') {
        const newCount = e.data.count || (downloadsRef.current + 1);
        setDownloads(newCount);
        try { localStorage.setItem(PF_DL_KEY, String(newCount)); } catch {}
        window.mmTrackComplete?.('photo-finder', { success: true });
      }
      // User clicked upgrade inside iframe
      if (e.data.type === 'pf-upgrade') {
        setShowPaywall(true);
      }
    };
    window.addEventListener('message', onMsg);
    return () => window.removeEventListener('message', onMsg);
  }, [up]);

  const probe = React.useCallback(async () => {
    setChecking(true);
    try {
      const res = await fetch(backendUrl + '/api/health', {
        cache: 'no-store',
        signal: AbortSignal.timeout ? AbortSignal.timeout(2000) : undefined,
      });
      setUp(res.ok);
    } catch { setUp(false); } finally { setChecking(false); }
  }, [backendUrl]);

  const tint = cat?.tint || '#ea580c';
  const soft = cat?.soft || '#ffede0';

  /* ---------- Loading ---------- */
  if (up === null) {
    return (
      <div className="pf-loading">
        <div className="pf-spinner" style={{ background: soft, color: tint }}>
          <window.Icon name="scan" size={28} strokeWidth={1.6} />
        </div>
        <div className="pf-loading-title">Checking the face recognition engine</div>
        <div className="pf-loading-sub">connecting to {backendUrl.replace(/^https?:\/\//, '')}…</div>
        <PfStyles tint={tint} soft={soft} />
      </div>
    );
  }

  /* ---------- Backend down ---------- */
  if (up === false) {
    return (
      <div className="pf-down">
        <div className="pf-hero" style={{ background: `linear-gradient(140deg, ${soft} 0%, var(--id-surface) 75%)` }}>
          <div className="pf-hero-icon" style={{ color: tint }}>
            <window.Icon name="scan" size={36} strokeWidth={1.5} />
          </div>
          <h3>Face Recognition Engine Offline</h3>
          <p>
            Start the PhotoFinder engine <strong>on your machine</strong> — everything runs
            locally; no selfie or gallery leaves your device.
          </p>
        </div>
        <div className="pf-steps">
          <div className="pf-step">
            <div className="pf-step-num" style={{ background: soft, color: tint }}>1</div>
            <div className="pf-step-body">
              <div className="pf-step-title">Run this in a terminal</div>
              <pre className="pf-code">cd tools/photorecognation{'\n'}./run.sh</pre>
              <div className="pf-hint">First run downloads the model (~300 MB, one-time).</div>
            </div>
          </div>
          <div className="pf-step">
            <div className="pf-step-num" style={{ background: soft, color: tint }}>2</div>
            <div className="pf-step-body">
              <div className="pf-step-title">Refresh when ready</div>
              <button className="btn btn-primary" onClick={probe} disabled={checking}
                      style={{ background: tint, borderColor: tint }}>
                <window.Icon name={checking ? 'rotate' : 'check'} size={16} />
                {checking ? ' Checking…' : ' Try again'}
              </button>
              <div className="pf-hint" style={{ marginTop: 8 }}>
                Auto-checking in the background — the tool will appear automatically.
              </div>
            </div>
          </div>
        </div>
        <PfStyles tint={tint} soft={soft} />
      </div>
    );
  }

  /* ---------- Backend up — iframe + usage bar ---------- */
  return (
    <div className="pf-up">
      {/* Usage indicator — hidden when admin disables paywall */}
      {!isPremium && window.MM_PF_PAYWALL === true && (
        <div className="pf-usage-bar">
          <div className="pf-usage-left">
            <window.Icon name="scan" size={14} />
            <span className="pf-usage-label">
              {isLimited
                ? 'Free limit reached'
                : `${freeLeft} free download${freeLeft !== 1 ? 's' : ''} remaining`}
            </span>
          </div>
          <div className="pf-usage-right">
            <div className="pf-usage-dots">
              {[...Array(PF_FREE_LIMIT)].map((_, i) => (
                <span key={i} className={`pf-dot ${i < downloads ? 'used' : ''}`} />
              ))}
            </div>
            {isLimited && (
              <button className="pf-upgrade-btn" onClick={() => setShowPaywall(true)}>
                <window.Icon name="bolt" size={12} /> Upgrade
              </button>
            )}
          </div>
        </div>
      )}

      {/* Result count badge */}
      {resultCount > 0 && (
        <div className="pf-result-badge">
          <window.Icon name="check" size={12} strokeWidth={2.5} />
          <span>{resultCount} photo{resultCount !== 1 ? 's' : ''} found</span>
        </div>
      )}

      <div className="pf-frame" style={{ boxShadow: `0 18px 50px -24px ${tint}44` }}>
        <iframe ref={iframeRef}
                src={`${backendUrl}/?theme=${theme}`}
                title="Face Recognition"
                allow="clipboard-write"
                style={{ width: '100%', height: '72vh', border: 0, display: 'block', background: 'var(--id-surface)' }} />
      </div>

      {/* Inline paywall overlay */}
      {showPaywall && (
        <div className="pf-paywall-overlay" onClick={() => setShowPaywall(false)}>
          <div className="pf-paywall-card" onClick={(e) => e.stopPropagation()}>
            <button className="pf-paywall-close" onClick={() => setShowPaywall(false)}>
              <window.Icon name="x" size={16} />
            </button>
            <div className="pf-paywall-icon" style={{ background: soft, color: tint }}>
              <window.Icon name="scan" size={32} strokeWidth={1.5} />
            </div>
            <h3>Unlock Unlimited Downloads</h3>
            <p>You've used your {PF_FREE_LIMIT} free downloads. Upgrade to Premium to download all matched photos, export albums as PDF, and create Instagram-ready crops.</p>
            <div className="pf-paywall-features">
              <div><window.Icon name="check" size={13} strokeWidth={2.5} style={{ color: tint }} /> Unlimited photo downloads</div>
              <div><window.Icon name="check" size={13} strokeWidth={2.5} style={{ color: tint }} /> PDF album &amp; ZIP export</div>
              <div><window.Icon name="check" size={13} strokeWidth={2.5} style={{ color: tint }} /> Instagram story templates</div>
              <div><window.Icon name="check" size={13} strokeWidth={2.5} style={{ color: tint }} /> Share link generation</div>
            </div>
            <button className="btn btn-primary" style={{ width: '100%', marginTop: 16, background: tint, borderColor: tint }}
                    onClick={() => {
                      setShowPaywall(false);
                      // Navigate to the main paywall — the parent app handles Stripe
                      const tool = window.TOOLS?.find((t) => t.id === 'photo-finder');
                      if (tool && window.mmNavigate) window.mmNavigate({ tool: tool.id });
                    }}>
              <window.Icon name="bolt" size={16} /> Upgrade to Premium
            </button>
            <button className="btn btn-secondary" style={{ width: '100%', marginTop: 8 }}
                    onClick={() => setShowPaywall(false)}>
              Maybe later
            </button>
          </div>
        </div>
      )}

      <PfStyles tint={tint} soft={soft} />
    </div>
  );
};

function PfStyles({ tint, soft }) {
  return <style>{`
    .pf-loading { text-align: center; padding: 54px 20px; }
    .pf-spinner {
      width: 68px; height: 68px; border-radius: 20px; margin: 0 auto 18px;
      display: flex; align-items: center; justify-content: center;
      animation: pfpulse 1.6s ease-in-out infinite;
      box-shadow: var(--id-shadow-lg);
    }
    .pf-loading-title { font-size: 16px; font-weight: 700; color: var(--id-text); margin-bottom: 4px; }
    .pf-loading-sub { font-size: 13px; color: var(--id-text-muted); }
    @keyframes pfpulse {
      0%, 100% { transform: scale(1); opacity: 1; }
      50%      { transform: scale(0.94); opacity: .65; }
    }

    .pf-down { padding: 4px; }
    .pf-hero {
      padding: 30px 24px; border-radius: 14px; text-align: center; margin-bottom: 20px;
      border: 1px solid var(--id-border);
    }
    .pf-hero-icon {
      width: 72px; height: 72px; border-radius: 18px; background: var(--id-surface);
      display: inline-flex; align-items: center; justify-content: center;
      margin-bottom: 14px; box-shadow: var(--id-shadow-lg);
    }
    .pf-hero h3 { font-size: 22px; margin: 0 0 8px; font-weight: 800; letter-spacing: -0.01em; color: var(--id-text); }
    .pf-hero p { margin: 0; font-size: 14px; color: var(--id-text-muted); max-width: 480px; margin-inline: auto; line-height: 1.55; }

    .pf-steps { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
    @media (max-width: 640px) { .pf-steps { grid-template-columns: 1fr; } }
    .pf-step {
      display: flex; gap: 12px; padding: 14px;
      background: var(--id-surface); border: 1px solid var(--id-border); border-radius: 12px;
    }
    .pf-step-num {
      width: 30px; height: 30px; border-radius: 10px; font-weight: 800; font-size: 14px;
      display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
    }
    .pf-step-body { min-width: 0; flex: 1; }
    .pf-step-title { font-size: 13px; font-weight: 700; margin-bottom: 8px; color: var(--id-text); }
    .pf-code {
      margin: 0 0 8px; padding: 10px 12px;
      background: var(--id-surface-alt); border-radius: 8px;
      font-size: 12px; font-family: var(--id-font-mono);
      overflow-x: auto; white-space: pre; color: var(--id-text);
    }
    .pf-hint { font-size: 11px; color: var(--id-text-muted); }

    .pf-up { padding: 2px; }
    .pf-frame { border-radius: 14px; overflow: hidden; border: 1px solid var(--id-border); }

    /* Usage bar */
    .pf-usage-bar {
      display: flex; align-items: center; justify-content: space-between;
      padding: 10px 14px; margin-bottom: 10px;
      background: var(--id-surface); border: 1px solid var(--id-border);
      border-radius: 10px; font-size: 13px;
    }
    .pf-usage-left { display: flex; align-items: center; gap: 8px; color: var(--id-text); font-weight: 600; }
    .pf-usage-right { display: flex; align-items: center; gap: 10px; }
    .pf-usage-dots { display: flex; gap: 5px; }
    .pf-dot {
      width: 10px; height: 10px; border-radius: 50%;
      background: var(--id-border); transition: background 0.2s;
    }
    .pf-dot.used { background: ${tint}; }
    .pf-upgrade-btn {
      display: inline-flex; align-items: center; gap: 4px;
      padding: 5px 12px; border-radius: 6px; border: 1px solid ${tint};
      background: transparent; color: ${tint}; font-size: 11px;
      font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
      cursor: pointer; transition: all 0.15s;
    }
    .pf-upgrade-btn:hover { background: ${tint}; color: #fff; }

    /* Result badge */
    .pf-result-badge {
      display: inline-flex; align-items: center; gap: 6px;
      padding: 6px 12px; margin-bottom: 8px;
      background: rgba(16,128,90,0.1); color: #10805a; border-radius: 8px;
      font-size: 12px; font-weight: 600;
    }
    [data-theme="dark"] .pf-result-badge { background: rgba(16,128,90,0.15); color: #5fd1a4; }

    /* Paywall overlay */
    .pf-paywall-overlay {
      position: fixed; inset: 0; z-index: 100;
      background: rgba(0,0,0,0.5); backdrop-filter: blur(4px);
      display: flex; align-items: center; justify-content: center;
      padding: 20px;
    }
    .pf-paywall-card {
      position: relative; max-width: 420px; width: 100%;
      background: var(--id-surface); border: 1px solid var(--id-border);
      border-radius: 16px; padding: 32px 28px; text-align: center;
    }
    .pf-paywall-close {
      position: absolute; top: 12px; right: 12px;
      background: none; border: none; color: var(--id-text-muted); cursor: pointer;
    }
    .pf-paywall-icon {
      width: 64px; height: 64px; border-radius: 16px; margin: 0 auto 16px;
      display: flex; align-items: center; justify-content: center;
    }
    .pf-paywall-card h3 {
      font-size: 20px; font-weight: 800; color: var(--id-text);
      margin: 0 0 8px; letter-spacing: -0.01em;
    }
    .pf-paywall-card p {
      font-size: 13px; color: var(--id-text-muted); line-height: 1.55;
      margin: 0 0 16px;
    }
    .pf-paywall-features {
      text-align: left; display: grid; gap: 8px;
      font-size: 13px; color: var(--id-text); font-weight: 500;
    }
    .pf-paywall-features > div { display: flex; align-items: center; gap: 8px; }
  `}</style>;
}
