// notes.jsx — ClickUp-style nestable pages: left page-tree + inline doc editor.
const { useState, useEffect, useRef } = React;
const NS = window.RaiseShell;

const NOTE_TYPES = {
  quick:   { label:'Quick',   color:'#3f9560', hint:'Note to self' },
  meeting: { label:'Meeting', color:'#8159bf', hint:'Call / meeting notes' },
  plan:    { label:'Plan',    color:'#c96442', hint:'Long-form thinking' },
};
const tint = (hex,a)=> hex+(a||'1e');

// ── inline document editor (the right pane) ────────────────────────
function NoteEditor({ id, onNavigate, onAddSub }){
  const R = window.RAISE, Store = window.RaiseStore;
  const notes = NS.useNotes();
  const n = notes.find(x=>x.id===id);
  const [actDraft, setActDraft] = useState('');
  const bodyRef = useRef(null);
  useEffect(()=>{ const el=bodyRef.current; if(el){ el.style.height='auto'; el.style.height=Math.max(el.scrollHeight,el.clientHeight)+'px'; } },[id]);
  if(!n) return null;
  const ty = NOTE_TYPES[n.type] || NOTE_TYPES.quick;
  const grow = (e)=>{ e.target.style.height='auto'; e.target.style.height=e.target.scrollHeight+'px'; };
  // breadcrumb chain
  const chain=[]; let p=n.parentId; const byId=id=>notes.find(x=>x.id===id);
  while(p){ const pp=byId(p); if(!pp) break; chain.unshift(pp); p=pp.parentId; }

  return (
    <div className="note-doc embedded" style={{['--ty']:ty.color}}>
      <div className="note-doc-hd">
        <div className="note-crumbs">
          {chain.map(c=>(<span key={c.id} className="crumb"><button onClick={()=>onNavigate(c.id)}>{c.title||'Untitled'}</button><span className="crumb-sep">/</span></span>))}
          <span className="crumb cur">{n.title||'Untitled'}</span>
        </div>
        <div style={{flex:1}}/>
        <select className="efsel" value={n.type} onChange={e=>Store.patchNote(n.id,{type:e.target.value})}>
          {Object.entries(NOTE_TYPES).map(([k,v])=><option key={k} value={k}>{v.label}</option>)}
        </select>
        <NS.PersonCombo value={n.personId||'self'} onChange={pid=>Store.patchNote(n.id,{personId:pid})} />
        <button className={'note-pin'+(n.pinned?' on':'')} title="Pin" onClick={()=>Store.patchNote(n.id,{pinned:!n.pinned})}>
          <svg viewBox="0 0 16 16" width="14" height="14" fill={n.pinned?'currentColor':'none'} stroke="currentColor" strokeWidth="1.4"><path d="M8 1.5l1.6 3.7 4 .35-3 2.65.9 3.9L8 10l-3.4 2.05.9-3.9-3-2.65 4-.35z"/></svg>
        </button>
      </div>

      <div className="note-doc-body-wrap scroll">
        <input className="note-doc-title" key={n.id+'-t'} defaultValue={n.title} placeholder="Untitled" onBlur={e=>Store.patchNote(n.id,{title:e.target.value})} />
        <div className="note-doc-sub mono">{n.date} · {ty.hint}</div>
        <textarea ref={bodyRef} key={n.id+'-b'} className="note-doc-body" defaultValue={n.body} placeholder="Start writing…  press to add plans, meeting notes, long-form thinking — this page grows with you."
                  onInput={grow} onBlur={e=>Store.patchNote(n.id,{body:e.target.value})} />

        <div className="note-doc-actions">
          <div className="nda-h">Action items <span className="mono">{n.actions?.filter(a=>a.done).length||0}/{n.actions?.length||0}</span></div>
          {(n.actions||[]).map(a=>(
            <div key={a.id} className={'nda-row'+(a.done?' done':'')}>
              <button className={'subcheck'+(a.done?' on':'')} onClick={()=>Store.patchNoteAction(n.id,a.id,{done:!a.done})}>{a.done&&'✓'}</button>
              <span className="nda-t">{a.text}</span>
              {!a.pushed && <button className="nda-push" title="Make it a to-do" onClick={()=>{Store.pushNoteAction(n.id,a.id);NS.toast('Added to To-Dos ✓');}}>→ To-do</button>}
              {a.pushed && <span className="nda-pushed mono">in to-dos</span>}
              <button className="xbtn" onClick={()=>Store.removeNoteAction(n.id,a.id)}>✕</button>
            </div>
          ))}
          <div className="addrow">
            <input className="addinp" placeholder="Add an action item…" value={actDraft}
                   onChange={e=>setActDraft(e.target.value)} onKeyDown={e=>{ if(e.key==='Enter'&&actDraft.trim()){ Store.addNoteAction(n.id,actDraft.trim()); setActDraft(''); } }} />
            <button className="btn sm" onClick={()=>{ if(actDraft.trim()){ Store.addNoteAction(n.id,actDraft.trim()); setActDraft(''); } }}>＋</button>
          </div>
        </div>
      </div>

      <div className="note-doc-foot">
        <button className="linkbtn" onClick={()=>onAddSub(n.id)}>＋ Add subpage</button>
        <button className="linkbtn del" onClick={()=>{ if(confirm('Delete "'+(n.title||'this page')+'"? Subpages move up a level.')){ Store.removeNote(n.id); onNavigate(n.parentId||null); } }}>Delete page</button>
      </div>
    </div>
  );
}

