// DaySchedule.jsx — Compact day planner for the Dashboard "Today's tasks" card.
// Source: v2/New_design easylife-schedule.jsx, adapted to use CSS variables
// and the V2 task shape ({ id, title, completed }).
//
// The timeline is split into two side-by-side columns — 06–15 and 15–24 —
// so a full day fits without the card growing very tall. Both ordinary tasks
// (todo_tasks) and goal/project todos (carrying `__gp` + `parentName`) can be
// dragged in and given a time.
const { useState: useSS, useRef: useSR, useEffect: useSE, useMemo: useSM } = React;

/* ═══ Constants ═══ */
// Day window split into two equal 8-hour columns (06–14 and 14–22) so the
// 2-hour grid lines line up horizontally across both columns.
const SCHED_START = 6;
const SCHED_END   = 22;
const SCHED_SPLIT = 14;            // boundary between the two columns
const SCHED_PXH   = 38;
const SCHED_SNAP  = 15;
const SCHED_DEF   = 60;
const SCHED_LBL   = 28;
// Two stacked-side-by-side columns: morning/afternoon and evening.
const SCHED_COLS  = [
  { s: SCHED_START, e: SCHED_SPLIT },
  { s: SCHED_SPLIT, e: SCHED_END },
];

// Accent (#00d4aa) tints. Inline because alpha cannot be concatenated onto
// `var(--accent)` in template literals.
const SCHED_ACCENT       = 'var(--accent)';
const SCHED_ACCENT_BG    = 'rgba(0,212,170,0.10)';
const SCHED_ACCENT_BG_H  = 'rgba(0,212,170,0.20)';
const SCHED_ACCENT_BD    = 'rgba(0,212,170,0.33)';
const SCHED_ACCENT_GHOST = 'rgba(0,212,170,0.12)';
const SCHED_ACCENT_DASH  = 'rgba(0,212,170,0.44)';
const SCHED_RED          = 'var(--red-ink, #ef4444)';
// Dedicated blue for the "now" line. --red-ink resolves to green in this
// theme, which made the time indicator look like a task strike-through.
const SCHED_NOW          = '#3b82f6';
const SCHED_ORANGE       = '#f97316';
const SCHED_DONE_BG      = 'rgba(255,255,255,0.02)';
const SCHED_DONE_BD      = 'rgba(255,255,255,0.04)';
const SCHED_GRID_MAJOR   = 'var(--surface-b)';
const SCHED_GRID_MINOR   = 'rgba(255,255,255,0.025)';
const SCHED_ROW_HOV      = 'rgba(255,255,255,0.04)';
const SCHED_CHECK_BG     = 'rgba(255,255,255,0.92)';

function _colH(col)      { return (col.e - col.s) * SCHED_PXH; }
function _mY(min, col)   { return ((min - col.s * 60) / ((col.e - col.s) * 60)) * _colH(col); }
function _yM(y, col)     { return Math.round((col.s * 60 + (y / _colH(col)) * (col.e - col.s) * 60) / SCHED_SNAP) * SCHED_SNAP; }
function _colOf(min)     { return min < SCHED_SPLIT * 60 ? 0 : 1; }
function _fmt(min)       { return `${String(Math.floor(min/60)).padStart(2,'0')}:${String(min%60).padStart(2,'0')}`; }
function _taskLabel(t)   { return t.title || t.text || t.name || ''; }


