// timeline.jsx — Timeline view: rooms x days grid with booking bars
// Click empty cell → onNewSlot(roomId, date)
// Click booking bar → onOpenBooking(id)

function Timeline({
  anchorDate, today,
  rooms, bookings, guests,
  filters,
  onNewSlot,
  onOpenBooking,
  blockStyle = 'default',  // default | outline | soft | gradient
  daysToShow = 14,
}) {
  const [tip, setTip] = React.useState(null);  // {b, x, y}

  // Build day list
  const days = React.useMemo(() => {
    const arr = [];
    for (let i = 0; i < daysToShow; i++) {
      arr.push(window.HotelData.addDays(anchorDate, i));
    }
    return arr;
  }, [anchorDate, daysToShow]);

  // Filter rooms
  const visibleRooms = React.useMemo(() => {
    return rooms.filter(r => {
      const t = r.type.startsWith('Suite') ? 'Suite' : r.type;
      if (filters.types.length && !filters.types.includes(t)) return false;
      return true;
    });
  }, [rooms, filters.types]);

  // Group rooms by floor
  const grouped = React.useMemo(() => {
    const g = {};
    visibleRooms.forEach(r => {
      if (!g[r.floor]) g[r.floor] = [];
      g[r.floor].push(r);
    });
    return g;
  }, [visibleRooms]);

  // Filter bookings
  const visibleBookings = React.useMemo(() => {
    return bookings.filter(b => filters.statuses.includes(b.status));
  }, [bookings, filters.statuses]);

  // Pre-compute width / today position
  const COL = 110;  // sync with --col-w
  const ROOM_COL = 200;
  const totalWidth = ROOM_COL + COL * daysToShow;

  // Today line position
  const todayIdx = daysBetween(anchorDate, today);
  const showTodayLine = todayIdx >= 0 && todayIdx < daysToShow;
  const todayX = ROOM_COL + COL * todayIdx + (COL * 0.5);  // place at noon

  // Booking → x, w, row
  const renderBookingBars = (roomId, roomRowIdx) => {
    const bks = visibleBookings.filter(b => b.roomId === roomId);
    return bks.map(b => {
      const startIdx = daysBetween(anchorDate, b.checkIn);
      const endIdx = daysBetween(anchorDate, b.checkOut);
      // Allow off-screen bookings to be clipped
      const visStart = Math.max(0, startIdx);
      const visEnd = Math.min(daysToShow, endIdx);
      if (visEnd <= 0 || visStart >= daysToShow) return null;
      // Inset by ~14px on each end of an unclipped edge for natural check-in/out gap
      const clipL = startIdx < 0;
      const clipR = endIdx > daysToShow;
      // Position: cell start + half day at check-in side, end at half day before checkout
      const leftPx = visStart * COL + (clipL ? 0 : COL * 0.5);
      const rightPx = visEnd * COL - (clipR ? 0 : COL * 0.5);
      const widthPx = Math.max(40, rightPx - leftPx);

      const guest = b.guestId ? findGuest(guests, b.guestId) : null;
      const isMaint = b.status === 'maintenance';
      const isCancelled = b.status === 'cancelled';
      const styleClass = blockStyle === 'default' ? 'style-default'
        : blockStyle === 'outline' ? 'style-outline'
        : blockStyle === 'soft' ? 'style-soft'
        : 'style-gradient';

      const label = isMaint
        ? '🔧 ' + (b.note ? b.note.split('.')[0] : 'Bảo trì')
        : guest ? guest.name : 'Khách';

      return (
        <div
          key={b.id}
          className={`bk ${styleClass} ${isCancelled ? 'cancelled' : ''}`}
          data-status={b.status}
          style={{
            left: leftPx + 'px',
            width: widthPx + 'px',
            opacity: isCancelled ? 0.55 : 1,
            textDecoration: isCancelled ? 'line-through' : 'none',
            borderTopLeftRadius: clipL ? 0 : undefined,
            borderBottomLeftRadius: clipL ? 0 : undefined,
            borderTopRightRadius: clipR ? 0 : undefined,
            borderBottomRightRadius: clipR ? 0 : undefined,
          }}
          onClick={(e) => { e.stopPropagation(); onOpenBooking(b.id); }}
          onMouseEnter={(e) => setTip({ b, guest, x: e.clientX, y: e.clientY })}
          onMouseMove={(e) => setTip(t => t && { ...t, x: e.clientX, y: e.clientY })}
          onMouseLeave={() => setTip(null)}
        >
          {!isMaint && guest && !clipL && (
            <span className="avatar">{initials(guest.name)}</span>
          )}
          <span className="name">{label}</span>
          {b.paymentStatus === 'paid' && !isMaint && (
            <svg className="stat-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
              <path d="M5 13l4 4 10-12"/>
            </svg>
          )}
        </div>
      );
    });
  };

  const floors = Object.keys(grouped).map(Number).sort((a, b) => a - b);

  return (
    <div className="timeline-wrap">
      <div className="tl" style={{ width: totalWidth + 'px' }}>
        <div className="tl-corner">Phòng</div>
        <div className="tl-day-row">
          {days.map((d, i) => {
            const isToday = sameDay(d, today);
            const isWeekend = d.getDay() === 0 || d.getDay() === 6;
            return (
              <div
                key={i}
                className={`tl-day ${isToday ? 'today' : ''} ${isWeekend ? 'weekend' : ''}`}
              >
                <div className="dow">{DOW_VN[d.getDay()]}</div>
                <div className="num">{d.getDate()}</div>
              </div>
            );
          })}
        </div>

        {floors.map((f, fi) => {
          const floorRooms = grouped[f];
          return (
            <React.Fragment key={f}>
              <div className="tl-floor-label">
                Tầng {f} · {floorRooms[0].type.startsWith('Suite') ? 'Suite' : floorRooms[0].type}
              </div>
              <div className="tl-floor-row">
                {days.map((d, i) => {
                  const isWeekend = d.getDay() === 0 || d.getDay() === 6;
                  return <div key={i} className={`tl-floor-cell ${isWeekend ? 'weekend' : ''}`} />;
                })}
              </div>

              {floorRooms.map((r, ri) => (
                <React.Fragment key={r.id}>
                  <div className="tl-room-label">
                    <span className={`tl-room-dot ${r.status === 'cleaning' ? 'cleaning' : r.status === 'maintenance' ? 'maint' : ''}`} />
                    <div style={{ display: 'flex', flexDirection: 'column', gap: '1px', flex: 1, minWidth: 0 }}>
                      <span className="tl-room-num">{r.name || ('Phòng ' + r.number)}</span>
                      <span className="tl-room-type">P.{r.number} · {r.type} · {VNDshort(r.price)}đ</span>
                    </div>
                  </div>
                  <div className="tl-row">
                    {days.map((d, i) => {
                      const isWeekend = d.getDay() === 0 || d.getDay() === 6;
                      const isToday = sameDay(d, today);
                      return (
                        <div
                          key={i}
                          className={`tl-cell ${isWeekend ? 'weekend' : ''} ${isToday ? 'today' : ''}`}
                          onClick={() => onNewSlot(r.id, d)}
                        />
                      );
                    })}
                    {renderBookingBars(r.id, ri)}
                  </div>
                </React.Fragment>
              ))}
            </React.Fragment>
          );
        })}

        {showTodayLine && (
          <div
            className="tl-today-line"
            style={{ left: todayX + 'px' }}
          />
        )}
      </div>

      {tip && <BookingTip {...tip} />}
    </div>
  );
}

