// tab-toolbox.jsx — Toolbox, redesigned as two focused views:
//   Assets → the fundraising asset library (search · status filter · category
//            chips · click-to-open tiles · modal editor). Backed by `assets`.
//   Gives  → Monthly Gives review (the research piece touch 2 shares):
//            approved give pinned on top, candidates by month below.
// Same data API as before (RaiseLiveData.assets/gives); presentation only.
const { useState, useEffect, useMemo } = React;
const TS = window.RaiseShell;

const CAT_ORDER = ['Investor Documents','Value-Add Tools','Webinars & Presentations','Outreach Assets','Links & Accounts'];
const KINDS = ['doc','deck','tool','page','link','sheet'];
const KIND_META = {
  doc:  { c:'var(--primary)', glyph:'▤', label:'Document' },
  deck: { c:'#8159bf',        glyph:'▦', label:'Deck' },
  tool: { c:'#1d9e75',        glyph:'⚙', label:'Tool' },
  page: { c:'#ba7517',        glyph:'◫', label:'Page' },
  link: { c:'#3f9560',        glyph:'↗', label:'Link' },
  sheet:{ c:'var(--ink-3)',   glyph:'▥', label:'Sheet' },
};
const kindMeta = (k)=> KIND_META[k] || KIND_META.doc;

function useLiveTick(){
  const [, force] = useState(0);
  useEffect(()=>{ const h=()=>force(x=>x+1); window.addEventListener('raise-livedata', h); return ()=>window.removeEventListener('raise-livedata', h); }, []);
}

const openUrl = (u)=>{ if(u) window.open(u, '_blank', 'noopener'); };
const copyPath = (p)=>{ if(!p) return; try{ navigator.clipboard.writeText(p); TS.toast('Path copied — paste in Finder (Cmd+Shift+G)'); }catch(_){ TS.toast(p); } };

// ── shared field style ──────────────────────────────────────────────────────
const inStyle = {fontSize:13, padding:'7px 9px', border:'1px solid var(--line,#e7e2d7)', borderRadius:8, background:'var(--surface,#fff)', color:'var(--ink)', width:'100%', boxSizing:'border-box'};
const labStyle = {fontSize:11, fontWeight:600, color:'var(--ink-3)', textTransform:'uppercase', letterSpacing:.4, display:'block', marginBottom:4};