/* ═══ Scheduled Block ═══ */
function SchedBlock({ task, slot, col, draggingId, onToggle, onEdit, onRemove, onMoveStart, onResizeStart }) {
  const top = _mY(slot.start, col);
  const h   = Math.max(Math.min(_mY(slot.end, col), _colH(col)) - top, 22);
  const tiny = h < 32;
  const done = !!task.completed;
  const isDrag = draggingId === task.id;
  const [hov, setHov] = useSS(false);
  // Hover med liten forsinkelse: streker for å dra (resize) er skjult når
  // musa ikke er på kortet, men en kort grace-periode gjør at man kan gå
  // litt utenfor og tilbake uten at de forsvinner — bedre brukeropplevelse.
  const hovT = useSR(null);
  function enterHov() { if (hovT.current) { clearTimeout(hovT.current); hovT.current = null; } setHov(true); }
  function leaveHov() { if (hovT.current) clearTimeout(hovT.current); hovT.current = setTimeout(() => { setHov(false); hovT.current = null; }, 450); }
  useSE(() => () => { if (hovT.current) clearTimeout(hovT.current); }, []);

  return (
    <div
      onMouseEnter={enterHov}
      onMouseLeave={leaveHov}
      onContextMenu={e => window.openFocusMenu && window.openFocusMenu(e, { id: task.id, text: _taskLabel(task), type: 'todo', done: !!task.completed, source: task.__gp, parentName: task.parentName })}
      onMouseDown={e => {
        if (e.button !== 0 || done) return;
        if (e.target.closest('[data-nd]')) return;
        e.preventDefault();
        onMoveStart(task.id, e);
      }}
      style={{
        position:'absolute', top, left:SCHED_LBL+6, right:3, height:h,
        background: done ? SCHED_DONE_BG : hov ? SCHED_ACCENT_BG_H : SCHED_ACCENT_BG,
        border:`1px solid ${done ? SCHED_DONE_BD : SCHED_ACCENT_BD}`,
        borderLeft:`2.5px solid ${done ? 'var(--mut)' : SCHED_ACCENT}`,
        borderRadius:'2px 6px 6px 2px',
        padding: tiny ? '1px 24px 1px 6px' : '4px 24px 4px 6px',
        cursor: done ? 'default' : 'grab',
        zIndex: isDrag ? 1 : 2,
        opacity: done ? 0.35 : isDrag ? 0.25 : 1,
        transition: 'background 0.1s, opacity 0.12s',
        display:'flex', alignItems:'center', gap:6,
        overflow:'hidden',
      }}
    >
      {/* Checkbox — high-contrast so it stays visible on green tint */}
      <button data-nd onClick={e=>{e.stopPropagation();onToggle(task);}} style={{
        width:16,height:16,borderRadius:4,flexShrink:0,padding:0,
        border:`2px solid ${SCHED_ACCENT}`,
        background: done ? SCHED_ACCENT : SCHED_CHECK_BG,
        boxShadow:'0 1px 2px rgba(0,0,0,0.18)',
        cursor:'pointer',
        display:'flex',alignItems:'center',justifyContent:'center',
      }}>
        {done && <svg width="10" height="10" viewBox="0 0 14 14" fill="none"><path d="M2.5 7l3 3L11.5 4" stroke="#000" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/></svg>}
      </button>

      {/* Text + (for goal/project todos) a tiny parent subtitle */}
      <div onClick={e=>{e.stopPropagation();onEdit(task);}} style={{
        display:'flex', flexDirection:'column', gap:0, minWidth:0, flex:'0 1 auto', cursor:'pointer', overflow:'hidden',
      }}>
        <span style={{
          fontSize:11,fontWeight:600,color:done?'var(--mut)':task.__overdue?SCHED_ORANGE:'var(--pri)',
          textDecoration:done?'line-through':'none',
          overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',lineHeight:1.2,
        }}>{_taskLabel(task)}</span>
        {!tiny && task.__gp && task.parentName && (
          <span style={{
            fontSize:9,color:'var(--mut)',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',
            display:'flex',alignItems:'center',gap:3,lineHeight:1.2,
          }}>
            <i className={`ti ${task.__gp === 'goal' ? 'ti-target-arrow' : 'ti-layout-grid'}`} style={{fontSize:9,color:'var(--accent)',opacity:0.8}}></i>{task.parentName}
          </span>
        )}
      </div>
      <span style={{flex:1,alignSelf:'stretch'}}/>

      {/* Remove */}
      <button data-nd onClick={e=>{e.stopPropagation();onRemove();}} style={{
        position:'absolute',top:0,right:0,width:24,height:24,borderRadius:6,
        border:'none',background:'transparent',color:'var(--mut)',cursor:'pointer',
        display:'flex',alignItems:'center',justifyContent:'center',
        fontSize:16,lineHeight:1,opacity:hov?0.7:0,
        transition:'opacity 0.1s,color 0.1s',padding:0,
      }}
      onMouseEnter={e=>e.currentTarget.style.color=SCHED_RED}
      onMouseLeave={e=>e.currentTarget.style.color='var(--mut)'}
      >×</button>

      {/* Resize handles — identical top/bottom stripes */}
      {!done && (() => {
        const hitStyle = {
          position:'absolute',left:'50%',transform:'translateX(-50%)',
          width:36,height:8,cursor:'ns-resize',padding:0,boxSizing:'border-box',
          display:'flex',alignItems:'center',justifyContent:'center',
        };
        const barStyle = {
          width:22,height:3,borderRadius:2,padding:0,boxSizing:'border-box',
          background:'var(--pri)',opacity:hov?0.7:0,transition:'opacity 0.18s',
        };
        return (
          <>
            <div data-nd
              onMouseDown={e=>{e.stopPropagation();e.preventDefault();onResizeStart(task.id,e,'top');}}
              title="Dra opp for tidligere start"
              style={{...hitStyle,top:0}}>
              <div style={barStyle}/>
            </div>
            {h > 22 && (
              <div data-nd
                onMouseDown={e=>{e.stopPropagation();e.preventDefault();onResizeStart(task.id,e,'bottom');}}
                title="Dra ned for senere slutt"
                style={{...hitStyle,bottom:0}}>
                <div style={barStyle}/>
              </div>
            )}
          </>
        );
      })()}
    </div>
  );
}


