/* === PHYSL 210 — Notes (personal notebook: folders, uploads, typed notes) === */
const { useState: useSNo, useEffect: useENo, useRef: useRNo } = React;

const NOTES_KEY = 'physl.notes.v1';
const nuid = () => Math.random().toString(36).slice(2, 9);
const isImg = (n) => n.type === 'file' && /^image\//.test(n.mime || '');
const isPdf = (n) => n.type === 'file' && /pdf/i.test(n.mime || '');
const prettyDate = (t) => new Date(t).toLocaleDateString('en-CA', { month:'short', day:'numeric' });

function loadNotes() {
  try { const r = JSON.parse(localStorage.getItem(NOTES_KEY)); if (r && r.folders && r.folders.length) return r; } catch (e) {}
  return { folders: [
    { id:'f_phys', name:'Cardiovascular', notes:[] },
    { id:'f_inbox', name:'My Notes', notes:[] },
  ] };
}

/* ---- file glyph (simple shapes only) ---- */
function FileGlyph({ note, color }) {
  if (isPdf(note)) return (
    <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:8 }}>
      <svg width="40" height="48" viewBox="0 0 40 48" fill="none" stroke={color} strokeWidth="2.4" strokeLinejoin="round" strokeLinecap="round">
        <path d="M6 3h20l8 8v34a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z" /><path d="M26 3v8h8" />
      </svg>
      <span style={{ fontFamily:'Quicksand', fontWeight:700, fontSize:12, color, letterSpacing:'.5px' }}>PDF</span>
    </div>
  );
  return (
    <svg width="40" height="48" viewBox="0 0 40 48" fill="none" stroke={color} strokeWidth="2.4" strokeLinejoin="round" strokeLinecap="round">
      <path d="M6 3h20l8 8v34a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z" /><path d="M26 3v8h8" /><path d="M13 24h14M13 31h14M13 38h8" />
    </svg>
  );
}