// ── asset editor: centered modal (never shoves the library around) ──────────
function AssetModal({ initial, cats, onClose }){
  const RLD = window.RaiseLiveData;
  const [a, setA] = useState(initial);
  const [busy, setBusy] = useState(false);
  const set = (k,v)=> setA(x=>({ ...x, [k]:v }));
  const save = ()=>{
    if(!a.name || !a.name.trim()){ TS.toast('Name required'); return; }
    setBusy(true);
    const payload = { name:a.name.trim(), category:a.category, kind:a.kind, status:a.status, url:(a.url||'').trim()||null, path:(a.path||'').trim()||null };
    const p = a.isNew ? RLD.addAsset(payload) : RLD.patchAsset(a.id, payload);
    Promise.resolve(p).then(()=>{ setBusy(false); TS.toast('Saved ✓'); onClose(); })
      .catch(()=>{ setBusy(false); TS.toast('Could not save'); });
  };
  const del = ()=>{
    if(!window.confirm('Remove "'+(a.name||'this item')+'" from the toolbox?')) return;
    setBusy(true);
    RLD.deleteAsset(a.id).then(()=>{ setBusy(false); TS.toast('Removed'); onClose(); })
      .catch(()=>{ setBusy(false); TS.toast('Could not remove'); });
  };
  return (
    <div style={{position:'fixed', inset:0, zIndex:400, background:'rgba(40,34,28,.34)', display:'flex', alignItems:'center', justifyContent:'center'}} onClick={onClose}>
      <div onClick={e=>e.stopPropagation()}
        style={{width:520, maxWidth:'94vw', maxHeight:'88vh', overflow:'auto', background:'var(--surface,#fff)', border:'1px solid var(--line,#e6dfd4)', borderRadius:14, boxShadow:'0 24px 60px rgba(0,0,0,.24)', padding:20}}>
        <div style={{fontSize:16, fontWeight:700, marginBottom:14}}>{a.isNew?'Add to toolbox':'Edit item'}</div>
        <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:12}}>
          <div style={{gridColumn:'1 / -1'}}><span style={labStyle}>Name</span>
            <input style={inStyle} autoFocus value={a.name} placeholder="e.g. Fund II one-pager" onChange={e=>set('name', e.target.value)}
              onKeyDown={e=>{ if(e.key==='Enter') save(); }} /></div>
          <div><span style={labStyle}>Category</span>
            <select style={inStyle} value={a.category} onChange={e=>set('category', e.target.value)}>
              {cats.map(c=><option key={c} value={c}>{c}</option>)}</select></div>
          <div><span style={labStyle}>Type</span>
            <select style={inStyle} value={a.kind} onChange={e=>set('kind', e.target.value)}>
              {KINDS.map(k=><option key={k} value={k}>{kindMeta(k).label}</option>)}</select></div>
          <div style={{gridColumn:'1 / -1'}}><span style={labStyle}>Link (URL)</span>
            <input style={inStyle} value={a.url||''} placeholder="https://… (opens on click)" onChange={e=>set('url', e.target.value)} /></div>
          <div style={{gridColumn:'1 / -1'}}><span style={labStyle}>Local path</span>
            <input style={inStyle} value={a.path||''} placeholder="Fundraising Toolbox/… (copies on click)" onChange={e=>set('path', e.target.value)} /></div>
          <div style={{gridColumn:'1 / -1'}}><span style={labStyle}>Status</span>
            <div style={{display:'flex', gap:6}}>
              {[['made','✓ Made'],['todo','To make']].map(([v,l])=>(
                <button key={v} onClick={()=>set('status', v)}
                  style={{flex:1, padding:'7px 10px', fontSize:13, borderRadius:8, cursor:'pointer',
                    border:'1px solid '+(a.status===v?'var(--primary,#c96442)':'var(--line,#e7e2d7)'),
                    background:a.status===v?'rgba(201,100,66,.08)':'transparent', color:'inherit', fontWeight:a.status===v?600:400}}>{l}</button>
              ))}
            </div></div>
        </div>
        <div style={{display:'flex', gap:8, marginTop:16}}>
          <button className="btn primary sm" disabled={busy} onClick={save}>{busy?'Saving…':'Save'}</button>
          <button className="btn sm" onClick={onClose}>Cancel</button>
          {!a.isNew && <button className="btn sm" disabled={busy} style={{marginLeft:'auto', color:'var(--rose)'}} onClick={del}>Delete</button>}
        </div>
      </div>
    </div>
  );
}