/* ═══ Timeline Column ═══ */
function SchedColumn({ col, colIdx, colRef, scheduled, schedule, ghost, nowMin, drag, onToggle, onEdit, onUnschedule, onMoveStart, onResizeStart }) {
  const colH = _colH(col);
  const showNow = nowMin >= col.s*60 && nowMin < col.e*60;
  return (
    <div style={{flex:1,minWidth:0}}>
      <div ref={colRef} style={{position:'relative',height:colH,padding:'0 2px'}}>
        {/* Hour lines — line sits EXACTLY at the hour's y-coordinate so task blocks align */}
        {Array.from({length:(col.e-col.s)+1},(_,i)=>{
          const hr = col.s+i;
          const y = i*SCHED_PXH;
          // Label every other row so both columns get marks at the same
          // y-positions (06,08,10,12,14 | 14,16,18,20,22) — perfectly aligned.
          const showLabel = i % 2 === 0;
          return (
            <div key={`h${i}`} style={{position:'absolute',top:y,left:0,right:0,height:1,pointerEvents:'none'}}>
              <span style={{
                position:'absolute',left:0,top:'50%',transform:'translateY(-50%)',
                fontSize:9,fontWeight:600,color:showLabel?'var(--mut)':'transparent',
                width:SCHED_LBL-3,textAlign:'right',fontVariantNumeric:'tabular-nums',
                lineHeight:1,
              }}>{String(hr % 24).padStart(2,'0')}</span>
              <div style={{position:'absolute',left:SCHED_LBL+1,right:0,top:0,height:1,background:showLabel?SCHED_GRID_MAJOR:SCHED_GRID_MINOR}}/>
            </div>
          );
        })}

        {/* Scheduled blocks belonging to this column */}
        {scheduled.filter(t => _colOf(schedule[t.id].start) === colIdx).map(t => (
          <SchedBlock key={t.id} task={t} slot={schedule[t.id]} col={col}
            draggingId={drag?.taskId}
            onToggle={onToggle} onEdit={onEdit}
            onRemove={()=>onUnschedule(t.id)}
            onMoveStart={onMoveStart}
            onResizeStart={onResizeStart}
          />
        ))}

        {/* Ghost */}
        {ghost && ghost.col === colIdx && (
          <div style={{
            position:'absolute',top:_mY(ghost.start,col),left:SCHED_LBL+6,right:3,
            height:Math.max(_mY(ghost.end,col)-_mY(ghost.start,col),14),
            background:SCHED_ACCENT_GHOST,border:`1.5px dashed ${SCHED_ACCENT_DASH}`,
            borderRadius:5,pointerEvents:'none',zIndex:10,
            display:'flex',alignItems:'center',justifyContent:'center',
          }}>
            <span style={{fontSize:9,color:SCHED_ACCENT,fontWeight:600,opacity:0.8}}>
              {_fmt(ghost.start)} – {_fmt(ghost.end)}
            </span>
          </div>
        )}

        {/* Now line */}
        {showNow && (
          <div style={{position:'absolute',top:_mY(nowMin,col),left:SCHED_LBL-1,right:0,height:1.5,background:SCHED_NOW,zIndex:8,pointerEvents:'none'}}>
            <div style={{position:'absolute',left:-3,top:-2.5,width:6,height:6,borderRadius:'50%',background:SCHED_NOW}}/>
          </div>
        )}
      </div>
    </div>
  );
}


