// ---------- Month Calendar View (Monday start, multi-day bars) ----------
const { useMemo: useMemoCal } = React;

const WEEKDAYS_MON = ['월', '화', '수', '목', '금', '토', '일'];

function MonthCalendar({ cursor, setCursor, items, tab, onItemClick, onDayDetail, onDayCreate, tabAccent }) {
  const grid = useMemoCal(() => D.monthGrid(cursor), [cursor]);
  const weeks = useMemoCal(() => {
    const out = [];
    for (let i = 0; i < 6; i++) out.push(grid.slice(i * 7, i * 7 + 7));
    return out;
  }, [grid]);

  const today = new Date();
  const todayISO = D.toISO(today);
  const curMonth = cursor.getMonth();

  const renderWeek = (week, wi) => {
    const wkStartISO = D.toISO(week[0]);
    const wkEndISO = D.toISO(week[6]);

    // collect items visible in this week
    const evs = items.filter((it) => {
      const d0 = itemDateISO(it);
      if (!d0) return false;
      if (it.tab === 'todo') {
        const endISO = ((it.endISO || it.startISO || '')).slice(0, 10);
        return d0 <= wkEndISO && endISO >= wkStartISO;
      }
      return d0 >= wkStartISO && d0 <= wkEndISO;
    });

    // sort: multi-day TODO first by start, then single-day by start time
    evs.sort((a, b) => {
      const aSpan = a.tab === 'todo' ? (((a.endISO || '').slice(0, 10)) > ((a.startISO || '').slice(0, 10))) : false;
      const bSpan = b.tab === 'todo' ? (((b.endISO || '').slice(0, 10)) > ((b.startISO || '').slice(0, 10))) : false;
      if (aSpan !== bSpan) return aSpan ? -1 : 1;
      const aD = itemDateISO(a) + (a.startISO || '').slice(11);
      const bD = itemDateISO(b) + (b.startISO || '').slice(11);
      return aD.localeCompare(bD);
    });

    // lane assignment
    const lanes = [];
    const placed = evs.map((it) => {
      let s = itemDateISO(it);
      let e = s;
      if (it.tab === 'todo' && it.endISO) e = it.endISO.slice(0, 10);
      const startInWk = s < wkStartISO ? 0 : week.findIndex((d) => D.toISO(d) === s);
      const endInWk = e > wkEndISO ? 6 : week.findIndex((d) => D.toISO(d) === e);
      let lane = 0;
      while (lanes[lane] && lanes[lane].some((r) => !(endInWk < r.s || startInWk > r.e))) lane++;
      if (!lanes[lane]) lanes[lane] = [];
      lanes[lane].push({ s: startInWk, e: endInWk });
      return {
        it,
        lane,
        startInWk: Math.max(0, startInWk),
        endInWk: Math.max(0, endInWk),
        contLeft: s < wkStartISO,
        contRight: e > wkEndISO,
      };
    });

    const visibleLanes = 5; // mobile: 3 via CSS
    const visible = placed.filter((p) => p.lane < visibleLanes);
    const hiddenPerDay = Array(7).fill(0);
    placed.forEach((p) => {
      if (p.lane >= visibleLanes) {
        for (let d = p.startInWk; d <= p.endInWk; d++) hiddenPerDay[d]++;
      }
    });

    return (
      <div className="cal-week" key={wi}>
        <div className="cal-week-cells">
          {week.map((d, di) => {
            const iso = D.toISO(d);
            const inMonth = d.getMonth() === curMonth;
            const isToday = iso === todayISO;
            const dow = di; // 0..6 (Mon..Sun)
            const isWeekend = dow >= 5;
            return (
              <button
                key={iso}
                className={
                  'cal-cell' +
                  (inMonth ? '' : ' out') +
                  (isToday ? ' today' : '') +
                  (isWeekend ? ' wknd' : '')
                }
                onClick={() => onDayCreate(d)}
              >
                <span className={'cal-num' + (isToday ? ' today-num' : '')}>{d.getDate()}</span>
                {inMonth && d.getDate() === 1 && <span className="cal-month-tag">{d.getMonth()+1}월</span>}
              </button>
            );
          })}
        </div>

        <div className="cal-bars">
          {visible.map((p, idx) => {
            const left = (p.startInWk / 7) * 100;
            const width = ((p.endInWk - p.startInWk + 1) / 7) * 100;
            const c = COLOR_BY_ID[p.it.color] || COLOR_BY_ID.blue;
            const done = p.it.tab === 'todo' && p.it.status === 'done';
            return (
              <button
                key={p.it.id + ':' + wi + ':' + idx}
                className={'cal-bar' + (done ? ' done' : '')}
                style={{
                  left: `calc(${left}% + 2px)`,
                  width: `calc(${width}% - 4px)`,
                  '--lane': p.lane,
                  '--bar-color': c.hex,
                  borderTopLeftRadius: p.contLeft ? 0 : 4,
                  borderBottomLeftRadius: p.contLeft ? 0 : 4,
                  borderTopRightRadius: p.contRight ? 0 : 4,
                  borderBottomRightRadius: p.contRight ? 0 : 4,
                }}
                onClick={(e) => { e.stopPropagation(); onItemClick(p.it); }}
                title={p.it.title || '(제목 없음)'}
              >
                {p.it.urgent && (
                  <span className="cal-bar-ico" aria-label="긴급"><Icon.Flame size={10} filled fillColor={c.hex} stroke={c.hex} /></span>
                )}
                {p.it.important && (
                  <span className="cal-bar-ico" aria-label="중요"><Icon.Star size={10} filled fillColor={c.hex} stroke={c.hex} /></span>
                )}
                <span className="cal-bar-title">{p.it.title || '(제목 없음)'}</span>
              </button>
            );
          })}

          {hiddenPerDay.map((n, di) =>
            n > 0 ? (
              <button
                key={'more-' + di}
                className="cal-more"
                style={{ left: `calc(${(di / 7) * 100}% + 2px)`, width: `calc(${100 / 7}% - 4px)`, '--lane': visibleLanes }}
                onClick={(e) => { e.stopPropagation(); onDayDetail(week[di]); }}
              >
                +{n}개 더
              </button>
            ) : null
          )}
        </div>
      </div>
    );
  };

  return (
    <div className="cal">
      <div className="cal-head">
        {WEEKDAYS_MON.map((w, i) => (
          <div key={w} className={'cal-head-cell' + (i >= 5 ? ' wknd' : '')}>{w}</div>
        ))}
      </div>
      <div className="cal-body">
        {weeks.map(renderWeek)}
      </div>

      <style>{`
        .cal{background:var(--bg);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
        .cal-head{display:grid;grid-template-columns:repeat(7,1fr);border-bottom:1px solid var(--line);background:var(--bg-soft)}
        .cal-head-cell{padding:10px 12px;font-size:11px;font-weight:600;letter-spacing:.04em;color:var(--ink-3);text-align:left}
        .cal-head-cell.wknd{color:var(--ink-2)}
        .cal-body{display:flex;flex-direction:column}
        .cal-week{position:relative;border-bottom:1px solid var(--line);min-height:168px}
        .cal-week:last-child{border-bottom:none}
        .cal-week-cells{display:grid;grid-template-columns:repeat(7,1fr);min-height:168px}
        .cal-cell{position:relative;border-right:1px solid var(--line);background:transparent;padding:6px 8px 0;text-align:left;cursor:pointer;transition:background .12s;font-family:inherit;border-top:none;border-bottom:none;border-left:none;display:flex;flex-direction:column;align-items:flex-end;gap:2px}
        .cal-cell:last-child{border-right:none}
        .cal-cell:hover{background:var(--bg-soft)}
        .cal-cell.out{background:var(--bg-soft)}
        .cal-cell.out .cal-num{color:var(--ink-4);opacity:.5}
        .cal-cell.wknd .cal-num{color:var(--ink-2)}
        .cal-num{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;font-size:11.5px;font-weight:600;color:var(--ink-2);border-radius:6px;padding:0 4px;font-variant-numeric:tabular-nums}
        .cal-num.today-num{background:var(--tab-accent,var(--ink));color:#fff;font-weight:700}
        .cal-month-tag{font-size:9.5px;font-weight:600;color:var(--ink-3);letter-spacing:.02em;line-height:1}

        .cal-bars{position:absolute;inset:0;pointer-events:none}
        .cal-bar{
          position:absolute;
          top:calc(34px + var(--lane) * 23px);
          height:21px;
          padding:0 7px;
          display:flex;align-items:center;gap:4px;
          background: var(--bar-color);
          color:#fff;
          font-size:11px;font-weight:600;line-height:1;letter-spacing:-.01em;
          border:none;border-radius:5px;
          cursor:pointer;pointer-events:auto;overflow:hidden;
          font-family:inherit;text-align:left;
          box-shadow:0 1px 0 rgba(0,0,0,.05);
        }
        .cal-bar:hover{ filter:brightness(1.08); }
        .cal-bar.done{ opacity:.5; text-decoration:line-through; text-decoration-thickness:1.5px; }
        .cal-bar-ico{display:inline-flex;flex-shrink:0;color:#fff;opacity:.95}
        .cal-bar-title{overflow:hidden;white-space:nowrap;flex:1;min-width:0}

        .cal-more{
          position:absolute;
          top:calc(34px + var(--lane) * 23px);
          height:21px; padding:0 6px;
          background:transparent;border:none;
          font-size:11px;color:var(--ink-2);cursor:pointer;pointer-events:auto;text-align:left;font-weight:600;
          font-family:inherit;
        }
        .cal-more:hover{color:var(--ink);text-decoration:underline}

        @media (max-width: 720px){
          .cal-week{min-height:110px}
          .cal-week-cells{min-height:110px}
          .cal-cell{padding:4px 4px 0}
          .cal-num{min-width:18px;height:18px;font-size:10.5px}
          .cal-head-cell{padding:8px 6px;font-size:10.5px}
          .cal-bar{height:18px;font-size:9.5px;padding:0 5px;top:calc(28px + var(--lane) * 19px)}
          .cal-bar:nth-of-type(n+4){display:none}
          .cal-more{top:calc(28px + 3 * 19px); font-size:10px;height:16px}
          .cal-month-tag{font-size:9px}
        }
      `}</style>
    </div>
  );
}

window.MonthCalendar = MonthCalendar;