// ── one asset card: the CARD is the action (open link / copy path) ──────────
function AssetTile({ a, live, onEdit }){
  const RLD = window.RaiseLiveData;
  const km = kindMeta(a.kind);
  const primary = a.url ? 'open' : a.path ? 'copy' : 'edit';
  const act = ()=>{ if(primary==='open') openUrl(a.url); else if(primary==='copy') copyPath(a.path); else onEdit(a); };
  const toggle = (e)=>{ e.stopPropagation(); if(!live) return;
    RLD.patchAsset(a.id,{status:a.status==='made'?'todo':'made'})
      .then(()=>TS.toast(a.status==='made'?'Marked to-make':'Marked made ✓')).catch(()=>TS.toast('Could not save')); };
  const made = a.status==='made';
  const sub = a.url ? a.url.replace(/^https?:\/\/(www\.)?/,'') : (a.path || '');
  return (
    <div onClick={act} title={primary==='open'?'Open link':primary==='copy'?'Copy the file path':'Edit'}
      style={{background:'var(--surface,#fff)', border:'1px solid var(--line,#e7e2d7)', borderRadius:12, padding:'12px 13px',
        display:'flex', flexDirection:'column', gap:6, minHeight:92, cursor:'pointer', opacity: made?1:.92}}>
      <div style={{display:'flex', alignItems:'center', gap:8}}>
        <span style={{width:22, height:22, borderRadius:6, display:'grid', placeItems:'center', fontSize:12, fontWeight:700, color:'#fff', background:km.c, flex:'0 0 auto'}}>{km.glyph}</span>
        <span style={{fontSize:14, fontWeight:600, color:'var(--ink)', lineHeight:1.3, minWidth:0, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>{a.name}</span>
        <button onClick={toggle} title={live?'Toggle made / to-make':''}
          style={{marginLeft:'auto', flex:'0 0 auto', fontSize:11, padding:'2px 9px', borderRadius:20, border:'none', cursor:live?'pointer':'default',
            background: made?'rgba(63,149,96,.14)':'var(--surface-2,#f1efe8)', color: made?'#2f7a4c':'var(--ink-3)', fontWeight:600}}>
          {made?'✓ Made':'To make'}
        </button>
      </div>
      {sub && <div style={{fontSize:11.5, color:'var(--ink-3)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}} title={a.url||a.path}>{sub}</div>}
      <div style={{display:'flex', gap:10, marginTop:'auto', alignItems:'center'}}>
        <span style={{fontSize:11, color:km.c, fontWeight:600}}>{primary==='open'?'Open ↗':primary==='copy'?'Click to copy path':'Add a link or path'}</span>
        {a.url && a.path && <button className="linkbtn" style={{fontSize:11}} onClick={e=>{ e.stopPropagation(); copyPath(a.path); }}>Copy path</button>}
        <button className="linkbtn" style={{marginLeft:'auto', fontSize:11}} onClick={e=>{ e.stopPropagation(); onEdit(a); }}>Edit</button>
      </div>
    </div>
  );
}

// ── Assets view: search · status filter · category chips · grouped grid ─────
function AssetsView(){
  const RLD = window.RaiseLiveData;
  const live = !!(RLD && RLD.assets);
  const assets = live ? RLD.assets() : [];
  const [q, setQ] = useState('');
  const [statusF, setStatusF] = useState('all');     // all | made | todo
  const [catF, setCatF] = useState('all');
  const [edit, setEdit] = useState(null);

  const cats = useMemo(()=>[...CAT_ORDER, ...Array.from(new Set(assets.map(a=>a.category))).filter(c=>!CAT_ORDER.includes(c))], [assets.length]);
  const filtered = useMemo(()=>{
    const s = q.trim().toLowerCase();
    return assets.filter(a=>
      (statusF==='all' || a.status===statusF) &&
      (catF==='all' || a.category===catF) &&
      (!s || (a.name+' '+(a.url||'')+' '+(a.path||'')+' '+a.category).toLowerCase().includes(s)));
  }, [assets, q, statusF, catF]);
  const made = assets.filter(a=>a.status==='made').length;
  const todoN = assets.length - made;

  const chip = (on)=>({fontSize:12, padding:'4px 11px', borderRadius:20, cursor:'pointer', whiteSpace:'nowrap',
    border:'1px solid '+(on?'var(--primary,#c96442)':'var(--line,#e7e2d7)'),
    background:on?'rgba(201,100,66,.08)':'transparent', color:on?'var(--primary)':'var(--ink-2)', fontWeight:on?600:400});

  return (
    <>
      {/* toolbar: search + status + add */}
      <div style={{display:'flex', gap:8, alignItems:'center', flexWrap:'wrap', margin:'2px 0 10px'}}>
        <div style={{position:'relative', flex:'1 1 220px', maxWidth:340}}>
          <input value={q} onChange={e=>setQ(e.target.value)} placeholder="Search assets…"
            style={{...inStyle, paddingLeft:30}} />
          <span style={{position:'absolute', left:10, top:'50%', transform:'translateY(-50%)', color:'var(--ink-3)', fontSize:13}}>⌕</span>
          {q && <button onClick={()=>setQ('')} style={{position:'absolute', right:8, top:'50%', transform:'translateY(-50%)', border:'none', background:'none', cursor:'pointer', color:'var(--ink-3)'}}>✕</button>}
        </div>
        <div style={{display:'flex', gap:5}}>
          <button style={chip(statusF==='all')} onClick={()=>setStatusF('all')}>All · {assets.length}</button>
          <button style={chip(statusF==='made')} onClick={()=>setStatusF('made')}>✓ Made · {made}</button>
          <button style={chip(statusF==='todo')} onClick={()=>setStatusF('todo')}>To make · {todoN}</button>
        </div>
        <button className="btn primary sm" style={{marginLeft:'auto'}}
          onClick={()=>setEdit({isNew:true, name:'', category: catF!=='all'?catF:(cats[0]||'Investor Documents'), kind:'doc', status:'todo', url:'', path:''})}>+ Add item</button>
      </div>

      {/* category chips */}
      <div style={{display:'flex', gap:5, flexWrap:'wrap', marginBottom:14}}>
        <button style={chip(catF==='all')} onClick={()=>setCatF('all')}>All categories</button>
        {cats.map(c=>{
          const n = assets.filter(a=>a.category===c).length;
          if(!n) return null;
          return <button key={c} style={chip(catF===c)} onClick={()=>setCatF(catF===c?'all':c)}>{c} · {n}</button>;
        })}
      </div>

      {!live && <div className="muted" style={{fontSize:13, padding:'20px 0', textAlign:'center'}}>Sign in to load your toolbox.</div>}
      {live && assets.length===0 && (
        <div style={{textAlign:'center', padding:'40px 0'}}>
          <div style={{fontSize:15, fontWeight:600, marginBottom:6}}>Your toolbox is empty</div>
          <div className="muted" style={{fontSize:13, marginBottom:14}}>Add the assets you send LPs and partners — decks, one-pagers, data-room links, tools.</div>
          <button className="btn primary sm" onClick={()=>setEdit({isNew:true, name:'', category:cats[0]||'Investor Documents', kind:'doc', status:'todo', url:'', path:''})}>+ Add your first item</button>
        </div>
      )}
      {live && assets.length>0 && filtered.length===0 && (
        <div className="muted" style={{fontSize:13, padding:'24px 0', textAlign:'center'}}>Nothing matches{q?' “'+q+'”':''} — clear the filters above.</div>
      )}

      {cats.map(cat=>{
        if(catF!=='all' && catF!==cat) return null;
        const items = filtered.filter(a=>a.category===cat);
        if(!items.length) return null;
        const cm = items.filter(a=>a.status==='made').length;
        return (
          <div key={cat} style={{marginBottom:22}}>
            <div style={{display:'flex', alignItems:'baseline', gap:8, margin:'0 0 10px'}}>
              <span style={{fontSize:13, fontWeight:700, color:'var(--ink)'}}>{cat}</span>
              <span style={{fontSize:11, color:'var(--ink-3)'}}>{cm}/{items.length} made</span>
            </div>
            <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(240px, 1fr))', gap:12}}>
              {items.map(a=> <AssetTile key={a.id} a={a} live={live} onEdit={setEdit} />)}
            </div>
          </div>
        );
      })}

      {edit && <AssetModal initial={edit} cats={cats} onClose={()=>setEdit(null)} />}
    </>
  );
}

// ── Gives view: approved give pinned, candidates by month ───────────────────
function GivesView(){
  const RLD = window.RaiseLiveData;
  const [busy, setBusy] = useState(null);
  const [findOpen, setFindOpen] = useState(false);
  const [angle, setAngle] = useState('');
  const [searching, setSearching] = useState(false);
  const [showArchived, setShowArchived] = useState(false);
  useEffect(()=>{ if(RLD && RLD.loadGives && !RLD._givesOk) RLD.loadGives(); }, []);
  const live = !!(RLD && RLD.gives);
  const all = live ? RLD.gives() : [];
  const gives = all.filter(g=> showArchived ? true : g.status!=='archived');
  const approved = all.filter(g=>g.status==='approved')
    .sort((a,b)=> String(b.month||'').localeCompare(String(a.month||'')));

  const findMore = ()=>{
    setSearching(true);
    Promise.resolve(RLD.requestGiveScout(angle)).then(r=>{
      setSearching(false); setFindOpen(false); setAngle('');
      TS.toast(r&&r.ok ? 'Searching — new options appear here in a few minutes' : 'Could not start search');
    });
  };
  const approve = (g)=>{ setBusy(g.id); Promise.resolve(RLD.approveGive(g)).then(r=>{ setBusy(null); TS.toast(r&&r.ok?'Approved — now sending in outreach ✓':'Could not approve'); }); };
  const archive = (g)=>{ setBusy(g.id); Promise.resolve(RLD.setGiveStatus(g.id,'archived')).then(()=>{ setBusy(null); TS.toast('Archived'); }).catch(()=>{ setBusy(null); TS.toast('Could not save'); }); };
  const restore = (g)=>{ setBusy(g.id); Promise.resolve(RLD.setGiveStatus(g.id,'candidate')).then(()=>{ setBusy(null); TS.toast('Restored to candidates'); }).catch(()=>{ setBusy(null); TS.toast('Could not save'); }); };
  const fmtMonth = (m)=>{ try{ const [y,mo]=m.split('-'); return new Date(y, mo-1, 1).toLocaleString('en-US',{month:'long',year:'numeric'}); }catch(_){ return m; } };

  const Card = ({ g })=>{
    const isAppr = g.status==='approved';
    const isArch = g.status==='archived';
    return (
      <div style={{background:'var(--surface,#fff)', border:'1px solid '+(isAppr?'#1d9e75':'var(--line,#e7e2d7)'), borderRadius:12, padding:'12px 13px',
        display:'flex', flexDirection:'column', gap:7, boxShadow:isAppr?'0 0 0 1px #1d9e75 inset':'none', opacity:isArch?.6:1}}>
        <div style={{display:'flex', alignItems:'center', gap:8}}>
          {g.rating!=null && <span style={{fontSize:10, fontWeight:700, color:'var(--ink-3)', border:'1px solid var(--line,#e7e2d7)', borderRadius:5, padding:'1px 5px'}}>{g.rating}/10</span>}
          {g.topic && <span style={{fontSize:11, color:'var(--ink-3)'}}>{g.topic}</span>}
          <span style={{marginLeft:'auto', fontSize:11, color:isAppr?'#2f7a4c':'var(--ink-3)', fontWeight:isAppr?600:400}}>
            {isAppr?'✓ Approved · sending now':isArch?'archived':'candidate'}</span>
        </div>
        <div style={{fontSize:14, fontWeight:600, color:'var(--ink)', lineHeight:1.3}}>{g.title}</div>
        {g.hook && <div style={{fontSize:12.5, color:'var(--ink-2)', lineHeight:1.45}}>{g.hook}</div>}
        {g.source && <div style={{fontSize:11, color:'var(--ink-3)'}}>{g.source}</div>}
        <div style={{display:'flex', gap:8, alignItems:'center', marginTop:3}}>
          {!isAppr && !isArch && <button className="btn primary sm" disabled={busy===g.id} onClick={()=>approve(g)} style={{fontSize:12}}>Approve</button>}
          {g.url && <button className="btn sm" onClick={()=>openUrl(g.url)} style={{fontSize:12}}>Read ↗</button>}
          {isArch
            ? <button className="linkbtn" style={{marginLeft:'auto'}} onClick={()=>restore(g)}>Restore</button>
            : <button className="linkbtn" style={{marginLeft:'auto'}} onClick={()=>archive(g)}>Archive</button>}
        </div>
      </div>
    );
  };

  const months = Array.from(new Set(gives.filter(g=>g.status!=='approved').map(g=>g.month))).sort().reverse();

  return (
    <>
      <div style={{display:'flex', gap:8, alignItems:'center', flexWrap:'wrap', margin:'2px 0 12px'}}>
        <div style={{fontSize:12.5, color:'var(--ink-2)'}}>The <b>give</b> is the research piece outreach touch 2 shares — approve one per month so drafts never invent content.</div>
        <span style={{marginLeft:'auto', display:'flex', gap:10, alignItems:'center'}}>
          <button className="linkbtn" onClick={()=>setShowArchived(v=>!v)}>{showArchived?'Hide archived':'Show archived'}</button>
          <button className="linkbtn" onClick={()=>RLD.loadGives && RLD.loadGives().then(()=>TS.toast('Refreshed'))}>Refresh</button>
          <button className="btn primary sm" onClick={()=>setFindOpen(v=>!v)}>✦ Find more</button>
        </span>
      </div>

      {findOpen && (
        <div style={{background:'var(--surface,#fff)', border:'1px solid var(--primary)', borderRadius:12, padding:'12px 13px', margin:'0 0 14px', display:'flex', gap:8, alignItems:'center', flexWrap:'wrap'}}>
          <span style={{fontSize:12.5, color:'var(--ink-2)'}}>Pull a fresh batch — optionally steer the angle:</span>
          <input value={angle} onChange={e=>setAngle(e.target.value)} placeholder="e.g. exchange funds, RSU timing (optional)"
            style={{...inStyle, flex:1, minWidth:200, width:'auto'}} onKeyDown={e=>{ if(e.key==='Enter') findMore(); }} />
          <button className="btn primary sm" disabled={searching} onClick={findMore}>{searching?'Starting…':'Search'}</button>
          <button className="btn sm" onClick={()=>setFindOpen(false)}>Cancel</button>
        </div>
      )}

      {!live && <div className="muted" style={{fontSize:13, padding:'20px 0', textAlign:'center'}}>Sign in to load your gives.</div>}
      {live && !all.length && <div className="muted" style={{fontSize:13, padding:'20px 0', textAlign:'center'}}>No gives yet — hit “Find more” to pull a batch, or wait for the monthly scout.</div>}

      {approved.length>0 && (
        <div style={{marginBottom:20}}>
          <div style={{fontSize:12, fontWeight:700, color:'#2f7a4c', margin:'0 0 8px'}}>SENDING NOW</div>
          <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(280px, 1fr))', gap:12}}>
            {approved.map(g=> <Card key={g.id} g={g} />)}
          </div>
        </div>
      )}

      {months.map(m=>{
        const items = gives.filter(g=>g.month===m && g.status!=='approved').sort((a,b)=>(b.rating||0)-(a.rating||0));
        if(!items.length) return null;
        return (
          <div key={m} style={{marginBottom:18}}>
            <div style={{fontSize:12, fontWeight:600, color:'var(--ink-3)', margin:'0 0 8px'}}>{fmtMonth(m)}</div>
            <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(280px, 1fr))', gap:12}}>
              {items.map(g=> <Card key={g.id} g={g} />)}
            </div>
          </div>
        );
      })}
    </>
  );
}

// ── main: two subviews behind a segmented toggle ────────────────────────────
function TabToolbox(){
  const RLD = window.RaiseLiveData;
  useLiveTick();
  useEffect(()=>{ if(RLD && RLD.loadAssets && !RLD._assetsOk) RLD.loadAssets(); }, []);
  const [view, setView] = useState(()=> localStorage.getItem('raiseos.toolbox.view') || 'assets');
  const goV = (v)=>{ setView(v); try{ localStorage.setItem('raiseos.toolbox.view', v); }catch(_){} };

  const assets = (RLD && RLD.assets) ? RLD.assets() : [];
  const made = assets.filter(a=>a.status==='made').length;
  const approvedN = (RLD && RLD.gives) ? RLD.gives().filter(g=>g.status==='approved').length : 0;

  return (
    <>
      <TS.TopBar title="Toolbox" sub={view==='assets' ? 'Every fundraising asset — made & to-make' : 'Monthly gives — the value your outreach shares'}>
        <div className="seg2" style={{marginRight:4}}>
          <button className={view==='assets'?'on':''} onClick={()=>goV('assets')}>Assets</button>
          <button className={view==='gives'?'on':''} onClick={()=>goV('gives')}>Gives{approvedN?' ✓':''}</button>
        </div>
        {view==='assets' && assets.length>0 && <div className="qpill acc">{made}/{assets.length} made</div>}
      </TS.TopBar>

      <div className="scroll" style={{padding:'8px 16px 28px'}}>
        <div style={{maxWidth:980, margin:'0 auto'}}>
          {view==='assets' ? <AssetsView /> : <GivesView />}
        </div>
      </div>
    </>
  );
}
window.TabToolbox = TabToolbox;