/* ═══ Main DaySchedule Component ═══ */
function DaySchedule({ tasks, schedule, onScheduleChange, onToggleTask, onEditTask, addForm }) {
  const colRef0 = useSR(null);
  const colRef1 = useSR(null);
  const colRefs = [colRef0, colRef1];
  const [drag, setDrag] = useSS(null);
  const [ghost, setGhost] = useSS(null);

  const ghostR = useSR(null);
  const schedR = useSR(schedule);
  const changR = useSR(onScheduleChange);
  useSE(() => { ghostR.current = ghost; }, [ghost]);
  useSE(() => { schedR.current = schedule; }, [schedule]);
  useSE(() => { changR.current = onScheduleChange; }, [onScheduleChange]);

  // Current time
  const [now, setNow] = useSS(() => new Date());
  useSE(() => { const id = setInterval(()=>setNow(new Date()), 30000); return ()=>clearInterval(id); }, []);
  const nowMin = now.getHours()*60 + now.getMinutes();

  // Split tasks
  const scheduled   = useSM(() => tasks.filter(t => schedule[t.id]), [tasks, schedule]);
  const unscheduled = useSM(() => tasks.filter(t => !schedule[t.id] && !t.completed), [tasks, schedule]);

  // Which column is the pointer over? Falls back to the nearest column.
  function activeCol(clientX) {
    let best = 0, bestDist = Infinity;
    colRefs.forEach((rf, i) => {
      const el = rf.current; if (!el) return;
      const r = el.getBoundingClientRect();
      if (clientX >= r.left && clientX <= r.right) { best = i; bestDist = -1; return; }
      if (bestDist >= 0) { const d = Math.abs(clientX - (r.left + r.right) / 2); if (d < bestDist) { bestDist = d; best = i; } }
    });
    return best;
  }

  /* ── Drag ── */
  useSE(() => {
    if (!drag) return;
    function onMove(e) {
      const fixed = drag.type === 'resize' || drag.type === 'resize-top';
      const ci = fixed ? drag.col : activeCol(e.clientX);
      const col = SCHED_COLS[ci];
      const el = colRefs[ci].current;
      if (!el) return;
      const y = e.clientY - el.getBoundingClientRect().top;
      let min = _yM(y, col);
      if (drag.type === 'new' || drag.type === 'move') {
        const dur = drag.type === 'move' ? (drag.orig.end - drag.orig.start) : SCHED_DEF;
        min = Math.max(col.s*60, Math.min(col.e*60 - dur, min));
        setGhost({ start:min, end:min+dur, taskId:drag.taskId, col:ci });
      } else if (drag.type === 'resize') {
        const newEnd = Math.max(drag.orig.start + SCHED_SNAP, Math.min(col.e*60, min));
        setGhost({ start:drag.orig.start, end:newEnd, taskId:drag.taskId, col:ci });
      } else if (drag.type === 'resize-top') {
        const newStart = Math.min(drag.orig.end - SCHED_SNAP, Math.max(col.s*60, min));
        setGhost({ start:newStart, end:drag.orig.end, taskId:drag.taskId, col:ci });
      }
    }
    function onUp() {
      const g = ghostR.current;
      if (g) { const n={...schedR.current}; n[g.taskId]={start:g.start,end:g.end}; changR.current(n); }
      setDrag(null); setGhost(null);
    }
    function onKey(e) { if (e.key==='Escape'){setDrag(null);setGhost(null);} }
    document.addEventListener('mousemove',onMove);
    document.addEventListener('mouseup',onUp);
    document.addEventListener('keydown',onKey);
    return()=>{document.removeEventListener('mousemove',onMove);document.removeEventListener('mouseup',onUp);document.removeEventListener('keydown',onKey);};
  }, [drag]);

  function unschedule(id) { const n={...schedule}; delete n[id]; onScheduleChange(n); }

  function quickSchedule(id) {
    const occ = tasks.filter(t=>schedule[t.id]).map(t=>schedule[t.id]);
    const lastEnd = occ.length ? Math.max(...occ.map(o=>o.end)) : 0;
    const earliest = Math.max(SCHED_START*60, Math.ceil(nowMin/SCHED_SNAP)*SCHED_SNAP);
    let s = Math.max(earliest, Math.ceil(lastEnd/SCHED_SNAP)*SCHED_SNAP);
    if(s+SCHED_SNAP<=SCHED_END*60){ const n={...schedule}; n[id]={start:s,end:Math.min(s+SCHED_DEF,SCHED_END*60)}; onScheduleChange(n); }
  }

  function startMove(id) { setDrag({ taskId:id, type:'move', orig:schedule[id], col:_colOf(schedule[id].start) }); }
  function startResize(id, _e, dir) { setDrag({ taskId:id, type:dir==='top'?'resize-top':'resize', orig:schedule[id], col:_colOf(schedule[id].start) }); }

  /* ═══ Render ═══ */
  return (
    <div style={{display:'flex',flexDirection:'column',userSelect:drag?'none':'auto'}}>
      {addForm && <div style={{padding:'8px 10px 6px',flexShrink:0}}>{addForm}</div>}

      {/* Seksjonstittel — samme stil som kort-titlene, med luft over timelinjen */}
      <div style={{
        fontSize:10,fontWeight:700,color:'var(--sec)',textTransform:'uppercase',
        letterSpacing:'1.2px',padding:'12px 2px 12px',flexShrink:0,
      }}>Tidsplan</div>

      {/* Two-column timeline — natural height, no internal scrolling. En tynn
          vertikal skillelinje skiller de to kolonnene (morgen/dag og kveld). */}
      <div style={{display:'flex',gap:12,flexShrink:0,alignItems:'stretch'}}>
        {SCHED_COLS.map((col, idx) => (
          <React.Fragment key={idx}>
            {idx === 1 && <div style={{width:1,background:'var(--surface-b)',flexShrink:0,alignSelf:'stretch'}}/>}
            <SchedColumn col={col} colIdx={idx} colRef={colRefs[idx]}
              scheduled={scheduled} schedule={schedule} ghost={ghost} nowMin={nowMin} drag={drag}
              onToggle={onToggleTask} onEdit={onEditTask}
              onUnschedule={unschedule}
              onMoveStart={(id)=>startMove(id)}
              onResizeStart={startResize}
            />
          </React.Fragment>
        ))}
      </div>

      {/* ── Unscheduled — drag-anywhere row, visible checkbox ── */}
      {unscheduled.length > 0 && (
        <div style={{
          borderTop:'1px solid var(--surface-b)',
          padding:'6px 8px 6px',flexShrink:0,
        }}>
          <div style={{fontSize:9,fontWeight:700,color:'var(--mut)',textTransform:'uppercase',letterSpacing:'1px',padding:'0 1px 4px'}}>
            Uplanlagt · {unscheduled.length}
          </div>
          {unscheduled.map(t => (
            <div key={t.id}
              onContextMenu={e => window.openFocusMenu && window.openFocusMenu(e, { id: t.id, text: _taskLabel(t), type: 'todo', done: !!t.completed, source: t.__gp, parentName: t.parentName })}
              onMouseDown={e=>{
                if(e.button!==0) return;
                if(e.target.closest('[data-nd]')) return;
                e.preventDefault();
                setDrag({taskId:t.id,type:'new'});
              }}
              style={{
                display:'flex',alignItems:'center',gap:8,padding:'4px 2px',borderRadius:6,
                cursor:'grab',transition:'background 0.1s',
              }}
              onMouseEnter={e=>e.currentTarget.style.background=SCHED_ROW_HOV}
              onMouseLeave={e=>e.currentTarget.style.background='transparent'}
            >
              {/* Checkbox — visible */}
              <button data-nd onClick={e=>{e.stopPropagation();onToggleTask(t);}} style={{
                width:16,height:16,borderRadius:4,padding:0,flexShrink:0,
                border:`2px solid ${SCHED_ACCENT}`,
                background:t.completed ? SCHED_ACCENT : SCHED_CHECK_BG,
                boxShadow:'0 1px 2px rgba(0,0,0,0.15)',
                cursor:'pointer',
                display:'flex',alignItems:'center',justifyContent:'center',
              }}>
                {t.completed && <svg width="10" height="10" viewBox="0 0 14 14" fill="none"><path d="M2.5 7l3 3L11.5 4" stroke="#000" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/></svg>}
              </button>
              {/* Text (+ goal/project subtitle) — only text opens the editor */}
              <div data-nd onClick={()=>onEditTask(t)} style={{
                display:'flex',flexDirection:'column',gap:0,flex:1,minWidth:0,cursor:'pointer',
              }}>
                <span style={{
                  fontSize:11,color:t.__overdue?SCHED_ORANGE:'var(--pri)',fontWeight:t.__overdue?600:500,
                  overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',lineHeight:1.25,
                }}>{_taskLabel(t)}</span>
                {t.__gp && t.parentName && (
                  <span style={{
                    fontSize:9,color:'var(--mut)',display:'flex',alignItems:'center',gap:3,
                    overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',lineHeight:1.25,
                  }}>
                    <i className={`ti ${t.__gp === 'goal' ? 'ti-target-arrow' : 'ti-layout-grid'}`} style={{fontSize:9,color:'var(--accent)',opacity:0.8}}></i>{t.parentName}
                  </span>
                )}
              </div>
              {t.__overdue && (() => {
                const raw = String(t.due_at || t.due_date || '').slice(0, 10);
                if (!raw) return null;
                const d = new Date(raw);
                if (isNaN(d)) return null;
                const dateStr = d.toLocaleDateString('no-NO', { day:'numeric', month:'short' });
                return (
                  <span style={{fontSize:10,fontWeight:600,color:SCHED_ORANGE,flexShrink:0,fontVariantNumeric:'tabular-nums'}}>{dateStr}</span>
                );
              })()}
              {/* Quick schedule — appends after last scheduled task */}
              <button data-nd onClick={()=>quickSchedule(t.id)} title="Planlegg etter siste todo" style={{
                width:26,height:26,borderRadius:6,border:'none',
                background:'transparent',color:'var(--mut)',cursor:'pointer',
                display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0,
                transition:'color 0.12s',padding:0,opacity:0.55,
              }}
              onMouseEnter={e=>{e.currentTarget.style.color=SCHED_ACCENT;e.currentTarget.style.opacity='1';}}
              onMouseLeave={e=>{e.currentTarget.style.color='var(--mut)';e.currentTarget.style.opacity='0.55';}}>
                <svg width="15" height="15" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5">
                  <circle cx="7" cy="7" r="5.5"/><path d="M7 4v3l2 1.5"/>
                </svg>
              </button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

window.DaySchedule = DaySchedule;
