// ── URL Shortener Page ─────────────────────────────────────────────────

function ShortenerPage({ user }) {
  const [links, setLinks] = useState([]);
  const [stats, setStats] = useState(null);
  const [loading, setLoading] = useState(false);
  const [showCreate, setShowCreate] = useState(false);
  const [showEdit, setShowEdit] = useState(null);
  const [showAdvanced, setShowAdvanced] = useState(false);
  const [error, setError] = useState('');
  const [copied, setCopied] = useState('');

  const [newUrl, setNewUrl] = useState('');
  const [newExpiry, setNewExpiry] = useState('');
  const [newMaxClicks, setNewMaxClicks] = useState('');
  const [newPermanent, setNewPermanent] = useState(false);
  const [newLambda, setNewLambda] = useState('');

  const [editUrl, setEditUrl] = useState('');
  const [editExpiry, setEditExpiry] = useState('');
  const [editMaxClicks, setEditMaxClicks] = useState('');
  const [editPermanent, setEditPermanent] = useState(false);
  const [editLambda, setEditLambda] = useState('');

  const loadLinks = useCallback(async () => {
    setLoading(true);
    try { setLinks(await api('/api/l/links')); } catch {}
    finally { setLoading(false); }
  }, []);

  const loadStats = useCallback(async () => {
    try { setStats(await api('/api/l/stats')); } catch {}
  }, []);

  useEffect(() => { loadLinks(); loadStats(); }, [loadLinks, loadStats]);

  const copyUrl = (url) => {
    navigator.clipboard.writeText(url);
    setCopied(url);
    setTimeout(() => setCopied(''), 2000);
  };

  const createLink = async () => {
    setError('');
    if (!newUrl) { setError('URL is required'); return; }
    try {
      const opts = {};
      if (newExpiry) opts.expires_at = new Date(newExpiry).toISOString();
      if (newMaxClicks) opts.max_clicks = parseInt(newMaxClicks, 10);
      if (newPermanent) opts.is_permanent = true;
      if (newLambda.trim()) opts.transform_lambda = newLambda.trim();

      await api('/api/l/links', {
        method: 'POST',
        body: JSON.stringify({ long_url: newUrl, options: opts }),
      });
      setShowCreate(false);
      setNewUrl(''); setNewExpiry(''); setNewMaxClicks(''); setNewPermanent(false); setNewLambda('');
      setShowAdvanced(false);
      loadLinks(); loadStats();
    } catch (e) { setError(e.message); }
  };

  const startEdit = (link) => {
    setEditUrl(link.long_url);
    setEditExpiry(link.expires_at ? link.expires_at.slice(0, 16) : '');
    setEditMaxClicks(link.max_clicks || '');
    setEditPermanent(!!link.is_permanent);
    setEditLambda(link.transform_lambda || '');
    setShowEdit(link.hash);
    setError('');
  };

  const updateLink = async () => {
    setError('');
    try {
      const opts = {};
      if (editExpiry) opts.expires_at = new Date(editExpiry).toISOString();
      else opts.expires_at = null;
      opts.max_clicks = editMaxClicks ? parseInt(editMaxClicks, 10) : 0;
      opts.is_permanent = editPermanent;
      opts.transform_lambda = editLambda.trim() || null;

      await api(`/api/l/links/${showEdit}`, {
        method: 'PUT',
        body: JSON.stringify({ long_url: editUrl, options: opts }),
      });
      setShowEdit(null);
      loadLinks(); loadStats();
    } catch (e) { setError(e.message); }
  };

  const deleteLink = async (hash) => {
    if (!confirm(`Delete short link ${hash}?`)) return;
    try {
      await api(`/api/l/links/${hash}`, { method: 'DELETE' });
      loadLinks(); loadStats();
    } catch {}
  };

  const fmtTime = (t) => t ? t.replace('T', ' ').slice(0, 19) : '-';

  const statusBadge = (link) => {
    let label = link.status;
    let color = 'var(--green)';
    let bg = 'rgba(52,211,153,0.15)';
    if (link.status === 'disabled') { color = 'var(--red)'; bg = 'rgba(248,113,113,0.15)'; }
    if (link.expires_at && new Date(link.expires_at) <= new Date()) { label = 'expired'; color = 'var(--yellow)'; bg = 'rgba(251,191,36,0.15)'; }
    if (link.max_clicks > 0 && link.clicks >= link.max_clicks) { label = 'maxed'; color = 'var(--yellow)'; bg = 'rgba(251,191,36,0.15)'; }
    return React.createElement('span', { style: { fontSize: 11, padding: '2px 8px', borderRadius: 4, background: bg, color } }, label);
  };

  return (
    <>
      <h2>URL Shortener</h2>
      <div className="page-sub">Create and manage short links at l.vibey.cloud</div>

      {stats && (
        <div style={{display:'flex',gap:12,marginBottom:20,flexWrap:'wrap'}}>
          {[
            { label: 'Total Links', value: stats.total_links, color: 'var(--accent)' },
            { label: 'Active', value: stats.active_links, color: 'var(--green)' },
            { label: 'Total Clicks', value: stats.total_clicks, color: 'var(--blue)' },
            { label: 'Disabled', value: stats.disabled_links, color: 'var(--text-dim)' },
          ].map(s => (
            <div key={s.label} style={{flex:'1 1 120px',background:'var(--surface)',border:'1px solid var(--border)',borderRadius:12,padding:'16px 20px'}}>
              <div style={{fontSize:11,color:'var(--text-dim)',textTransform:'uppercase',letterSpacing:'0.06em',marginBottom:4}}>{s.label}</div>
              <div style={{fontSize:24,fontWeight:700,color:s.color}}>{s.value}</div>
            </div>
          ))}
        </div>
      )}

      <div className="profile-card" style={{maxWidth:'none'}}>
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:16}}>
          <h3 style={{margin:0}}>Your Links</h3>
          <div style={{display:'flex',gap:8}}>
            <button className="btn-sm btn-ghost" onClick={() => { loadLinks(); loadStats(); }} disabled={loading}>
              {loading ? 'Loading...' : 'Refresh'}
            </button>
            <button className="btn-sm" onClick={() => { setShowCreate(true); setError(''); }}>+ New Link</button>
          </div>
        </div>

        {links.length === 0 && !loading && (
          <div style={{textAlign:'center',padding:'40px 0',color:'var(--text-dim)'}}>
            <p style={{fontSize:16,fontWeight:600,color:'var(--text)',marginBottom:8}}>No links yet</p>
            <p>Create your first short link to get started.</p>
          </div>
        )}

        {links.length > 0 && (
          <div style={{overflowX:'auto'}}>
            <table style={{width:'100%',borderCollapse:'collapse',fontSize:13}}>
              <thead>
                <tr style={{borderBottom:'1px solid var(--border)'}}>
                  <th style={{textAlign:'left',padding:'8px 12px',color:'var(--text-dim)',fontWeight:500}}>Short Link</th>
                  <th style={{textAlign:'left',padding:'8px 12px',color:'var(--text-dim)',fontWeight:500}}>Destination</th>
                  <th style={{textAlign:'right',padding:'8px 12px',color:'var(--text-dim)',fontWeight:500}}>Clicks</th>
                  <th style={{textAlign:'center',padding:'8px 12px',color:'var(--text-dim)',fontWeight:500}}>Type</th>
                  <th style={{textAlign:'center',padding:'8px 12px',color:'var(--text-dim)',fontWeight:500}}>Status</th>
                  <th style={{textAlign:'left',padding:'8px 12px',color:'var(--text-dim)',fontWeight:500}}>Expires</th>
                  <th style={{padding:'8px 12px'}}></th>
                </tr>
              </thead>
              <tbody>
                {links.map(l => (
                  <tr key={l.hash} style={{borderBottom:'1px solid var(--border)'}}>
                    <td style={{padding:'10px 12px'}}>
                      <div style={{display:'flex',alignItems:'center',gap:6}}>
                        <a href={l.short_url} target="_blank" rel="noopener"
                           style={{color:'var(--accent)',textDecoration:'none',fontFamily:'monospace',fontSize:12}}>
                          l.vibey.cloud/{l.hash}
                        </a>
                        <button className="btn-ghost" style={{padding:'2px 6px',fontSize:10,border:'none',color: copied === l.short_url ? 'var(--green)' : 'var(--text-dim)'}}
                                onClick={() => copyUrl(l.short_url)}>
                          {copied === l.short_url ? 'copied' : 'copy'}
                        </button>
                      </div>
                    </td>
                    <td style={{padding:'10px 12px',maxWidth:250,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
                      <a href={l.long_url} target="_blank" rel="noopener" title={l.long_url}
                         style={{color:'var(--text-dim)',textDecoration:'none',fontSize:12}}>{l.long_url}</a>
                    </td>
                    <td style={{textAlign:'right',padding:'10px 12px',fontFamily:'monospace',fontSize:12,fontWeight:600}}>{l.clicks}</td>
                    <td style={{textAlign:'center',padding:'10px 12px'}}>
                      <div style={{display:'flex',gap:4,justifyContent:'center',flexWrap:'wrap'}}>
                        <span style={{fontSize:10,padding:'2px 6px',borderRadius:4,background:'rgba(96,165,250,0.15)',color:'var(--blue)'}}>
                          {l.is_permanent ? '301' : '302'}
                        </span>
                        {l.has_lambda && (
                          <span style={{fontSize:10,padding:'2px 6px',borderRadius:4,background:'rgba(251,191,36,0.15)',color:'var(--yellow)'}}>lambda</span>
                        )}
                        {l.max_clicks > 0 && (
                          <span style={{fontSize:10,padding:'2px 6px',borderRadius:4,background:'rgba(124,92,252,0.15)',color:'var(--accent)'}}>{l.clicks}/{l.max_clicks}</span>
                        )}
                      </div>
                    </td>
                    <td style={{textAlign:'center',padding:'10px 12px'}}>{statusBadge(l)}</td>
                    <td style={{padding:'10px 12px',fontSize:12,color:'var(--text-dim)',whiteSpace:'nowrap'}}>
                      {l.expires_at ? fmtTime(l.expires_at) : 'never'}
                    </td>
                    <td style={{padding:'10px 12px',whiteSpace:'nowrap'}}>
                      <div style={{display:'flex',gap:4}}>
                        <button className="btn-sm btn-ghost" onClick={() => startEdit(l)} style={{fontSize:11}}>Edit</button>
                        <button className="btn-sm btn-danger" onClick={() => deleteLink(l.hash)} style={{fontSize:11}}>Delete</button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>

      {/* Create Modal */}
      {showCreate && (
        <div className="modal-overlay" onClick={() => setShowCreate(false)}>
          <div className="modal" onClick={e => e.stopPropagation()}>
            <h3>New Short Link</h3>
            {error && <div className="error-banner">{error}</div>}
            <div className="field">
              <label>Destination URL</label>
              <input value={newUrl} onChange={e => setNewUrl(e.target.value)} placeholder="https://example.com/long-page-url" autoFocus />
            </div>
            <div style={{marginBottom:16}}>
              <button className="btn-sm btn-ghost" onClick={() => setShowAdvanced(!showAdvanced)} style={{fontSize:12}}>
                {showAdvanced ? '▾ Hide Advanced' : '▸ Advanced Options'}
              </button>
            </div>
            {showAdvanced && (
              <>
                <div style={{display:'flex',gap:12}}>
                  <div className="field" style={{flex:1}}>
                    <label>Expires At</label>
                    <input type="datetime-local" value={newExpiry} onChange={e => setNewExpiry(e.target.value)} />
                  </div>
                  <div className="field" style={{flex:1}}>
                    <label>Max Clicks (0 = unlimited)</label>
                    <input type="number" min="0" value={newMaxClicks} onChange={e => setNewMaxClicks(e.target.value)} placeholder="0" />
                  </div>
                </div>
                <div className="field" style={{display:'flex',alignItems:'center',gap:10}}>
                  <label style={{margin:0,flex:1}}>Permanent Redirect (301)</label>
                  <label className="toggle">
                    <input type="checkbox" checked={newPermanent} onChange={e => setNewPermanent(e.target.checked)} />
                    <span className="slider"></span>
                  </label>
                </div>
                <div className="field">
                  <label className="cm-label">
                    Transform Lambda (JS)
                    <span className="cm-hint">(url, ctx) → ctx.headers, ctx.ip</span>
                  </label>
                  <LambdaEditor
                    value={newLambda}
                    onChange={setNewLambda}
                    placeholder={'(url, ctx) => {\n  return url + "?ref=" + ctx.ip;\n}'}
                  />
                </div>
                <LambdaHelp />
              </>
            )}
            <div className="modal-actions">
              <button className="btn-ghost" onClick={() => setShowCreate(false)}>Cancel</button>
              <button onClick={createLink}>Create Link</button>
            </div>
          </div>
        </div>
      )}

      {/* Edit Modal */}
      {showEdit && (
        <div className="modal-overlay" onClick={() => setShowEdit(null)}>
          <div className="modal" onClick={e => e.stopPropagation()}>
            <h3>Edit Link — {showEdit}</h3>
            {error && <div className="error-banner">{error}</div>}
            <div className="field">
              <label>Destination URL</label>
              <input value={editUrl} onChange={e => setEditUrl(e.target.value)} />
            </div>
            <div style={{display:'flex',gap:12}}>
              <div className="field" style={{flex:1}}>
                <label>Expires At</label>
                <input type="datetime-local" value={editExpiry} onChange={e => setEditExpiry(e.target.value)} />
              </div>
              <div className="field" style={{flex:1}}>
                <label>Max Clicks (0 = unlimited)</label>
                <input type="number" min="0" value={editMaxClicks} onChange={e => setEditMaxClicks(e.target.value)} placeholder="0" />
              </div>
            </div>
            <div className="field" style={{display:'flex',alignItems:'center',gap:10}}>
              <label style={{margin:0,flex:1}}>Permanent Redirect (301)</label>
              <label className="toggle">
                <input type="checkbox" checked={editPermanent} onChange={e => setEditPermanent(e.target.checked)} />
                <span className="slider"></span>
              </label>
            </div>
            <div className="field">
              <label className="cm-label">
                Transform Lambda (JS)
                <span className="cm-hint">(url, ctx) → ctx.headers, ctx.ip</span>
              </label>
              <LambdaEditor
                value={editLambda}
                onChange={setEditLambda}
                placeholder={'(url, ctx) => {\n  return url + "?ref=vibey";\n}'}
              />
            </div>
            <LambdaHelp />
            <div className="modal-actions">
              <button className="btn-ghost" onClick={() => setShowEdit(null)}>Cancel</button>
              <button onClick={updateLink}>Save Changes</button>
            </div>
          </div>
        </div>
      )}

      <div className="profile-card" style={{marginTop:16}}>
        <h3>API Usage</h3>
        <div style={{fontSize:13,color:'var(--text-dim)',lineHeight:1.8}}>
          <p>Create short links programmatically using the l.vibey.cloud API:</p>
          <pre style={{marginTop:8,background:'var(--bg)',border:'1px solid var(--border)',borderRadius:8,padding:16,fontSize:12,fontFamily:'SF Mono,Menlo,Consolas,monospace',color:'var(--text)',whiteSpace:'pre-wrap'}}>
{`curl -X POST https://l.vibey.cloud/create \\
  -H "Content-Type: application/json" \\
  -H "X-Invite-Code: ${user.invite_code || '<your-code>'}" \\
  -d '{
"long_url": "https://example.com/page",
"options": {
  "expires_at": "2026-12-31T23:59:59Z",
  "max_clicks": 1000,
  "is_permanent": false,
  "transform_lambda": "(url, ctx) => url + \\"?ref=\\" + ctx.ip"
}
  }'`}
          </pre>
        </div>
      </div>

      <div className="profile-card" style={{marginTop:16}}>
        <h3>Limits & Security</h3>
        <div style={{fontSize:13,color:'var(--text-dim)',lineHeight:1.6}}>
          <p style={{marginBottom:10}}>Rate limits per invite code + IP:</p>
          <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:'6px 24px'}}>
            <div style={{display:'flex',justifyContent:'space-between'}}><span>Create links</span><strong style={{color:'var(--text)'}}>10 / min</strong></div>
            <div style={{display:'flex',justifyContent:'space-between'}}><span>Redirects</span><strong style={{color:'var(--text)'}}>300 / min</strong></div>
          </div>
          <p style={{marginTop:14,marginBottom:8}}>Security features:</p>
          <ul style={{paddingLeft:20,lineHeight:2}}>
            <li>Three-tier URL validation (TLD, domain, keyword checks)</li>
            <li>Sandboxed Lambda execution (isolated-vm, 50ms timeout, 16MB)</li>
            <li>Lambda receives <code style={{fontSize:11,background:'var(--surface)',padding:'2px 6px',borderRadius:4}}>(url, ctx)</code> — ctx has filtered headers + IP</li>
            <li>Post-Lambda output validation (re-checks against blacklist)</li>
            <li>Obfuscated error responses (no invite code mining)</li>
          </ul>
        </div>
      </div>

      <div className="profile-card" style={{marginTop:16}}>
        <h3>URL Blacklist</h3>
        <div style={{fontSize:13,color:'var(--text-dim)',lineHeight:1.6}}>
          <p style={{marginBottom:12}}>
            Every URL is validated before a short link is created <strong style={{color:'var(--text)'}}>and</strong> again
            after a Lambda transforms it. URLs that match any of these rules are rejected with a generic 403.
          </p>

          <div style={{background:'var(--bg)',border:'1px solid var(--border)',borderRadius:10,overflow:'hidden'}}>
            <div style={{padding:'12px 16px',borderBottom:'1px solid var(--border)'}}>
              <div style={{fontSize:12,fontWeight:600,color:'var(--red)',textTransform:'uppercase',letterSpacing:'0.06em',marginBottom:6}}>
                Blocked TLDs
              </div>
              <div style={{fontSize:12,color:'var(--text-dim)'}}>
                URLs ending in high-risk top-level domains are rejected outright.
              </div>
              <div style={{display:'flex',flexWrap:'wrap',gap:6,marginTop:8}}>
                {['.zip','.mov','.exe','.top','.gdn','.tk','.cf','.ml','.ga','.gq'].map(t => (
                  <code key={t} style={{fontSize:11,background:'rgba(248,113,113,0.1)',color:'var(--red)',padding:'2px 8px',borderRadius:4,border:'1px solid rgba(248,113,113,0.2)'}}>{t}</code>
                ))}
              </div>
            </div>

            <div style={{padding:'12px 16px',borderBottom:'1px solid var(--border)'}}>
              <div style={{fontSize:12,fontWeight:600,color:'var(--yellow)',textTransform:'uppercase',letterSpacing:'0.06em',marginBottom:6}}>
                Blocked Redirect Chains
              </div>
              <div style={{fontSize:12,color:'var(--text-dim)'}}>
                Other URL shorteners are blocked to prevent redirect chains and abuse obfuscation.
              </div>
              <div style={{display:'flex',flexWrap:'wrap',gap:6,marginTop:8}}>
                {['bit.ly','t.co','tinyurl.com','is.gd','buff.ly','rebrand.ly','t.ly','qrco.de','ow.ly','tiny.cc','short.io','shor.by'].map(d => (
                  <code key={d} style={{fontSize:11,background:'rgba(251,191,36,0.1)',color:'var(--yellow)',padding:'2px 8px',borderRadius:4,border:'1px solid rgba(251,191,36,0.2)'}}>{d}</code>
                ))}
              </div>
            </div>

            <div style={{padding:'12px 16px'}}>
              <div style={{fontSize:12,fontWeight:600,color:'var(--accent)',textTransform:'uppercase',letterSpacing:'0.06em',marginBottom:6}}>
                Blocked Phishing Keywords
              </div>
              <div style={{fontSize:12,color:'var(--text-dim)'}}>
                URLs containing these substrings (case-insensitive, anywhere in the URL) are flagged as phishing.
              </div>
              <div style={{display:'flex',flexWrap:'wrap',gap:6,marginTop:8}}>
                {['secure-login','verify-account','signin-google','microsoft-auth','bank-update','paypal-confirm','account-verify','password-reset-confirm','apple-id-verify','amazon-security','netflix-payment','dropbox-verify'].map(k => (
                  <code key={k} style={{fontSize:11,background:'rgba(124,92,252,0.1)',color:'var(--accent)',padding:'2px 8px',borderRadius:4,border:'1px solid rgba(124,92,252,0.2)'}}>{k}</code>
                ))}
              </div>
            </div>
          </div>

          <div style={{marginTop:12,fontSize:12,color:'var(--text-dim)',background:'var(--surface)',borderRadius:8,padding:'10px 14px'}}>
            <strong style={{color:'var(--text)'}}>Only HTTP and HTTPS</strong> URLs are accepted.
            All other protocols (ftp, javascript, data, etc.) are rejected.
            If your link is blocked and you believe it's legitimate, contact an admin.
          </div>
        </div>
      </div>
    </>
  );
}
