// JAVIS — calendar views (Today / Week / Month) + event card

// ----- Category map -----
const CATEGORIES = {
  "운동":   { color: "#7256FF", bg: "rgba(114,86,255,0.15)",   fg: "#B8AAFF", label: "운동" },
  "식사":   { color: "#FF8800", bg: "rgba(255,136,0,0.15)",    fg: "#F3C896", label: "식사" },
  "업무":   { color: "rgba(255,255,255,0.45)", bg: "rgba(255,255,255,0.08)", fg: "#EDEDED", label: "업무" },
  "약속":   { color: "#A855F7", bg: "rgba(168,85,247,0.15)",   fg: "#D8B4FE", label: "약속" },
  "개인":   { color: "#999999", bg: "rgba(153,153,153,0.12)",  fg: "#BFBFBF", label: "개인" },
  "이동":   { color: "#717171", bg: "rgba(113,113,113,0.12)",  fg: "#999999", label: "이동" },
};
const CAT_KEYS = Object.keys(CATEGORIES);
function cat(name) { return CATEGORIES[name] || CATEGORIES["개인"]; }
window.CATEGORIES = CATEGORIES;
window.CAT_KEYS = CAT_KEYS;
window.catLookup = cat;

// ----- Date helpers -----
const DOW_KO = ["일", "월", "화", "수", "목", "금", "토"];
function fmtDateKR(d) {
  return `${d.getFullYear()}년 ${d.getMonth()+1}월 ${d.getDate()}일 (${DOW_KO[d.getDay()]})`;
}
function fmtMonthKR(d) {
  return `${d.getFullYear()}년 ${d.getMonth()+1}월`;
}
function fmtTime12(hhmm) {
  if (!hhmm) return "";
  const [h, m] = hhmm.split(":").map(Number);
  const ampm = h < 12 ? "오전" : "오후";
  const h12 = h % 12 === 0 ? 12 : h % 12;
  return `${ampm} ${h12}:${String(m).padStart(2,"0")}`;
}
function fmtTimeShort(hhmm) {
  if (!hhmm) return "";
  const [h, m] = hhmm.split(":").map(Number);
  if (m === 0) return `${h}시`;
  return `${h}:${String(m).padStart(2,"0")}`;
}
function isoDate(d) {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const dd = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${dd}`;
}
function sameDay(a, b) { return a.getFullYear()===b.getFullYear() && a.getMonth()===b.getMonth() && a.getDate()===b.getDate(); }
function startOfWeek(d) {
  // week starts Sunday
  const nd = new Date(d); nd.setHours(0,0,0,0);
  nd.setDate(nd.getDate() - nd.getDay());
  return nd;
}
function addDays(d, n) { const nd = new Date(d); nd.setDate(nd.getDate()+n); return nd; }
function hhmmToMins(h) { const [a,b] = h.split(":").map(Number); return a*60+(b||0); }

window.fmtDateKR = fmtDateKR;
window.fmtMonthKR = fmtMonthKR;
window.fmtTime12 = fmtTime12;
window.fmtTimeShort = fmtTimeShort;
window.isoDate = isoDate;
window.sameDay = sameDay;
window.startOfWeek = startOfWeek;
window.addDays = addDays;
window.hhmmToMins = hhmmToMins;
window.DOW_KO = DOW_KO;

// ----- Event card -----
const EventCard = ({ ev, isPast, justAdded, onDelete }) => {
  const c = cat(ev.category);
  return (
    <div
      className={`event ${isPast ? "is-past":""} ${justAdded ? "is-just-added":""}`}
      style={{ "--cat-color": c.color, "--cat-bg": c.bg, "--cat-fg": c.fg }}
    >
      <div className="e-top">
        <span className="e-time">{fmtTime12(ev.start)}{ev.end ? ` – ${fmtTime12(ev.end)}` : ""}</span>
        <span className="e-cat">{c.label}</span>
        <div className="e-actions">
          <BmButton variant="outline-danger" size="icon-xs" title="삭제" onClick={() => onDelete(ev.id)}>
            <JIcon name="trash" size={14} />
          </BmButton>
        </div>
      </div>
      <div className="e-title">{ev.title}</div>
      {(ev.location || ev.reminder || ev.attendees) && (
        <div className="e-meta">
          {ev.location && (
            <span className="e-meta-item"><JIcon name="map-pin" size={14}/> {ev.location}</span>
          )}
          {ev.attendees && (
            <span className="e-meta-item"><JIcon name="users" size={14}/> {ev.attendees}</span>
          )}
          {ev.reminder && (
            <span className="e-meta-item has-reminder"><JIcon name="bell" size={14}/> {ev.reminder}</span>
          )}
        </div>
      )}
    </div>
  );
};

// ----- TODAY view -----
const TodayView = ({ events, now, justAddedId, onDelete }) => {
  const dayEvents = events
    .filter(e => e.date === isoDate(now))
    .sort((a,b) => hhmmToMins(a.start) - hhmmToMins(b.start));

  // category breakdown
  const breakdown = {};
  for (const e of dayEvents) breakdown[e.category] = (breakdown[e.category]||0) + 1;

  const nextEvent = dayEvents.find(e => hhmmToMins(e.start) >= now.getHours()*60 + now.getMinutes());

  const hours = Array.from({length: 18}, (_, i) => i + 6); // 6 AM → 11 PM

  const nowMins = now.getHours()*60 + now.getMinutes();
  const hourHeight = 64;
  // top offset within track:
  function pxFor(mins) {
    const startOfRange = 6*60;
    return ((mins - startOfRange) / 60) * hourHeight;
  }

  // place events absolutely inside one tall track
  return (
    <div className="today-grid">
      <aside className="today-summary">
        <div className="summary-stat">
          <div className="num">{dayEvents.length}</div>
          <div className="lbl">오늘의 일정</div>
        </div>
        {nextEvent ? (
          <div className="summary-stat next">
            <div className="lbl">다음 일정</div>
            <div className="num">{fmtTime12(nextEvent.start)}</div>
            <div className="next-title">{nextEvent.title}</div>
            {nextEvent.location && (
              <div className="next-meta">
                <JIcon name="map-pin" size={13}/> {nextEvent.location}
              </div>
            )}
          </div>
        ) : (
          <div className="summary-stat">
            <div className="lbl">남은 일정</div>
            <div className="num" style={{fontSize: "20px", color: "var(--color-slate)"}}>없음</div>
          </div>
        )}
        {Object.keys(breakdown).length > 0 && (
          <div className="summary-stat" style={{gap: 10}}>
            <div className="lbl" style={{marginBottom: 4}}>카테고리</div>
            <div className="category-breakdown">
              {Object.entries(breakdown).map(([k, v]) => (
                <div className="cat-row" key={k}>
                  <span className="dot" style={{background: cat(k).color}}/>
                  <span>{k}</span>
                  <span className="count">{v}</span>
                </div>
              ))}
            </div>
          </div>
        )}
      </aside>

      <div className="timeline" style={{position: "relative"}}>
        {hours.map(h => (
          <div className="timeline-hour" key={h}>
            <div className="hour-label">{fmtTime12(`${String(h).padStart(2,"0")}:00`)}</div>
            <div className="hour-track"/>
          </div>
        ))}
        {/* now line */}
        {now.getHours() >= 6 && now.getHours() < 24 && (
          <div
            className="now-line"
            data-label={fmtTime12(`${String(now.getHours()).padStart(2,"0")}:${String(now.getMinutes()).padStart(2,"0")}`)}
            style={{ top: pxFor(nowMins) + "px", left: 60 + "px" }}
          />
        )}
        {/* events overlaid as absolute */}
        <div style={{position: "absolute", left: 68, right: 8, top: 0, bottom: 0, pointerEvents: "none"}}>
          {dayEvents.map(ev => {
            const top = pxFor(hhmmToMins(ev.start));
            const dur = ev.end ? Math.max(40, hhmmToMins(ev.end) - hhmmToMins(ev.start)) : 60;
            const height = Math.max(56, (dur/60) * hourHeight - 6);
            const past = hhmmToMins(ev.start) + (ev.end ? (hhmmToMins(ev.end)-hhmmToMins(ev.start)) : 60) < nowMins;
            return (
              <div key={ev.id} style={{position: "absolute", top: top + "px", left: 0, right: 0, pointerEvents: "auto"}}>
                <EventCard
                  ev={ev}
                  isPast={past}
                  justAdded={ev.id === justAddedId}
                  onDelete={onDelete}
                />
              </div>
            );
          })}
        </div>
        {/* spacer */}
        <div style={{height: 6}}/>
      </div>
    </div>
  );
};

// ----- WEEK view -----
const WeekView = ({ events, anchor, today, justAddedId, onDelete }) => {
  const start = startOfWeek(anchor);
  const days = Array.from({length: 7}, (_, i) => addDays(start, i));
  const hours = Array.from({length: 16}, (_, i) => i + 7); // 7 AM → 10 PM
  const HOUR = 64;

  return (
    <div className="week-grid">
      <div/>
      {days.map(d => (
        <div className="day-cell" key={isoDate(d)}>
          <div className={`day-cell ${sameDay(d, today) ? "is-today" : ""}`} style={{display: "flex", flexDirection: "column", alignItems: "flex-start", padding: 0}}>
            <span className="dow">{DOW_KO[d.getDay()]}</span>
            <span className="dom">{d.getDate()}</span>
          </div>
        </div>
      ))}
      {hours.map(h => (
        <React.Fragment key={h}>
          <div className="week-hour-label">{h === 12 ? "정오" : (h < 12 ? `${h}AM` : `${h-12}PM`)}</div>
          {days.map(d => {
            const isToday = sameDay(d, today);
            return (
              <div
                key={`${h}-${isoDate(d)}`}
                className={`week-cell ${isToday ? "is-today-col":""}`}
                style={{height: HOUR}}
              >
                {/* events that start in this hour on this day */}
                {events.filter(e => e.date === isoDate(d) && hhmmToMins(e.start) >= h*60 && hhmmToMins(e.start) < (h+1)*60)
                  .map(ev => {
                    const c = cat(ev.category);
                    const top = ((hhmmToMins(ev.start) - h*60)/60)*HOUR;
                    const dur = ev.end ? (hhmmToMins(ev.end) - hhmmToMins(ev.start)) : 60;
                    const rawHeight = (dur/60)*HOUR - 4;
                    const height = Math.max(48, rawHeight);
                    const isShort = rawHeight < 56;
                    return (
                      <div
                        key={ev.id}
                        className={`week-event ${isShort ? "is-short":""}`}
                        title={`${fmtTime12(ev.start)} ${ev.title}`}
                        style={{
                          top: top + "px",
                          height: height + "px",
                          "--cat-color": c.color, "--cat-bg": c.bg, "--cat-fg": c.fg
                        }}
                      >
                        {isShort ? (
                          <span className="we-line">
                            <span className="we-time-inline">{fmtTimeShort(ev.start)}</span>
                            <span className="we-title-inline">{ev.title}</span>
                          </span>
                        ) : (
                          <>
                            <span className="we-time">{fmtTimeShort(ev.start)}</span>
                            <span className="we-title">{ev.title}</span>
                          </>
                        )}
                      </div>
                    );
                  })}
              </div>
            );
          })}
        </React.Fragment>
      ))}
    </div>
  );
};

// ----- MONTH view -----
const MonthView = ({ events, anchor, today, onDelete }) => {
  const firstOfMonth = new Date(anchor.getFullYear(), anchor.getMonth(), 1);
  const gridStart = startOfWeek(firstOfMonth);
  const cells = Array.from({length: 42}, (_, i) => addDays(gridStart, i));
  const nowMins = today.getHours()*60 + today.getMinutes();

  return (
    <>
      <div className="month-grid">
        {DOW_KO.map(d => <div className="month-dow" key={d}>{d}</div>)}
        {cells.map(c => {
          const isThisMonth = c.getMonth() === anchor.getMonth();
          const isToday = sameDay(c, today);
          const evs = events
            .filter(e => e.date === isoDate(c))
            .sort((a,b) => hhmmToMins(a.start) - hhmmToMins(b.start));
          return (
            <div
              key={isoDate(c)}
              className={`month-cell ${isThisMonth ? "" : "is-other-month"} ${isToday ? "is-today":""}`}
            >
              <div className="month-num">{c.getDate()}</div>
              {evs.slice(0, 3).map(ev => {
                const cc = cat(ev.category);
                const start = hhmmToMins(ev.start);
                const end = ev.end ? hhmmToMins(ev.end) : start + 60;
                const isNow = isToday && start <= nowMins && nowMins < end;
                return (
                  <div
                    key={ev.id}
                    className={`month-chip ${isNow ? "is-now" : ""}`}
                    style={{"--cat-color": cc.color, "--cat-bg": cc.bg, "--cat-fg": cc.fg}}
                    title={`${fmtTime12(ev.start)} ${ev.title}${isNow ? " (진행 중)" : ""}`}
                  >
                    <span className="mc-time">{fmtTimeShort(ev.start)}</span>{ev.title}
                  </div>
                );
              })}
              {evs.length > 3 && (
                <div className="more">+{evs.length - 3}</div>
              )}
            </div>
          );
        })}
      </div>
    </>
  );
};

// ----- Today agenda panel (used as sidebar in Month view) -----
const TodayAgendaPanel = ({ events, now, justAddedId, onDelete }) => {
  const dayEvents = events
    .filter(e => e.date === isoDate(now))
    .sort((a,b) => hhmmToMins(a.start) - hhmmToMins(b.start));
  const nowMins = now.getHours()*60 + now.getMinutes();

  // categorize breakdown
  const breakdown = {};
  for (const e of dayEvents) breakdown[e.category] = (breakdown[e.category]||0) + 1;

  const nextEvent = dayEvents.find(e => hhmmToMins(e.start) >= nowMins);

  return (
    <aside className="today-agenda">
      <div className="ta-head">
        <div className="ta-eyebrow">오늘</div>
        <div className="ta-title">{fmtDateKR(now)}</div>
        <div className="ta-count">
          <span className="ta-count-num">{dayEvents.length}</span>
          <span className="ta-count-lbl">개의 일정</span>
        </div>
      </div>

      {nextEvent && (
        <div className="ta-next">
          <div className="ta-next-lbl">다음 일정</div>
          <div className="ta-next-time">{fmtTime12(nextEvent.start)}</div>
          <div className="ta-next-title">{nextEvent.title}</div>
          {nextEvent.location && (
            <div className="ta-next-meta">
              <JIcon name="map-pin" size={13}/> {nextEvent.location}
            </div>
          )}
        </div>
      )}

      <div className="ta-list-head">
        <span>전체 일정</span>
        {Object.keys(breakdown).length > 0 && (
          <span className="ta-dots">
            {Object.entries(breakdown).map(([k, v]) => (
              <span key={k} className="ta-dot" title={`${k} ${v}건`} style={{background: cat(k).color}}/>
            ))}
          </span>
        )}
      </div>

      <div className="ta-list">
        {dayEvents.length === 0 && (
          <div className="ta-empty">
            <div className="ta-empty-icon"><JIcon name="calendar" size={20}/></div>
            <div>오늘은 일정이 없습니다.</div>
            <div className="ta-empty-sub">아래에서 자연어로 일정을 추가해 보세요.</div>
          </div>
        )}
        {dayEvents.map(ev => {
          const c = cat(ev.category);
          const end = ev.end ? hhmmToMins(ev.end) : (hhmmToMins(ev.start) + 60);
          const past = end < nowMins;
          const isCurrent = !past && hhmmToMins(ev.start) <= nowMins;
          return (
            <div
              key={ev.id}
              className={`agenda-row ${past ? "is-past":""} ${isCurrent ? "is-now":""} ${ev.id===justAddedId ? "is-just-added":""}`}
              style={{ "--cat-color": c.color, "--cat-bg": c.bg, "--cat-fg": c.fg }}
            >
              <div className="ag-time">
                <span className="ag-time-main">{fmtTimeShort(ev.start)}</span>
                <span className="ag-time-ampm">{hhmmToMins(ev.start) < 12*60 ? "AM" : "PM"}</span>
              </div>
              <div className="ag-body">
                <div className="ag-row1">
                  <span className="ag-title">{ev.title}</span>
                  <BmButton variant="outline-neutral-ghost" size="icon-xs" onClick={() => onDelete(ev.id)} title="삭제">
                    <JIcon name="x" size={13}/>
                  </BmButton>
                </div>
                <div className="ag-row2">
                  <span className="ag-cat">{c.label}</span>
                  {ev.location && (
                    <span className="ag-loc"><JIcon name="map-pin" size={12}/>{ev.location}</span>
                  )}
                  {ev.reminder && (
                    <span className="ag-rem"><JIcon name="bell" size={12}/>{ev.reminder}</span>
                  )}
                </div>
              </div>
            </div>
          );
        })}
      </div>
    </aside>
  );
};

Object.assign(window, { EventCard, TodayView, WeekView, MonthView, TodayAgendaPanel });