// ── page tree (left rail) ──────────────────────────────────────────
function PageRow({ note, depth, notes, selId, onSelect, onAddSub, onDel, expanded, toggle, dnd }){
  const kids = notes.filter(n=>n.parentId===note.id);
  const hasKids = kids.length>0;
  const open = expanded.has(note.id);
  const ty = NOTE_TYPES[note.type]||NOTE_TYPES.quick;
  const isSrc = dnd.dragId===note.id;
  const dz = dnd.over && dnd.over.id===note.id ? dnd.over.zone : null;

  const onDragOver = (e)=>{
    if(!dnd.dragId || dnd.dragId===note.id) return;
    e.preventDefault(); e.stopPropagation();
    e.dataTransfer.dropEffect='move';
    const r = e.currentTarget.getBoundingClientRect();
    const y = (e.clientY - r.top) / r.height;
    const zone = y < 0.28 ? 'before' : y > 0.72 ? 'after' : 'into';
    dnd.setOver(o=> (o && o.id===note.id && o.zone===zone) ? o : {id:note.id, zone});
  };

  return (
    <>
      <div className={'pg-row'+(selId===note.id?' on':'')+(isSrc?' drag-src':'')+(dz?' dz-'+dz:'')}
           style={{paddingLeft:6+depth*15}}
           draggable
           onClick={()=>onSelect(note.id)}
           onDragStart={e=>{ e.stopPropagation(); e.dataTransfer.effectAllowed='move'; e.dataTransfer.setData('text/plain',note.id); dnd.setDragId(note.id); }}
           onDragEnd={()=>dnd.end()}
           onDragOver={onDragOver}
           onDragLeave={e=>{ if(!e.currentTarget.contains(e.relatedTarget)) dnd.setOver(o=> o&&o.id===note.id?null:o); }}
           onDrop={e=>{ e.preventDefault(); e.stopPropagation(); dnd.drop(note.id); }}>
        <button className={'pg-twist'+(hasKids?'':' empty')+(open?' open':'')} onClick={e=>{e.stopPropagation(); hasKids&&toggle(note.id);}}>
          <svg viewBox="0 0 10 10" width="9" height="9" fill="currentColor"><path d="M3 1.5L7 5L3 8.5z"/></svg>
        </button>
        <span className="pg-dot" style={{background:ty.color}}/>
        <span className="pg-title">{note.title||'Untitled'}</span>
        {note.pinned && <span className="pg-pin">★</span>}
        <span className="pg-tools">
          <button className="pg-tool" title="Add subpage" onClick={e=>{e.stopPropagation(); onAddSub(note.id);}}>＋</button>
          <button className="pg-tool" title="Delete" onClick={e=>{e.stopPropagation(); onDel(note.id);}}>✕</button>
        </span>
      </div>
      {open && kids.map(k=><PageRow key={k.id} note={k} depth={depth+1} notes={notes} selId={selId} onSelect={onSelect} onAddSub={onAddSub} onDel={onDel} expanded={expanded} toggle={toggle} dnd={dnd} />)}
    </>
  );
}

