// ─── Unified Calendar Module ─────────────────────────────
// Shows both drops and slips on a shared monthly grid with
// an unscheduled queue sidebar. CSS prefix: CAL-

function CalendarModule(props) {
  var db = props.db, showToast = props.showToast, switchTab = props.switchTab;
  var drops = props.drops || {};
  var slips = props.slips || {};

  var [calMonth, setCalMonth] = useState(function() { var d = new Date(); return { year: d.getFullYear(), month: d.getMonth() }; });
  var [filter, setFilter] = useState('all');
  var [bulkStartDate, setBulkStartDate] = useState('');
  var [selected, setSelected] = useState({});
  var [editItem, setEditItem] = useState(null);

  var [isMobile, setIsMobile] = useState(window.innerWidth < 768);
  useEffect(function(){
    function onResize(){setIsMobile(window.innerWidth < 768)}
    window.addEventListener('resize', onResize);
    return function(){window.removeEventListener('resize', onResize)};
  },[]);
  var [mobileView, setMobileView] = useState('calendar');

  // All content items with type tags
  var allContent = useMemo(function() {
    var items = [];
    Object.values(drops).forEach(function(d) {
      items.push(Object.assign({}, d, { _type: 'drop' }));
    });
    Object.values(slips).forEach(function(s) {
      items.push(Object.assign({}, s, { _type: 'slip' }));
    });
    return items;
  }, [drops, slips]);

  // Filtered content
  var filteredContent = useMemo(function() {
    if (filter === 'drops') return allContent.filter(function(c) { return c._type === 'drop'; });
    if (filter === 'slips') return allContent.filter(function(c) { return c._type === 'slip'; });
    return allContent;
  }, [allContent, filter]);

  // Scheduled content by date
  var scheduledByDate = useMemo(function() {
    var map = {};
    filteredContent.forEach(function(c) {
      if (c.scheduled_date && c.status !== 'draft') {
        if (!map[c.scheduled_date]) map[c.scheduled_date] = [];
        map[c.scheduled_date].push(c);
      }
    });
    return map;
  }, [filteredContent]);

  // Unscheduled drafts
  var drafts = useMemo(function() {
    return filteredContent
      .filter(function(c) { return c.status === 'draft' || (!c.scheduled_date && c.status !== 'published'); })
      .sort(function(a, b) { return (a.created_at || '').toString().localeCompare((b.created_at || '').toString()); });
  }, [filteredContent]);

  // Calendar helpers
  var calDays = useMemo(function() {
    var year = calMonth.year, month = calMonth.month;
    var firstDay = new Date(year, month, 1).getDay();
    var daysInMonth = new Date(year, month + 1, 0).getDate();
    var days = [];
    for (var i = 0; i < firstDay; i++) days.push(null);
    for (var d = 1; d <= daysInMonth; d++) days.push(d);
    return days;
  }, [calMonth]);

  var monthLabel = useMemo(function() {
    var months = ['JANUARY','FEBRUARY','MARCH','APRIL','MAY','JUNE','JULY','AUGUST','SEPTEMBER','OCTOBER','NOVEMBER','DECEMBER'];
    return months[calMonth.month] + ' ' + calMonth.year;
  }, [calMonth]);

  function prevMonth() {
    setCalMonth(function(p) {
      var m = p.month - 1, y = p.year;
      if (m < 0) { m = 11; y--; }
      return { year: y, month: m };
    });
  }
  function nextMonth() {
    setCalMonth(function(p) {
      var m = p.month + 1, y = p.year;
      if (m > 11) { m = 0; y++; }
      return { year: y, month: m };
    });
  }

  function dateStr(day) {
    var m = String(calMonth.month + 1).padStart(2, '0');
    var d = String(day).padStart(2, '0');
    return calMonth.year + '-' + m + '-' + d;
  }

  function toggleSelect(id) { setSelected(function(p) { var n = Object.assign({}, p); if (n[id]) delete n[id]; else n[id] = true; return n; }); }
  function selectAllDrafts() { var n = {}; drafts.forEach(function(d) { n[d.id] = true; }); setSelected(n); }
  function clearSelection() { setSelected({}); }
  var selCount = Object.keys(selected).length;

  function bulkSchedule() {
    if (!bulkStartDate || selCount === 0) return;
    var ids = Object.keys(selected);
    var updates = {};
    var start = new Date(bulkStartDate + 'T00:00:00');
    var count = 0;
    ids.forEach(function(id, i) {
      var d = new Date(start);
      d.setDate(d.getDate() + i);
      var ds = d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0');
      // Determine if drop or slip
      if (drops[id]) {
        updates['drops/' + id + '/scheduled_date'] = ds;
        updates['drops/' + id + '/status'] = 'scheduled';
        count++;
      } else if (slips[id]) {
        updates['slips/' + id + '/scheduled_date'] = ds;
        updates['slips/' + id + '/status'] = 'scheduled';
        count++;
      }
    });
    if (count === 0) { showToast('NO DRAFTS SELECTED'); return; }
    db.ref().update(updates).then(function() {
      showToast(count + ' ITEMS SCHEDULED');
      clearSelection(); setBulkStartDate('');
    }).catch(function(e) { showToast('SCHEDULE FAILED: ' + e.message); });
  }

  // Pill styling
  function getPillStyle(item) {
    if (item._type === 'slip') {
      if (item.status === 'published') {
        if (item.performance === 'fire') return { bg: 'rgba(74,222,128,.08)', color: '#4ade80', border: '#4ade80', dashed: true };
        if (item.performance === 'flop') return { bg: 'rgba(239,68,68,.08)', color: '#ef4444', border: '#ef4444', dashed: true };
        if (item.performance === 'mid') return { bg: 'rgba(156,163,175,.08)', color: '#9ca3af', border: '#9ca3af', dashed: true };
        return { bg: 'rgba(74,222,128,.08)', color: '#4ade80', border: '#4ade80', dashed: true };
      }
      return { bg: 'rgba(255,215,0,.08)', color: 'var(--gold)', border: 'var(--gold)', dashed: true };
    }
    // drops
    if (item.status === 'published') {
      if (item.performance === 'fire') return { bg: 'rgba(74,222,128,.12)', color: '#4ade80', border: '#4ade80' };
      if (item.performance === 'flop') return { bg: 'rgba(239,68,68,.12)', color: '#ef4444', border: '#ef4444' };
      if (item.performance === 'mid') return { bg: 'rgba(156,163,175,.12)', color: '#9ca3af', border: '#9ca3af' };
      return { bg: 'rgba(74,222,128,.12)', color: '#4ade80', border: '#4ade80' };
    }
    if (item.status === 'rendered') return { bg: 'rgba(0,255,255,.12)', color: 'var(--cyan)', border: 'var(--cyan)' };
    return { bg: 'rgba(255,215,0,.12)', color: 'var(--gold)', border: 'var(--gold)' };
  }

  function getItemLabel(item) {
    if (item._type === 'drop') return item.line ? item.line.substring(0, 18) : '—';
    return item.acronym || item.answer || '—';
  }

  // Stats
  var stats = useMemo(function() {
    var allDrops = Object.values(drops);
    var allSlips = Object.values(slips);
    return {
      totalDrops: allDrops.length,
      totalSlips: allSlips.length,
      draftDrops: allDrops.filter(function(d) { return d.status === 'draft'; }).length,
      draftSlips: allSlips.filter(function(s) { return s.status === 'draft'; }).length,
      scheduledDrops: allDrops.filter(function(d) { return d.status === 'scheduled' || d.status === 'rendered'; }).length,
      scheduledSlips: allSlips.filter(function(s) { return s.status === 'scheduled'; }).length,
      publishedDrops: allDrops.filter(function(d) { return d.status === 'published'; }).length,
      publishedSlips: allSlips.filter(function(s) { return s.status === 'published'; }).length
    };
  }, [drops, slips]);

  return (
    <div style={{display:'flex',flexDirection:'column',height:'100%',overflow:'hidden'}}>
      {/* Filter bar */}
      <div className="CAL-filter-bar">
        <div style={{display:'flex',gap:6}}>
          {['all','drops','slips'].map(function(f) {
            return <div key={f} className={'A-chip' + (filter === f ? ' on' : '')} onClick={function(){setFilter(f)}}>{f.toUpperCase()}</div>;
          })}
        </div>
      </div>

      {isMobile && (
        <div style={{display:'flex',gap:0,borderBottom:'1px solid var(--border)'}}>
          <button className={'A-btn' + (mobileView==='calendar'?' signal':'')} style={{flex:1,border:'none',borderBottom:mobileView==='calendar'?'2px solid var(--signal)':'2px solid transparent'}} onClick={function(){setMobileView('calendar')}}>CALENDAR</button>
          <button className={'A-btn' + (mobileView==='queue'?' signal':'')} style={{flex:1,border:'none',borderBottom:mobileView==='queue'?'2px solid var(--signal)':'2px solid transparent'}} onClick={function(){setMobileView('queue')}}>QUEUE</button>
        </div>
      )}

      <div style={{display:'flex',flex:1,overflow:'hidden'}}>
        {/* Left: Unscheduled queue */}
        <div style={{width:isMobile?'100%':300,flexShrink:0,borderRight:isMobile?'none':'1px solid var(--border)',display:isMobile?(mobileView==='queue'?'flex':'none'):'flex',flexDirection:'column',overflow:'hidden'}}>
          <div style={{padding:'12px 16px',borderBottom:'1px solid var(--border)'}}>
            <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:8}}>
              <span style={{fontSize:10,letterSpacing:2,color:'var(--signal)'}}>UNSCHEDULED ({drafts.length})</span>
            </div>
            <div style={{display:'flex',gap:6,fontSize:9}}>
              <span style={{cursor:'pointer',color:'var(--cyan)',letterSpacing:1}} onClick={selectAllDrafts}>SELECT ALL</span>
              <span style={{cursor:'pointer',color:'var(--text-dim)',letterSpacing:1}} onClick={clearSelection}>CLEAR</span>
            </div>
          </div>
          {selCount > 0 && (
            <div style={{padding:'8px 16px',borderBottom:'1px solid var(--border)',background:'rgba(255,0,127,.05)'}}>
              <div style={{fontSize:9,color:'var(--signal)',letterSpacing:1,marginBottom:6}}>{selCount} SELECTED</div>
              <div style={{display:'flex',gap:6,alignItems:'center'}}>
                <input type="date" className="A-input" style={{fontSize:isMobile?16:10,padding:'4px 6px',flex:1}} value={bulkStartDate} onChange={function(e){setBulkStartDate(e.target.value)}} />
                <button className="A-btn gold" style={{fontSize:9,padding:'4px 8px',whiteSpace:'nowrap'}} onClick={bulkSchedule} disabled={!bulkStartDate}>SCHEDULE</button>
              </div>
            </div>
          )}
          <div style={{flex:1,overflow:'auto'}}>
            {drafts.map(function(c) {
              var sel = selected[c.id];
              var badge = c._type === 'drop' ? 'D' : 'S';
              var badgeColor = c._type === 'drop' ? 'var(--signal)' : 'var(--cyan)';
              return (
                <div key={c.id} style={{
                  display:'flex',alignItems:'center',gap:8,padding:'8px 12px',borderBottom:'1px solid #1a1a1a',cursor:'pointer',
                  background:sel?'rgba(0,255,255,.05)':'transparent'
                }}>
                  <div onClick={function(e){e.stopPropagation();toggleSelect(c.id)}} style={{width:16,height:16,border:'1px solid '+(sel?'var(--cyan)':'var(--border)'),background:sel?'var(--cyan)':'transparent',flexShrink:0,cursor:'pointer'}}></div>
                  <span style={{fontSize:9,fontWeight:700,color:badgeColor,flexShrink:0,width:12,textAlign:'center'}}>{badge}</span>
                  <div style={{flex:1,minWidth:0}}>
                    <div style={{fontSize:12,color:'#e0e0e0',whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>{c._type === 'drop' ? '"' + (c.line || '—') + '"' : (c.acronym || '—')}</div>
                    <div style={{fontSize:10,color:'#888',whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>{c.source || ''} {c.medium ? '· ' + c.medium : ''}</div>
                  </div>
                </div>
              );
            })}
            {drafts.length === 0 && <div style={{padding:24,textAlign:'center',color:'var(--text-dim)',fontSize:11}}>No unscheduled content</div>}
          </div>
        </div>

        {/* Center: Calendar grid */}
        <div style={{flex:1,display:isMobile?(mobileView==='calendar'?'flex':'none'):'flex',flexDirection:'column',overflow:'hidden',minWidth:0}}>
          <div style={{padding:'12px 16px',borderBottom:'1px solid var(--border)',display:'flex',alignItems:'center',justifyContent:'space-between'}}>
            <button className="A-btn" style={{fontSize:10,padding:'4px 10px'}} onClick={prevMonth}>&#9664;</button>
            <span style={{fontSize:11,letterSpacing:2,color:'var(--signal)'}}>{monthLabel}</span>
            <button className="A-btn" style={{fontSize:10,padding:'4px 10px'}} onClick={nextMonth}>&#9654;</button>
          </div>
          <div style={{flex:1,overflow:'auto',padding:16}}>
            <div style={{display:'grid',gridTemplateColumns:'repeat(7, 1fr)',gap:2,marginBottom:8}}>
              {['SUN','MON','TUE','WED','THU','FRI','SAT'].map(function(d) {
                return <div key={d} style={{textAlign:'center',fontSize:9,color:'var(--text-dim)',letterSpacing:1,padding:4}}>{d}</div>;
              })}
            </div>
            <div style={{display:'grid',gridTemplateColumns:'repeat(7, 1fr)',gap:2}}>
              {calDays.map(function(day, idx) {
                if (day === null) return <div key={'e' + idx}></div>;
                var ds = dateStr(day);
                var dayContent = scheduledByDate[ds] || [];
                var today = new Date();
                var isToday = today.getFullYear() === calMonth.year && today.getMonth() === calMonth.month && today.getDate() === day;
                return (
                  <div key={day} style={{
                    minHeight:isMobile?60:80,padding:4,border:'1px solid ' + (isToday ? 'var(--cyan)' : 'var(--border)'),
                    background:isToday ? 'rgba(0,255,255,.03)' : 'var(--surface)'
                  }}>
                    <div style={{fontSize:10,color:isToday ? 'var(--cyan)' : 'var(--text-dim)',marginBottom:4}}>{day}</div>
                    {dayContent.map(function(item) {
                      var ps = getPillStyle(item);
                      var badge = item._type === 'drop' ? 'D' : 'S';
                      return (
                        <div key={item.id} onClick={function(){switchTab('create')}} style={{
                          fontSize:8,padding:'2px 4px',marginBottom:2,cursor:'pointer',
                          background:ps.bg, color:ps.color, border:'1px ' + (ps.dashed ? 'dashed' : 'solid') + ' ' + ps.border,
                          whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis',letterSpacing:'.5px',
                          display:'flex',alignItems:'center',gap:3
                        }}>
                          <span style={{fontWeight:700,flexShrink:0}}>{badge}</span>
                          <span style={{overflow:'hidden',textOverflow:'ellipsis'}}>{getItemLabel(item)}</span>
                        </div>
                      );
                    })}
                  </div>
                );
              })}
            </div>
          </div>
          {/* Stats footer */}
          <div style={{display:'flex',gap:16,padding:'8px 20px',borderTop:'1px solid var(--border)',fontSize:10,color:'var(--text-dim)',letterSpacing:1,flexShrink:0,background:'#000',flexWrap:'wrap'}}>
            <span>DROPS: <b style={{color:'#fff'}}>{stats.totalDrops}</b></span>
            <span>SLIPS: <b style={{color:'#fff'}}>{stats.totalSlips}</b></span>
            <span>DRAFT: <b style={{color:'var(--text-sec)'}}>{stats.draftDrops + stats.draftSlips}</b></span>
            <span>SCHEDULED: <b style={{color:'var(--gold)'}}>{stats.scheduledDrops + stats.scheduledSlips}</b></span>
            <span>PUBLISHED: <b style={{color:'#4ade80'}}>{stats.publishedDrops + stats.publishedSlips}</b></span>
          </div>
        </div>
      </div>
    </div>
  );
}
