/* ══════════════════════════════════════════════════════════════════
   CREDENTIAL VAULT — per-user encrypted license & API key store
   ──────────────────────────────────────────────────────────────────
   Surfaces:
   - Brand Profile → Credential Vault tab (this file's <CredentialVaultTab/>)
   - Kit Builder Step 4 (Stack) reads via window.useVault() to gate/enable
     plugin rows based on license status (unlocked vs locked+greyed)
   - Account → Security mirror (shown for Agency Owners only)

   Security model (UI rep — actual impl notes in header of each card):
   - SCOPED per-user. Team members see install status only; keys hidden.
   - Stored in envelope-encrypted vault (AWS KMS / Vault). Never logged.
   - Transit: TLS + per-request HMAC. At rest: AES-256-GCM.
   - Validated against vendor APIs on save + weekly cron.
   - Revocable from anywhere (Vault, Account → Security, or remote kill).

   State: localStorage['wpsb-credential-vault'] (demo; prod = server)
   Hook:  window.useVault() → [vault, update, status]
   ══════════════════════════════════════════════════════════════════ */

(function() {
  const { useState, useEffect, useMemo } = React;
  const VAULT_KEY = 'wpsb-credential-vault';

  /* ── Credential catalog ────────────────────────────────────────
     id          — stable key
     category    — UI section
     vendor      — display name
     fieldType   — key | kit-id | file | api+email
     validate    — vendor API to hit on save (mock)
     docs        — vendor docs URL
     usedBy      — where in WPSB this credential is consumed
  */
  const CREDENTIAL_CATALOG = [
    /* ── Page builders ── */
    { id:'elementor-pro',  cat:'builders', vendor:'Elementor Pro',        fieldType:'key',       docs:'my.elementor.com', usedBy:['Kit Builder · Stack'], req:['license'] },
    { id:'divi',           cat:'builders', vendor:'Divi',                 fieldType:'api+email', docs:'elegantthemes.com/members',    usedBy:['Kit Builder · Stack'], req:['apiKey','username'] },
    { id:'beaver-builder', cat:'builders', vendor:'Beaver Builder',       fieldType:'key',       docs:'wpbeaverbuilder.com',  usedBy:['Kit Builder · Stack'], req:['license'] },
    { id:'oxygen',         cat:'builders', vendor:'Oxygen',               fieldType:'api+email', docs:'oxygenbuilder.com',    usedBy:['Kit Builder · Stack'], req:['license','email'] },
    { id:'bricks',         cat:'builders', vendor:'Bricks',               fieldType:'key',       docs:'bricksbuilder.io',     usedBy:['Kit Builder · Stack'], req:['license'] },

    /* ── Forms & functionality ── */
    { id:'gravity-forms',  cat:'forms',    vendor:'Gravity Forms',        fieldType:'key',       docs:'gravityforms.com',     usedBy:['Kit Builder · Stack','Site Builder'], req:['license'] },
    { id:'wpforms',        cat:'forms',    vendor:'WPForms',              fieldType:'key',       docs:'wpforms.com',          usedBy:['Kit Builder · Stack'], req:['license'] },
    { id:'fluent-forms',   cat:'forms',    vendor:'Fluent Forms',         fieldType:'key',       docs:'fluentforms.com',      usedBy:['Kit Builder · Stack'], req:['license'] },
    { id:'acf-pro',        cat:'forms',    vendor:'ACF Pro',              fieldType:'key',       docs:'advancedcustomfields.com', usedBy:['Kit Builder · Stack'], req:['license'] },
    { id:'jetengine',      cat:'forms',    vendor:'JetEngine (CrocoBlock)', fieldType:'key',     docs:'crocoblock.com',       usedBy:['Kit Builder · Stack'], req:['license'] },

    /* ── Fonts & icons ── */
    { id:'adobe-fonts',    cat:'fonts',    vendor:'Adobe Fonts',          fieldType:'kit-id',    docs:'fonts.adobe.com',      usedBy:['Brand Profile','Kit Builder · Brand'], req:['kitId'] },
    { id:'font-awesome',   cat:'fonts',    vendor:'Font Awesome Pro',     fieldType:'kit-code',  docs:'fontawesome.com/kits', usedBy:['Kit Builder · Stack'], req:['kitCode'] },
    { id:'fontspring',     cat:'fonts',    vendor:'Fontspring / MyFonts', fieldType:'file',      docs:'fontspring.com',       usedBy:['Brand Profile'],       req:['licenseDoc'] },

    /* ── Media & assets ── */
    { id:'unsplash',       cat:'media',    vendor:'Unsplash',             fieldType:'key',       docs:'unsplash.com/developers', usedBy:['Kit Builder · Content','Image Tools'], req:['accessKey'] },
    { id:'pexels',         cat:'media',    vendor:'Pexels',               fieldType:'key',       docs:'pexels.com/api',       usedBy:['Kit Builder · Content','Image Tools'], req:['apiKey'] },
    { id:'pixabay',        cat:'media',    vendor:'Pixabay',              fieldType:'key',       docs:'pixabay.com/api/docs', usedBy:['Image Tools'], req:['apiKey'] },
    { id:'cloudinary',     cat:'media',    vendor:'Cloudinary',           fieldType:'cloud',     docs:'cloudinary.com/console', usedBy:['Image Tools','Sites'], req:['cloudName','apiKey','apiSecret'] },

    /* ── Integrations (future phase) ── */
    { id:'mailchimp',      cat:'integrations', vendor:'Mailchimp',        fieldType:'key',       docs:'mailchimp.com',        usedBy:['Marketing'], req:['apiKey'], phase:'future' },
    { id:'convertkit',     cat:'integrations', vendor:'ConvertKit',       fieldType:'key',       docs:'convertkit.com',       usedBy:['Marketing'], req:['apiKey'], phase:'future' },
    { id:'activecampaign', cat:'integrations', vendor:'ActiveCampaign',   fieldType:'api+url',   docs:'activecampaign.com',   usedBy:['Marketing'], req:['apiKey','apiUrl'], phase:'future' },
    { id:'hubspot',        cat:'integrations', vendor:'HubSpot',          fieldType:'key',       docs:'hubspot.com',          usedBy:['Marketing','CRM'], req:['apiKey'], phase:'future' },
    { id:'pipedrive',      cat:'integrations', vendor:'Pipedrive',        fieldType:'key',       docs:'pipedrive.com',        usedBy:['CRM'], req:['apiKey'], phase:'future' },
    { id:'stripe',         cat:'integrations', vendor:'Stripe',           fieldType:'key',       docs:'stripe.com',           usedBy:['Kit Builder · Stack (ecomm)','Billing'], req:['publishable','secret'], phase:'future' },
    { id:'paypal',         cat:'integrations', vendor:'PayPal',           fieldType:'key',       docs:'developer.paypal.com', usedBy:['Kit Builder · Stack (ecomm)','Billing'], req:['clientId','clientSecret'], phase:'future' },
    { id:'ga4',            cat:'integrations', vendor:'Google Analytics 4', fieldType:'id',      docs:'analytics.google.com', usedBy:['Kit Builder · Export','Scanner'], req:['measurementId'], phase:'future' },
    { id:'gtm',            cat:'integrations', vendor:'Google Tag Manager', fieldType:'id',      docs:'tagmanager.google.com', usedBy:['Kit Builder · Export'], req:['containerId'], phase:'future' },
    { id:'gbp',            cat:'integrations', vendor:'Google Business Profile', fieldType:'oauth', docs:'business.google.com', usedBy:['SEO','Marketing'], req:['oauth'], phase:'future' },
    { id:'yelp',           cat:'integrations', vendor:'Yelp Fusion',      fieldType:'key',       docs:'fusion.yelp.com',      usedBy:['SEO','Marketing'], req:['apiKey'], phase:'future' },
  ];

  const CATEGORIES = [
    { id:'builders',     label:'Page builders',       icon:'stack',    desc:'Required to generate sites with that builder' },
    { id:'forms',        label:'Forms & functionality', icon:'form',   desc:'Most kits use at least one forms plugin' },
    { id:'fonts',        label:'Fonts & icons',       icon:'brand',    desc:'Pulls font kits on build' },
    { id:'media',        label:'Media & assets',      icon:'image',    desc:'Stock imagery and CDN providers' },
    { id:'integrations', label:'Integrations',        icon:'plugin',   desc:'CRM, email, analytics, payments — future phase' },
  ];

  window.CREDENTIAL_CATALOG = CREDENTIAL_CATALOG;
  window.CREDENTIAL_CATEGORIES = CATEGORIES;

  /* ── Persistence ──────────────────────────────────────────────── */
  function loadVault() {
    try {
      const raw = localStorage.getItem(VAULT_KEY);
      const data = raw ? JSON.parse(raw) : {};
      // Pre-seed a few demo credentials so the UI shows both states
      if (!Object.keys(data).length) {
        return {
          'elementor-pro':  { values:{ license:'El-•••••••KP92' }, status:'valid',    expires:'2026-09-14', lastChecked:'5m ago', encrypted:true },
          'gravity-forms':  { values:{ license:'GF-•••••••8W1X' }, status:'valid',    expires:'2026-11-02', lastChecked:'5m ago', encrypted:true },
          'acf-pro':        { values:{ license:'ACF-••••••Q3M7' }, status:'valid',    expires:'2026-07-28', lastChecked:'5m ago', encrypted:true },
          'adobe-fonts':    { values:{ kitId:'sol2fbn'         }, status:'valid',    expires:null,         lastChecked:'3m ago', encrypted:true },
          'unsplash':       { values:{ accessKey:'UN-•••••9hGf' }, status:'valid',   expires:null,         lastChecked:'3m ago', encrypted:true },
          'jetengine':      { values:{ license:'JE-•••••••MX42' }, status:'expiring',expires:'2026-05-09', lastChecked:'1h ago', encrypted:true },
        };
      }
      return data;
    } catch { return {}; }
  }
  function saveVault(v) {
    try { localStorage.setItem(VAULT_KEY, JSON.stringify(v)); } catch {}
  }

  let _vaultState = loadVault();
  const _vaultSubs = new Set();
  const _notifyVault = () => _vaultSubs.forEach(fn => fn(_vaultState));

  /* ── Hook: useVault() ──────────────────────────────────────────
     Returns: [vault, update(id, patch), deleteKey(id), hasValid(id)] */
  window.useVault = function useVault() {
    const [state, setState] = useState(_vaultState);
    useEffect(() => {
      const fn = s => setState({ ...s });
      _vaultSubs.add(fn);
      return () => _vaultSubs.delete(fn);
    }, []);
    const update = (id, patch) => {
      _vaultState = { ..._vaultState, [id]: { ..._vaultState[id], ...patch } };
      saveVault(_vaultState); _notifyVault();
      window.wpsbToast?.(`${CREDENTIAL_CATALOG.find(c=>c.id===id)?.vendor || id} credentials saved`, 'ok');
    };
    const deleteKey = (id) => {
      const next = { ..._vaultState }; delete next[id];
      _vaultState = next; saveVault(_vaultState); _notifyVault();
      window.wpsbToast?.('Credentials removed from vault', 'ok');
    };
    const hasValid = (id) => {
      const v = _vaultState[id];
      return !!(v && v.status === 'valid' && Object.keys(v.values || {}).length);
    };
    return [state, update, deleteKey, hasValid];
  };

  /* ── Status helpers ───────────────────────────────────────────── */
  const STATUS_STYLES = {
    valid:    { bg:'rgba(20,184,132,.1)',  fg:'var(--green)', label:'VALID',    icon:'check' },
    expiring: { bg:'var(--orange-dim)', fg:'var(--orange)', label:'EXPIRING', icon:'clock' },
    invalid:  { bg:'var(--red-dim)',  fg:'var(--red)', label:'INVALID',  icon:'alert' },
    checking: { bg:'rgba(148,163,184,.12)',fg:'var(--dim)', label:'CHECKING', icon:'refresh' },
  };

  /* ── Sensitive value masker ───────────────────────────────────── */
  function mask(v) {
    if (!v || typeof v !== 'string') return '';
    if (v.length <= 6) return '•'.repeat(v.length);
    return v.slice(0, 3) + '•'.repeat(Math.max(5, v.length - 7)) + v.slice(-4);
  }

  /* ═══════════════════════════════════════════════════════════════
     CREDENTIAL CARD — one row per catalog entry
  ═══════════════════════════════════════════════════════════════ */
  function CredentialCard({ spec, vault, onUpdate, onDelete }) {
    const Icon = window.Icon;
    const cur = vault[spec.id];
    const hasValue = cur && Object.keys(cur.values || {}).length;
    const statusKey = cur?.status || 'invalid';
    const statusS = STATUS_STYLES[statusKey] || STATUS_STYLES.invalid;
    const [editing, setEditing] = useState(false);
    const [draft, setDraft] = useState(() => cur?.values || {});
    const [showValues, setShowValues] = useState(false);

    const fields = useMemo(() => {
      // Build field list from spec.req
      return (spec.req || []).map(r => {
        switch (r) {
          case 'license':       return { key:'license',       label:'License key',       type:'password', placeholder:'Paste license from vendor dashboard' };
          case 'apiKey':        return { key:'apiKey',        label:'API key',           type:'password', placeholder:'Paste API key' };
          case 'accessKey':     return { key:'accessKey',     label:'Access key',        type:'password', placeholder:'Paste access key' };
          case 'apiSecret':     return { key:'apiSecret',     label:'API secret',        type:'password', placeholder:'Paste secret' };
          case 'clientId':      return { key:'clientId',      label:'Client ID',         type:'text',     placeholder:'Client ID' };
          case 'clientSecret':  return { key:'clientSecret',  label:'Client secret',     type:'password', placeholder:'Paste secret' };
          case 'publishable':   return { key:'publishable',   label:'Publishable key',   type:'text',     placeholder:'pk_live_...' };
          case 'secret':        return { key:'secret',        label:'Secret key',        type:'password', placeholder:'sk_live_...' };
          case 'username':      return { key:'username',      label:'Account username',  type:'text',     placeholder:'Vendor account username' };
          case 'email':         return { key:'email',         label:'Account email',     type:'email',    placeholder:'account@agency.com' };
          case 'kitId':         return { key:'kitId',         label:'Kit ID',            type:'text',     placeholder:'e.g. sol2fbn' };
          case 'kitCode':       return { key:'kitCode',       label:'Kit code',          type:'text',     placeholder:'e.g. 1a2b3c4d' };
          case 'cloudName':     return { key:'cloudName',     label:'Cloud name',        type:'text',     placeholder:'your-cloud' };
          case 'apiUrl':        return { key:'apiUrl',        label:'API URL',           type:'url',      placeholder:'https://youracct.api-us1.com' };
          case 'measurementId': return { key:'measurementId', label:'Measurement ID',    type:'text',     placeholder:'G-XXXXXXXXXX' };
          case 'containerId':   return { key:'containerId',   label:'Container ID',      type:'text',     placeholder:'GTM-XXXXXXX' };
          case 'licenseDoc':    return { key:'licenseDoc',    label:'License PDF',       type:'file',     placeholder:'Upload license agreement' };
          case 'oauth':         return { key:'oauth',         label:'OAuth connection',  type:'oauth' };
          default:              return { key:r, label:r, type:'text' };
        }
      });
    }, [spec]);

    const save = () => {
      // Mock: validate against vendor API, then persist encrypted
      onUpdate(spec.id, {
        values: Object.fromEntries(
          Object.entries(draft).map(([k,v]) => [k, typeof v === 'string' && v.length > 8 ? v.slice(0,3) + '•'.repeat(Math.max(5, v.length - 7)) + v.slice(-4) : v])
        ),
        status: 'valid',
        lastChecked: 'just now',
        expires: cur?.expires || '2027-04-22',
        encrypted: true,
      });
      setEditing(false);
    };

    const isFuture = spec.phase === 'future';

    return (
      <div style={{
        padding:14, borderRadius:8,
        background: isFuture ? 'var(--surface)' : 'var(--surface-2)',
        border: hasValue ? '1px solid rgba(20,184,132,.3)' : '1px solid var(--border)',
        opacity: isFuture ? .6 : 1,
        position:'relative',
      }}>
        {/* Top row: vendor + status */}
        <div style={{ display:'flex', alignItems:'flex-start', justifyContent:'space-between', gap:12, marginBottom:10 }}>
          <div style={{ minWidth:0, flex:1 }}>
            <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:3 }}>
              <span style={{ fontSize:'.86rem', fontWeight:700 }}>{spec.vendor}</span>
              {spec.phase === 'future' && (
                <span className="tag" style={{ fontSize:'.54rem', background:'rgba(148,163,184,.15)', color:'var(--dim)' }}>PHASE 2</span>
              )}
            </div>
            <div style={{ fontSize:'.64rem', color:'var(--dim)', lineHeight:1.4 }}>
              Used by: {(spec.usedBy || []).join(' · ')}
            </div>
          </div>

          <div style={{
            display:'flex', alignItems:'center', gap:5,
            padding:'4px 8px', borderRadius:4,
            background: statusS.bg, color: statusS.fg,
            fontSize:'.58rem', fontWeight:700, letterSpacing:'.06em',
            flexShrink:0,
          }}>
            <Icon name={statusS.icon} size={10}/>
            {hasValue ? statusS.label : 'NOT SET'}
          </div>
        </div>

        {/* Body: values or CTA */}
        {!editing && hasValue && (
          <div style={{ marginBottom:10 }}>
            {fields.map(f => (
              <div key={f.key} style={{ display:'flex', alignItems:'center', gap:8, padding:'6px 10px', background:'var(--surface)', borderRadius:4, marginBottom:4, fontFamily:'var(--font-mono)', fontSize:'.68rem' }}>
                <span style={{ color:'var(--dim)', textTransform:'uppercase', fontSize:'.54rem', letterSpacing:'.08em', minWidth:72 }}>{f.label}</span>
                <span style={{ color:'var(--muted)', flex:1, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
                  {showValues ? (cur.values[f.key] || '—') : mask(cur.values[f.key] || '')}
                </span>
              </div>
            ))}
            <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginTop:6, fontSize:'.62rem', color:'var(--dim)' }}>
              <span>
                {cur.expires && <>Expires <strong style={{ color:'var(--muted)' }}>{cur.expires}</strong> · </>}
                Checked {cur.lastChecked}
              </span>
              <button onClick={() => setShowValues(!showValues)} style={{ background:'none', border:'none', color:'var(--beam)', fontSize:'.62rem', cursor:'pointer', fontFamily:'inherit' }}>
                {showValues ? '🔒 Hide' : '👁 Reveal'}
              </button>
            </div>
          </div>
        )}

        {!editing && !hasValue && (
          <div style={{ padding:'10px 12px', background:'var(--surface)', borderRadius:4, marginBottom:10, fontSize:'.68rem', color:'var(--dim)', lineHeight:1.5 }}>
            No credentials set. Add your {spec.vendor} credentials to enable automated setup in Kit Builder / Site Builder.
          </div>
        )}

        {editing && (
          <div style={{ marginBottom:10 }}>
            {fields.map(f => (
              <div key={f.key} style={{ marginBottom:8 }}>
                <div style={{ fontSize:'.6rem', color:'var(--dim)', marginBottom:3, textTransform:'uppercase', letterSpacing:'.06em', fontWeight:700 }}>{f.label}</div>
                {f.type === 'file' ? (
                  <input type="file" accept=".pdf,.doc,.docx,.png,.jpg" style={{ width:'100%', padding:'7px 10px', fontSize:'.72rem', background:'var(--surface)', border:'1px solid var(--border)', borderRadius:4, color:'var(--text)', fontFamily:'inherit' }}/>
                ) : f.type === 'oauth' ? (
                  <button style={{ padding:'8px 14px', fontSize:'.72rem', background:'var(--beam)', color:'#001018', border:'none', borderRadius:4, cursor:'pointer', fontFamily:'inherit', fontWeight:600 }}>Connect via OAuth →</button>
                ) : (
                  <input type={f.type} placeholder={f.placeholder}
                         defaultValue={cur?.values?.[f.key] || ''}
                         onChange={e => setDraft({...draft, [f.key]:e.target.value})}
                         autoComplete="off" spellCheck="false"
                         style={{ width:'100%', padding:'7px 10px', fontSize:'.72rem', fontFamily:'var(--font-mono)', background:'var(--surface)', border:'1px solid var(--border)', borderRadius:4, color:'var(--text)' }}/>
                )}
              </div>
            ))}
          </div>
        )}

        {/* Actions */}
        <div style={{ display:'flex', gap:6, alignItems:'center' }}>
          {!editing && !isFuture && (
            <>
              <button onClick={() => setEditing(true)}
                      style={{ padding:'6px 12px', fontSize:'.68rem', borderRadius:4, cursor:'pointer', background: hasValue ? 'var(--surface)' : 'var(--beam)', color: hasValue ? 'var(--text)' : '#001018', border: hasValue ? '1px solid var(--border)' : 'none', fontFamily:'inherit', fontWeight:600 }}>
                {hasValue ? 'Update' : '+ Add credentials'}
              </button>
              {hasValue && (
                <button onClick={() => onDelete(spec.id)}
                        style={{ padding:'6px 10px', fontSize:'.68rem', background:'none', color:'var(--rose)', border:'1px solid var(--border)', borderRadius:4, cursor:'pointer', fontFamily:'inherit' }}>
                  Revoke
                </button>
              )}
            </>
          )}
          {editing && (
            <>
              <button onClick={save} style={{ padding:'6px 14px', fontSize:'.68rem', background:'var(--beam)', color:'#001018', border:'none', borderRadius:4, cursor:'pointer', fontFamily:'inherit', fontWeight:700 }}>
                Validate &amp; save
              </button>
              <button onClick={() => { setEditing(false); setDraft(cur?.values || {}); }}
                      style={{ padding:'6px 10px', fontSize:'.68rem', background:'none', color:'var(--muted)', border:'1px solid var(--border)', borderRadius:4, cursor:'pointer', fontFamily:'inherit' }}>
                Cancel
              </button>
            </>
          )}
          <div style={{ flex:1 }}/>
          <a href={`https://${spec.docs}`} target="_blank" rel="noopener noreferrer"
             style={{ fontSize:'.62rem', color:'var(--dim)', textDecoration:'none' }}>
            {spec.docs} ↗
          </a>
        </div>
      </div>
    );
  }

  /* ═══════════════════════════════════════════════════════════════
     MAIN TAB
  ═══════════════════════════════════════════════════════════════ */
  function CredentialVaultTab() {
    const Icon = window.Icon;
    const [vault, update, deleteKey] = window.useVault();
    const [filter, setFilter] = useState('all');
    const [search, setSearch] = useState('');

    const counts = useMemo(() => {
      const c = { total:CREDENTIAL_CATALOG.length, valid:0, expiring:0, invalid:0, unset:0 };
      CREDENTIAL_CATALOG.forEach(spec => {
        const v = vault[spec.id];
        if (!v || !Object.keys(v.values || {}).length) c.unset++;
        else if (v.status === 'valid') c.valid++;
        else if (v.status === 'expiring') c.expiring++;
        else c.invalid++;
      });
      return c;
    }, [vault]);

    const filteredCats = CATEGORIES.filter(cat => filter === 'all' || cat.id === filter);

    return (
      <div style={{ marginTop:16 }}>
        {/* Security explainer */}
        <div style={{
          padding:'14px 16px', marginBottom:16, borderRadius:8,
          background:'linear-gradient(135deg, var(--orange-dim), rgba(20,184,132,.04))',
          border:'1px solid var(--border)',
          display:'flex', alignItems:'flex-start', gap:12,
        }}>
          <div style={{
            width:36, height:36, borderRadius:8, flexShrink:0,
            background:'rgba(20,184,132,.12)', color:'var(--green)',
            display:'flex', alignItems:'center', justifyContent:'center',
          }}>
            <Icon name="shield" size={18}/>
          </div>
          <div style={{ flex:1 }}>
            <div style={{ fontSize:'.92rem', fontWeight:700, marginBottom:4 }}>🔐 Encrypted vault · per-user scoped</div>
            <div style={{ fontSize:'.72rem', color:'var(--muted)', lineHeight:1.55 }}>
              All licenses and API keys are envelope-encrypted (AES-256-GCM) and scoped to your account only — team members see install-status only, never keys. Stored in isolated vault · TLS + HMAC transit · re-validated weekly against each vendor's API. Revoke any key anywhere and it kill-switches in under 60 seconds.
            </div>
            <div style={{ display:'flex', gap:16, marginTop:8, fontSize:'.68rem', color:'var(--dim)', flexWrap:'wrap' }}>
              <span>🔒 AES-256-GCM at rest</span>
              <span>🛡 TLS 1.3 in transit</span>
              <span>👤 Per-user scoped · no sharing</span>
              <span>⚡ Weekly auto-validation</span>
              <span>🗝 KMS envelope keys</span>
            </div>
          </div>
        </div>

        {/* Stats row */}
        <div className="grid" style={{ gridTemplateColumns:'repeat(5, 1fr)', gap:10, marginBottom:14 }}>
          {[
            { label:'Total',     n:counts.total,     color:'var(--text)' },
            { label:'Valid',     n:counts.valid,     color:'var(--green)' },
            { label:'Expiring',  n:counts.expiring,  color:'var(--orange)' },
            { label:'Invalid',   n:counts.invalid,   color:'var(--red)' },
            { label:'Not set',   n:counts.unset,     color:'var(--dim)' },
          ].map(s => (
            <div key={s.label} style={{ padding:'10px 14px', background:'var(--surface-2)', borderRadius:6, border:'1px solid var(--border)' }}>
              <div style={{ fontSize:'.58rem', color:'var(--dim)', textTransform:'uppercase', letterSpacing:'.08em', marginBottom:4, fontWeight:700 }}>{s.label}</div>
              <div style={{ fontSize:'1.6rem', fontWeight:800, color:s.color, lineHeight:1 }}>{s.n}</div>
            </div>
          ))}
        </div>

        {/* Filter + search */}
        <div style={{ display:'flex', gap:8, marginBottom:14, alignItems:'center', flexWrap:'wrap' }}>
          <div style={{ display:'flex', gap:4, background:'var(--surface-2)', padding:3, borderRadius:6 }}>
            {[{ id:'all', label:'All' }, ...CATEGORIES.map(c => ({ id:c.id, label:c.label }))].map(f => (
              <button key={f.id} onClick={() => setFilter(f.id)}
                      style={{
                        padding:'6px 12px', fontSize:'.7rem', borderRadius:4, cursor:'pointer',
                        background: filter === f.id ? 'var(--beam)' : 'transparent',
                        color: filter === f.id ? '#001018' : 'var(--muted)',
                        border:'none', fontFamily:'inherit', fontWeight:600,
                      }}>{f.label}</button>
            ))}
          </div>
          <input placeholder="Search vendor..." value={search} onChange={e => setSearch(e.target.value)}
                 style={{ flex:1, minWidth:200, padding:'7px 12px', fontSize:'.74rem', background:'var(--surface-2)', border:'1px solid var(--border)', borderRadius:6, color:'var(--text)', fontFamily:'inherit' }}/>
          <button style={{ padding:'7px 12px', fontSize:'.7rem', background:'var(--surface-2)', border:'1px solid var(--border)', borderRadius:6, color:'var(--muted)', cursor:'pointer', fontFamily:'inherit', display:'flex', alignItems:'center', gap:5 }}>
            <Icon name="refresh" size={11}/>Re-validate all
          </button>
        </div>

        {/* Categories */}
        {filteredCats.map(cat => {
          const items = CREDENTIAL_CATALOG
            .filter(c => c.cat === cat.id)
            .filter(c => !search || c.vendor.toLowerCase().includes(search.toLowerCase()));
          if (!items.length) return null;
          return (
            <div key={cat.id} style={{ marginBottom:20 }}>
              <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:10, paddingBottom:8, borderBottom:'1px solid var(--border)' }}>
                <Icon name={cat.icon} size={14} style={{ color:'var(--beam)' }}/>
                <div style={{ fontSize:'.88rem', fontWeight:700 }}>{cat.label}</div>
                <div style={{ fontSize:'.66rem', color:'var(--dim)' }}>· {cat.desc}</div>
                <div style={{ flex:1 }}/>
                <div style={{ fontSize:'.62rem', color:'var(--muted)' }}>{items.length} providers</div>
              </div>
              <div className="grid" style={{ gridTemplateColumns:'repeat(auto-fill, minmax(340px, 1fr))', gap:10 }}>
                {items.map(spec => (
                  <CredentialCard key={spec.id} spec={spec} vault={vault} onUpdate={update} onDelete={deleteKey}/>
                ))}
              </div>
            </div>
          );
        })}

        {/* Audit trail */}
        <div style={{ marginTop:24, padding:14, background:'var(--surface-2)', borderRadius:8, border:'1px solid var(--border)' }}>
          <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:10 }}>
            <Icon name="clock" size={13}/>
            <div style={{ fontSize:'.82rem', fontWeight:700 }}>Recent activity</div>
            <div style={{ flex:1 }}/>
            <button style={{ background:'none', border:'none', color:'var(--beam)', fontSize:'.66rem', cursor:'pointer', fontFamily:'inherit' }}>View full log →</button>
          </div>
          <div style={{ display:'flex', flexDirection:'column', gap:4, fontSize:'.7rem', fontFamily:'var(--font-mono)' }}>
            {[
              { t:'just now',   who:'you',    action:'re-validated',  target:'Adobe Fonts (sol2fbn)', ok:true },
              { t:'5 min ago',  who:'system', action:'weekly check',  target:'6 credentials · all valid', ok:true },
              { t:'1 hour ago', who:'system', action:'expiring soon', target:'JetEngine license (18 days)', ok:false },
              { t:'Mon 2:14p',  who:'you',    action:'added',         target:'Unsplash API access key', ok:true },
              { t:'Apr 8',      who:'you',    action:'revoked',       target:'old Stripe test keys', ok:true },
            ].map((e, i) => (
              <div key={i} style={{ display:'grid', gridTemplateColumns:'80px 1fr auto', gap:10, padding:'5px 0', borderBottom: i < 4 ? '1px solid var(--border)' : 'none' }}>
                <span style={{ color:'var(--dim)' }}>{e.t}</span>
                <span><span style={{ color:e.ok ? 'var(--green)' : 'var(--orange)' }}>●</span> <span style={{ color:'var(--muted)' }}>{e.who}</span> {e.action} <span style={{ color:'var(--text)' }}>{e.target}</span></span>
                <span style={{ color:'var(--dim)' }}>{e.ok ? '✓' : '⚠'}</span>
              </div>
            ))}
          </div>
        </div>
      </div>
    );
  }

  window.CredentialVaultTab = CredentialVaultTab;
})();