function BookingTip({ b, guest, x, y }) {
  const wrapRef = React.useRef(null);
  const [pos, setPos] = React.useState({ x, y });
  React.useLayoutEffect(() => {
    if (!wrapRef.current) return;
    const r = wrapRef.current.getBoundingClientRect();
    let nx = x + 14, ny = y + 14;
    if (nx + r.width > window.innerWidth - 8) nx = x - r.width - 14;
    if (ny + r.height > window.innerHeight - 8) ny = y - r.height - 14;
    setPos({ x: nx, y: ny });
  }, [x, y]);
  const data = window.HotelData;
  const room = findRoom(data.rooms, b.roomId);
  const t = computeBookingTotal(b, data.rooms, data.serviceCatalog, data.inStayMenu);
  const status = data.statuses.find(s => s.key === b.status);
  return (
    <div ref={wrapRef} className="tip show" style={{ left: pos.x, top: pos.y }}>
      <div className="tip-name">{guest ? guest.name : 'Bảo trì'}</div>
      <div className="tip-row"><span>Phòng</span> <b>{room?.number} · {room?.type}</b></div>
      <div className="tip-row"><span>{formatDateShort(b.checkIn)}</span> → <b>{formatDateShort(b.checkOut)}</b></div>
      <div className="tip-row"><span>{t.nights} đêm</span></div>
      {b.status !== 'maintenance' && (
        <div className="tip-row"><span>Tổng</span> <b>{VND(t.total)}</b></div>
      )}
      <span className="tip-status" style={{ color: status?.color, background: 'rgba(255,255,255,.1)' }}>
        <span className="pill-dot" /> {status?.label}
      </span>
    </div>
  );
}

window.Timeline = Timeline;