// ── notes view: tree rail + inline editor ──────────────────────────
function NotesView(){
  const R = window.RAISE, Store = window.RaiseStore;
  const notes = NS.useNotes();
  const [sel, setSel] = useState(null);
  const [q, setQ] = useState('');
  const [expanded, setExpanded] = useState(null);
  const [dragId, setDragId] = useState(null);
  const [over, setOver] = useState(null); // {id, zone:'before'|'after'|'into'}

  // initialise: expand every parent once, select first page
  useEffect(()=>{
    if(expanded===null && notes.length){
      setExpanded(new Set(notes.filter(n=>notes.some(c=>c.parentId===n.id)).map(n=>n.id)));
    }
    if(sel===null && notes.length){ setSel(notes[0].id); }
  },[notes]);
  const exp = expanded||new Set();
  const toggle = (id)=> setExpanded(s=>{ const n=new Set(s); n.has(id)?n.delete(id):n.add(id); return n; });

  // ── drag controller: nest into a page, or reorder among siblings ──
  const dnd = {
    dragId, over, setDragId, setOver,
    end: ()=>{ setDragId(null); setOver(null); },
    drop: (targetId)=>{
      const o = over; const src = dragId;
      setDragId(null); setOver(null);
      if(!src || !o || src===targetId) return;
      const tgt = notes.find(n=>n.id===targetId); if(!tgt) return;
      let parentId, beforeId;
      if(o.zone==='into'){
        parentId = targetId; beforeId = null;            // nest as last child
        setExpanded(s=>new Set(s).add(targetId));
      } else {
        parentId = tgt.parentId || null;
        const sibs = notes.filter(n=>(n.parentId||null)===parentId && n.id!==src);
        const ti = sibs.findIndex(n=>n.id===targetId);
        beforeId = o.zone==='before' ? targetId : (sibs[ti+1] ? sibs[ti+1].id : null);
      }
      const ok = Store.moveNote(src, parentId, beforeId);
      if(ok){ setSel(src); NS.toast(o.zone==='into' ? 'Nested under "'+(tgt.title||'page')+'"' : 'Page moved'); }
      else NS.toast("Can't drop a page inside itself");
    },
    // drop onto empty rail space → promote to top-level
    dropRoot: ()=>{ const src=dragId; setDragId(null); setOver(null);
      if(src){ const ok=Store.moveNote(src,null,null); if(ok){ setSel(src); NS.toast('Moved to top level'); } } },
  };

  const addPage = (parentId=null)=>{ const id=Store.addNote({ title:'', parentId, type: parentId? (R.contactById(notes.find(n=>n.id===parentId)?.personId)?.isSelf===false?'meeting':'quick') : 'quick' }); if(parentId) setExpanded(s=>new Set(s).add(parentId)); setSel(id); };
  const del = (id)=>{ if(confirm('Delete this page? Subpages move up a level.')){ const wasSel=sel===id; const par=notes.find(n=>n.id===id)?.parentId; Store.removeNote(id); if(wasSel) setSel(par||null); NS.toast('Page deleted'); } };

  const roots = notes.filter(n=>!n.parentId);
  const ql = q.trim().toLowerCase();
  const matches = ql ? notes.filter(n=>{ const c=R.contactById(n.personId||'self'); return [n.title,n.body||'',...(n.actions||[]).map(a=>a.text),c?c.name:''].join(' ').toLowerCase().includes(ql); }) : null;

  return (
    <div className="notesview pages">
      <div className="pgrail">
        <div className="pgrail-hd"><span>Pages</span><button className="pgrail-add" title="New top-level page" onClick={()=>addPage(null)}>＋</button></div>
        <div className="pgsearch">
          <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5"><circle cx="7" cy="7" r="4.5"/><path d="M11 11l3 3" strokeLinecap="round"/></svg>
          <input placeholder="Search pages…" value={q} onChange={e=>setQ(e.target.value)} />
          {q && <button className="tdclear" onClick={()=>setQ('')}>✕</button>}
        </div>
        <div className="pgtree-wrap scroll"
             onDragOver={e=>{ if(dnd.dragId){ e.preventDefault(); e.dataTransfer.dropEffect='move'; } }}
             onDrop={e=>{ if(dnd.dragId && !over){ e.preventDefault(); dnd.dropRoot(); } }}>
          {matches ? (
            matches.length? matches.map(n=>{ const ty=NOTE_TYPES[n.type]||NOTE_TYPES.quick; return (
              <div key={n.id} className={'pg-row flat'+(sel===n.id?' on':'')} onClick={()=>setSel(n.id)}>
                <span className="pg-dot" style={{background:ty.color}}/><span className="pg-title">{n.title||'Untitled'}</span>
              </div>); }) : <div className="pg-empty">No pages match.</div>
          ) : (
            roots.map(r=><PageRow key={r.id} note={r} depth={0} notes={notes} selId={sel} onSelect={setSel} onAddSub={addPage} onDel={del} expanded={exp} toggle={toggle} dnd={dnd} />)
          )}
        </div>
        <button className="pgrail-newpage" onClick={()=>addPage(null)}>＋ Add page</button>
      </div>

      <div className="pgmain">
        {sel ? <NoteEditor id={sel} onNavigate={(pid)=>setSel(pid)} onAddSub={addPage} /> : (
          <div className="pgempty">
            <div className="pgempty-i">▢</div>
            <div>Select a page on the left, or <button className="linkbtn" onClick={()=>addPage(null)}>create a new one</button>.</div>
          </div>
        )}
      </div>
    </div>
  );
}

window.NotesView = NotesView;