function NotesPage() {
  const [state, setState] = useSNo(loadNotes);
  const [active, setActive] = useSNo(() => loadNotes().folders[0].id);
  const [drag, setDrag] = useSNo(false);
  const [viewer, setViewer] = useSNo(null);
  const [compose, setCompose] = useSNo(null);     // {title, body, id?}
  const [newFolder, setNewFolder] = useSNo(false);
  const [folderName, setFolderName] = useSNo('');
  const [warn, setWarn] = useSNo(false);
  const fileRef = useRNo(null);

  useENo(() => { try { localStorage.setItem(NOTES_KEY, JSON.stringify(state)); setWarn(false); } catch (e) { setWarn(true); } }, [state]);

  const folder = state.folders.find(f => f.id === active) || state.folders[0];
  const setFolderNotes = (fn) => setState(s => ({ ...s, folders: s.folders.map(f => f.id === active ? { ...f, notes: fn(f.notes) } : f) }));

  function handleFiles(list) {
    const files = [...list].slice(0, 25);
    Promise.all(files.map(f => new Promise(res => {
      const fr = new FileReader();
      fr.onload = () => res({ id:'n_'+nuid(), type:'file', name:f.name.replace(/\.[^.]+$/, ''), mime:f.type, size:f.size, dataUrl:fr.result, created:Date.now() });
      fr.onerror = () => res(null);
      fr.readAsDataURL(f);
    }))).then(notes => setFolderNotes(prev => [...notes.filter(Boolean), ...prev]));
  }

  function saveCompose() {
    const c = compose; if (!c.title.trim() && !c.body.trim()) { setCompose(null); return; }
    if (c.id) setFolderNotes(prev => prev.map(n => n.id === c.id ? { ...n, name:c.title || 'Untitled', text:c.body } : n));
    else setFolderNotes(prev => [{ id:'n_'+nuid(), type:'text', name:c.title || 'Untitled', text:c.body, created:Date.now() }, ...prev]);
    setCompose(null);
  }
  function addFolder() {
    const name = folderName.trim(); if (!name) { setNewFolder(false); return; }
    const id = 'f_'+nuid();
    setState(s => ({ ...s, folders: [...s.folders, { id, name, notes:[] }] }));
    setActive(id); setFolderName(''); setNewFolder(false);
  }
  const delNote = (id) => setFolderNotes(prev => prev.filter(n => n.id !== id));
  const delFolder = (id) => setState(s => {
    const folders = s.folders.filter(f => f.id !== id);
    if (active === id && folders.length) setActive(folders[0].id);
    return { ...s, folders: folders.length ? folders : [{ id:'f_inbox', name:'My Notes', notes:[] }] };
  });

  return (
    <div className="page fade">
      <div className="page-head">
        <div className="page-eyebrow">Notes</div>
        <h1 className="page-title">My notebook</h1>
      </div>

      <div className="notes-layout">
        {/* ---- folder rail ---- */}
        <div>
          <div className="folder-list">
            {state.folders.map(f => (
              <div key={f.id} className={`folder-item${f.id===active?' on':''}`} onClick={() => setActive(f.id)}>
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinejoin="round" strokeLinecap="round"><path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" /></svg>
                <span style={{ whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{f.name}</span>
                <span className="ct">{f.notes.length}</span>
              </div>
            ))}
          </div>
          {newFolder
            ? <div style={{ marginTop:8, display:'flex', gap:6 }}>
                <input className="io-input" autoFocus value={folderName} placeholder="Folder name"
                  style={{ padding:'9px 12px', fontSize:14.5 }}
                  onChange={e => setFolderName(e.target.value)} onKeyDown={e => { if (e.key==='Enter') addFolder(); if (e.key==='Escape') setNewFolder(false); }} />
                <button className="btn btn-md btn-primary" style={{ padding:'9px 14px' }} onClick={addFolder}>Add</button>
              </div>
            : <button className="new-folder" style={{ marginTop:8 }} onClick={() => setNewFolder(true)}>
                <span style={{ fontSize:18, lineHeight:1 }}>＋</span> New folder
              </button>}

          {state.folders.length > 1 && (
            <button onClick={() => delFolder(active)} style={{ marginTop:18, background:'none', border:'none', cursor:'pointer', color:'var(--muted)', fontSize:13, fontWeight:600, padding:'4px 14px' }}>
              Delete “{folder.name}”
            </button>
          )}
        </div>

        {/* ---- folder contents ---- */}
        <div onDragOver={e => { e.preventDefault(); setDrag(true); }} onDragLeave={() => setDrag(false)}
          onDrop={e => { e.preventDefault(); setDrag(false); if (e.dataTransfer.files.length) handleFiles(e.dataTransfer.files); }}>

          <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', gap:14, marginBottom:18, flexWrap:'wrap' }}>
            <div className="disp" style={{ fontSize:24, fontWeight:600 }}>{folder.name}</div>
            <div style={{ display:'flex', gap:10 }}>
              <button className="btn btn-md btn-ghost" onClick={() => setCompose({ title:'', body:'' })}>✎ Write a note</button>
              <button className="btn btn-md btn-primary" onClick={() => fileRef.current.click()}>↥ Upload</button>
              <input ref={fileRef} type="file" accept="image/*,application/pdf" multiple style={{ display:'none' }}
                onChange={e => { handleFiles(e.target.files); e.target.value=''; }} />
            </div>
          </div>

          {warn && <div className="explain" style={{ marginBottom:16, background:'oklch(0.95 0.04 28)', borderColor:'oklch(0.85 0.07 30)' }}>This file was added for now, but it’s too large to save between sessions in this demo.</div>}

          {folder.notes.length === 0 ? (
            <div className={`dropzone${drag?' drag':''}`} style={{ padding:'56px 32px', textAlign:'center' }} onClick={() => fileRef.current.click()} role="button">
              <div style={{ width:64, height:64, borderRadius:'50%', background:'var(--coral-tint)', display:'grid', placeItems:'center', margin:'0 auto 16px' }}>
                <svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="var(--coral)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 16V4M7 9l5-5 5 5" /><path d="M5 20h14" /></svg>
              </div>
              <div className="disp" style={{ fontSize:21, fontWeight:600 }}>{drag ? 'Drop to add to this folder' : 'Add your first note'}</div>
              <div style={{ color:'var(--muted)', fontSize:15, marginTop:8, lineHeight:1.5, maxWidth:420, margin:'8px auto 0' }}>
                AirDrop from Goodnotes, then drag the file here — or click to browse. PDFs and images welcome. You can also <span style={{ color:'var(--coral-deep)', fontWeight:600, cursor:'pointer' }} onClick={e => { e.stopPropagation(); setCompose({ title:'', body:'' }); }}>type a note</span>.
              </div>
            </div>
          ) : (
            <div className={`dropzone${drag?' drag':''}`} style={{ padding: drag ? 14 : 0, border: drag ? undefined : 'none', background:'transparent' }}>
              <div className="note-grid">
                {folder.notes.map(n => (
                  <div key={n.id} className="note-card fade" onClick={() => n.type==='text' ? setCompose({ id:n.id, title:n.name, body:n.text||'' }) : setViewer(n)}>
                    <button className="note-del" title="Delete" onClick={e => { e.stopPropagation(); delNote(n.id); }}>✕</button>
                    {isImg(n)
                      ? <div className="note-thumb" style={{ backgroundImage:`url(${n.dataUrl})` }} />
                      : n.type==='text'
                        ? <div className="note-thumb" style={{ background:'var(--coral-tint)', alignItems:'flex-start', padding:'16px 16px', overflow:'hidden' }}>
                            <div style={{ fontSize:12.5, color:'var(--ink-soft)', lineHeight:1.55, display:'-webkit-box', WebkitLineClamp:6, WebkitBoxOrient:'vertical', overflow:'hidden' }}>{n.text || 'Empty note'}</div>
                          </div>
                        : <div className="note-thumb"><FileGlyph note={n} color="var(--coral)" /></div>}
                    <div className="note-foot">
                      <div className="disp" style={{ fontSize:15, fontWeight:600, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{n.name}</div>
                      <div style={{ fontSize:12, color:'var(--muted)', marginTop:2 }}>
                        {n.type==='text' ? 'Typed note' : isPdf(n) ? 'PDF' : isImg(n) ? 'Image' : 'File'} · {prettyDate(n.created)}
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          )}
        </div>
      </div>

      {/* ---- file viewer ---- */}
      {viewer && (
        <div onClick={() => setViewer(null)} style={{ position:'fixed', inset:0, zIndex:60, background:'oklch(0.28 0.02 50 / .62)', backdropFilter:'blur(8px)', display:'grid', placeItems:'center', padding:32 }}>
          <div onClick={e => e.stopPropagation()} className="fade" style={{ background:'var(--surface)', borderRadius:'var(--r-xl)', maxWidth:'min(900px,94vw)', width:'100%', maxHeight:'90vh', overflow:'hidden', display:'flex', flexDirection:'column', boxShadow:'var(--shadow-lift)' }}>
            <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', padding:'16px 22px', borderBottom:'1.5px solid var(--line)' }}>
              <div className="disp" style={{ fontSize:18, fontWeight:600 }}>{viewer.name}</div>
              <button className="crumb" style={{ margin:0, padding:'6px 14px' }} onClick={() => setViewer(null)}>Close ✕</button>
            </div>
            <div style={{ flex:1, overflow:'auto', background:'var(--bg)', display:'grid', placeItems:'center' }}>
              {isImg(viewer)
                ? <img src={viewer.dataUrl} alt={viewer.name} style={{ maxWidth:'100%', display:'block' }} />
                : isPdf(viewer)
                  ? <iframe title={viewer.name} src={viewer.dataUrl} style={{ width:'100%', height:'78vh', border:'none' }} />
                  : <div style={{ padding:40, color:'var(--muted)' }}>Preview not available — <a href={viewer.dataUrl} download={viewer.name} style={{ color:'var(--coral-deep)' }}>download</a>.</div>}
            </div>
          </div>
        </div>
      )}

      {/* ---- composer ---- */}
      {compose && (
        <div onClick={() => setCompose(null)} style={{ position:'fixed', inset:0, zIndex:60, background:'oklch(0.28 0.02 50 / .55)', backdropFilter:'blur(8px)', display:'grid', placeItems:'center', padding:32 }}>
          <div onClick={e => e.stopPropagation()} className="panel fade" style={{ width:'min(640px,94vw)' }}>
            <input className="io-input" autoFocus value={compose.title} placeholder="Note title"
              style={{ fontFamily:'Quicksand', fontWeight:600, fontSize:20, border:'none', background:'transparent', padding:'4px 2px', marginBottom:6 }}
              onChange={e => setCompose({ ...compose, title:e.target.value })} />
            <textarea className="io-input" value={compose.body} placeholder="Start typing…  (your notes save automatically to this folder)"
              rows={10} onChange={e => setCompose({ ...compose, body:e.target.value })} />
            <div style={{ display:'flex', justifyContent:'flex-end', gap:12, marginTop:18 }}>
              <button className="btn btn-md btn-ghost" onClick={() => setCompose(null)}>Cancel</button>
              <button className="btn btn-md btn-primary" onClick={saveCompose}>Save note</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
window.NotesPage = NotesPage;
