// tab-todos.jsx — Apple-style list columns · drag-drop · sub-tasks · recurring · reminders · Notes
const { useState, useRef } = React;
const DS = window.RaiseShell;
const R = window.RAISE;

const recurLabel = (r)=> !r ? '' : 'Every '+(r.every>1?r.every+' ':'')+r.unit+(r.every>1?'s':'');

// search + filter predicate for a to-do
function matchTodo(t, q, f){
  if(f.flagged && !t.flagged) return false;
  if(f.reminder && !t.reminder) return false;
  if(f.recurring && !t.recurring) return false;
  if(f.personId && !DS.ownedBy(t, f.personId)) return false;
  if(q){
    const s = q.toLowerCase();
    const c = R.contactById(t.personId||'self');
    const hay = [t.text, t.note||'', ...t.subtasks.map(st=>st.text), c?(c.name+' '+c.firm):''].join(' ').toLowerCase();
    if(!hay.includes(s)) return false;
  }
  return true;
}

// ── single to-do row (collapsed pill → expands to a tight editor) ──
function TodoItem({ t, dragId, onDragStart, onDragEnd }){
  const Store = window.RaiseStore;
  const [open, setOpen] = useState(false);
  const [subDraft, setSubDraft] = useState('');
  const list = Store.getLists().find(l=>l.id===t.listId);
  const color = list?.color || 'var(--primary)';
  const subDone = t.subtasks.filter(s=>s.done).length;

  const check = (e)=>{ e.stopPropagation(); if(!t.done){ const r=e.currentTarget.getBoundingClientRect(); DS.celebrate(r.left+9,r.top+9); } Store.complete(t.id); };
  const person = R.contactById(t.personId||'self');
  const addSub = ()=>{ if(!subDraft.trim())return; Store.addSub(t.id,subDraft.trim()); setSubDraft(''); };

  return (
    <div className={'tarow'+(t.done?' done':'')+(dragId===t.id?' dragging':'')}
         draggable onDragStart={(e)=>onDragStart(e,t.id)} onDragEnd={onDragEnd} data-todo={t.id}>
      <div className="tarow-main" onClick={()=>setOpen(o=>!o)}>
        <button className={'rcheck'+(t.done?' on':'')} style={t.done?{background:color,borderColor:color}:{borderColor:color}} onClick={check}>{t.done&&'✓'}</button>
        <div className="tarow-body">
          <span className="tarow-t">{t.text}</span>
          <span className="tarow-ind mono">
            {person && !person.isSelf && <span className={'tmini'+(person.anchor?' anchor':'')} title={person.name}>{DS.initials(person.name)}</span>}
            {t.reminder && <span className="ti" title={t.reminder}>⏰</span>}
            {t.recurring && <span className="ti" title={recurLabel(t.recurring)}>↻</span>}
            {t.note && <span className="ti" title="Has note">✎</span>}
            {t.subtasks.length>0 && <span className="cnt">{subDone}/{t.subtasks.length}</span>}
          </span>
        </div>
      </div>

      {open && (
        <div className="tedit2">
          <div className="ef-person"><DS.PersonChip id={t.personId||'self'} sub /></div>
          <div className="ef">
            <label>Reminder</label>
            <input className="efinp" defaultValue={t.reminder} placeholder="e.g. Today 1:30 PM, Fri 9am"
                   onBlur={e=>Store.patch(t.id,{reminder:e.target.value})} />
          </div>
          <div className="ef">
            <label>Repeat</label>
            <div className="recur">
              <span className="mono" style={{color:'var(--ink-3)',fontSize:12}}>Every</span>
              <input className="efinp num mono" type="number" min="1" defaultValue={t.recurring?.every||1}
                     onBlur={e=>{ const ev=Math.max(1,+e.target.value||1); Store.patch(t.id,{recurring:{every:ev,unit:t.recurring?.unit||'week'}}); }} />
              <select className="efsel" value={t.recurring?.unit||''}
                      onChange={e=>Store.patch(t.id,{recurring: e.target.value? {every:t.recurring?.every||1,unit:e.target.value} : null})}>
                <option value="">— none —</option>
                <option value="day">day(s)</option>
                <option value="week">week(s)</option>
                <option value="month">month(s)</option>
              </select>
            </div>
          </div>
          <div className="ef">
            <label>Person</label>
            <DS.PersonCombo value={t.personId||'self'} onChange={pid=>Store.patch(t.id,{personId:pid})} />
          </div>
          <div className="ef col">
            <label>Sub-tasks</label>
            <div className="subs flush">
              {t.subtasks.map(s=>(
                <div key={s.id} className={'subrow'+(s.done?' done':'')}>
                  <button className={'subcheck'+(s.done?' on':'')} onClick={()=>Store.patchSub(t.id,s.id,{done:!s.done})}>{s.done&&'✓'}</button>
                  <span className="subt">{s.text}</span>
                  <button className="xbtn" onClick={()=>Store.removeSub(t.id,s.id)}>✕</button>
                </div>
              ))}
              <div className="addrow">
                <input className="addinp" placeholder="Add sub-task…" value={subDraft}
                       onChange={e=>setSubDraft(e.target.value)} onKeyDown={e=>e.key==='Enter'&&addSub()} />
                <button className="btn sm" onClick={addSub}>＋</button>
              </div>
            </div>
          </div>
          <div className="ef col">
            <label>Note</label>
            <textarea className="efnote" defaultValue={t.note} placeholder="Context…"
                      onBlur={e=>Store.patch(t.id,{note:e.target.value})} />
          </div>
          <div className="ef-foot">
            <button className="linkbtn" onClick={()=>setOpen(false)}>Done</button>
            <div style={{display:'flex',gap:12}}>
              <button className="linkbtn" onClick={()=>{ Store.todoToNote(t.id); DS.toast('Moved to Notes ￥'); }}>→ Move to Notes</button>
              <button className="linkbtn del" onClick={()=>Store.remove(t.id)}>Delete</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ── one list = one column ─────────────────────────────────────────
function ListColumn({ list, items, drag, setDrag, drop, setDrop, dimEmpty }){
  const Store = window.RaiseStore;
  const [draft, setDraft] = useState('');
  const [renaming, setRenaming] = useState(false);
  const [menu, setMenu] = useState(false);
  const open = items.filter(t=>!t.done), done = items.filter(t=>t.done);
  const flat = [...open, ...done];  // keep dragged row mounted (dimmed) so native DnD doesn't abort

  const add = ()=>{ if(!draft.trim())return; Store.add({ text:draft.trim(), listId:list.id }); setDraft(''); };

  const onDragStart = (e,id)=>{ e.dataTransfer.effectAllowed='move'; setDrag(id); };
  const onDragEnd = ()=>{ setDrag(null); setDrop(null); };
  const onDragOver = (e)=>{
    if(!drag) return; e.preventDefault();
    const rows=[...e.currentTarget.querySelectorAll('[data-todo]')].filter(r=>r.dataset.todo!==drag);
    let beforeId=null;
    for(const r of rows){ const b=r.getBoundingClientRect(); if(e.clientY < b.top + b.height/2){ beforeId=r.dataset.todo; break; } }
    setDrop({listId:list.id, beforeId});
  };
  const onDrop = (e)=>{ if(!drag) return; e.preventDefault(); Store.moveBefore(drag, list.id, drop?.beforeId??null); setDrag(null); setDrop(null); };

  const showBar = (id)=> drop && drop.listId===list.id && drop.beforeId===id;
  const isOver = drag && drop && drop.listId===list.id;

  return (
    <div className={'lcol'+(isOver?' over':'')} onDragOver={onDragOver} onDrop={onDrop}>
      <div className="lcol-hd">
        <span className="ldot2" style={{background:list.color}}/>
        {renaming
          ? <input className="lname-edit" autoFocus defaultValue={list.name}
                   onBlur={e=>{Store.patchList(list.id,{name:e.target.value||list.name});setRenaming(false);}}
                   onKeyDown={e=>e.key==='Enter'&&e.currentTarget.blur()} />
          : <span className="lname" style={{color:list.color}} onClick={()=>setRenaming(true)}>{list.name}</span>}
        <span className="lcount2 mono">{open.length}</span>
        <div className="lmenu-wrap">
          <button className="lkebab" onClick={()=>setMenu(m=>!m)}>⋯</button>
          {menu && (
            <>
              <div className="menu-back" onClick={()=>setMenu(false)}/>
              <div className="lmenu">
                <button onClick={()=>{setRenaming(true);setMenu(false);}}>Rename list</button>
                <button className="del" onClick={()=>{ if(confirm('Delete "'+list.name+'" and its to-dos?')){Store.removeList(list.id);} setMenu(false); }}>Delete list</button>
              </div>
            </>
          )}
        </div>
      </div>

      <div className="lcol-add">
        <input className="addinp" placeholder="Add to-do…" value={draft}
               onChange={e=>setDraft(e.target.value)} onKeyDown={e=>e.key==='Enter'&&add()} />
        <button className="btn primary sm" onClick={add}>＋</button>
      </div>

      <div className="lcol-body scroll">
        {flat.length===0 && !drag && <div className="lcol-empty">{dimEmpty?'No matches in this list':'No to-dos. Add one above.'}</div>}
        {flat.map(t=>(
          <React.Fragment key={t.id}>
            {showBar(t.id) && <div className="dropbar"/>}
            <TodoItem t={t} dragId={drag} onDragStart={onDragStart} onDragEnd={onDragEnd} />
          </React.Fragment>
        ))}
        {drop && drop.listId===list.id && drop.beforeId==null && drag && <div className="dropbar"/>}
      </div>
    </div>
  );
}

// NotesView lives in notes.jsx (window.NotesView)

function TabTodos(){
  const todos = DS.useTodos();
  const lists = DS.useLists();
  const [view, setView] = useState('todos');
  const [drag, setDrag] = useState(null);
  const [drop, setDrop] = useState(null);
  const [newList, setNewList] = useState(false);
  const [query, setQuery] = useState('');
  const [filt, setFilt] = useState({ flagged:false, reminder:false, recurring:false, personId:'' });
  const Store = window.RaiseStore;
  const openCount = todos.filter(t=>!t.done).length;
  const active = query.trim() || filt.flagged || filt.reminder || filt.recurring || filt.personId;
  const peopleWithTodos = [...new Set(todos.map(t=>t.personId||'self'))].sort((a,b)=>a==='self'?-1:b==='self'?1:0);
  const tog = (k)=> setFilt(f=>({...f,[k]:!f[k]}));
  const visible = todos.filter(t=>matchTodo(t, query.trim(), filt));
  const matchCount = visible.filter(t=>!t.done).length;

  return (
    <>
      <DS.TopBar title="To-Dos & Notes" sub={`${openCount} open · ${lists.length} lists · drag to organize`}>
        <div className="seg2">
          <button className={view==='todos'?'on':''} onClick={()=>setView('todos')}>To-Dos</button>
          <button className={view==='notes'?'on':''} onClick={()=>setView('notes')}>Notes</button>
        </div>
      </DS.TopBar>

      {view==='todos' ? (
        <>
          <div className="tdbar">
            <div className="tdsearch">
              <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 to-dos, sub-tasks, people…" value={query} onChange={e=>setQuery(e.target.value)} />
              {query && <button className="tdclear" onClick={()=>setQuery('')}>✕</button>}
            </div>
            <div className="tdfilters">
              <button className={'nfilter'+(filt.flagged?' on':'')} onClick={()=>tog('flagged')}>⚑ Flagged</button>
              <button className={'nfilter'+(filt.reminder?' on':'')} onClick={()=>tog('reminder')}>⏰ Scheduled</button>
              <button className={'nfilter'+(filt.recurring?' on':'')} onClick={()=>tog('recurring')}>↻ Recurring</button>
              <select className="efsel" value={filt.personId} onChange={e=>setFilt(f=>({...f,personId:e.target.value}))}>
                <option value="">All people</option>
                {peopleWithTodos.map(pid=>{ const c=R.contactById(pid); return c && <option key={pid} value={pid}>{pid==='self'?'Me (AJ)':c.name}</option>; })}
              </select>
              {active && <button className="tdreset" onClick={()=>{setQuery('');setFilt({flagged:false,reminder:false,recurring:false,personId:''});}}>Clear · {matchCount} match{matchCount===1?'':'es'}</button>}
            </div>
          </div>
          <div className="lcols scroll-x">
            {lists.map(l=>(
              <ListColumn key={l.id} list={l} items={visible.filter(t=>t.listId===l.id)} dimEmpty={active}
                          drag={drag} setDrag={setDrag} drop={drop} setDrop={setDrop} />
            ))}
            <div className="lcol-new">
              {newList ? (
                <input className="lname-edit" autoFocus placeholder="List name…"
                       onBlur={e=>{ if(e.target.value.trim())Store.addList(e.target.value.trim()); setNewList(false); }}
                       onKeyDown={e=>{ if(e.key==='Enter'){ if(e.target.value.trim())Store.addList(e.target.value.trim()); setNewList(false);} }} />
              ) : (
                <button className="addlist" onClick={()=>setNewList(true)}>＋ Add list</button>
              )}
            </div>
          </div>
        </>
      ) : <window.NotesView />}
    </>
  );
}
window.TabTodos = TabTodos;
