// Calendar grid: time column + N stylist columns with bookings
// Drag-and-drop is handled here.

const HOUR_HEIGHT = 88;          // px per hour at default density
const START_HOUR = 8;
const END_HOUR = 19;
const MINUTES_VISIBLE = (END_HOUR - START_HOUR) * 60;

function fmtTime(min) {
  const h = Math.floor(min / 60);
  const m = min % 60;
  return `${h}:${m.toString().padStart(2, '0')}`;
}

function snapToFive(min) {
  return Math.round(min / 5) * 5;
}

const Avatar = ({ name, tone, photo, size = 32 }) => {
  const initials = name.split(' ').map(w => w[0]).slice(0, 2).join('');
  if (photo) {
    return (
      <div style={{
        width: size, height: size, borderRadius: '50%',
        background: `url(${photo}) center/cover`,
        border: '1px solid #E5E2D5', flexShrink: 0,
      }} />
    );
  }
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: tone, color: '#3a2e22',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontSize: size * 0.42, fontWeight: 600, letterSpacing: '0.02em',
      flexShrink: 0,
    }}>{initials}</div>
  );
};

const StaffHeader = ({ staff }) => (
  <div style={{
    display: 'flex', alignItems: 'center', gap: 10,
    padding: '14px 16px', borderRight: '1px solid #EAEAE3',
    background: '#fff', minHeight: 60,
  }}>
    <Avatar name={staff.name} tone={staff.tone} photo={staff.photo} />
    <div style={{ fontSize: 14, fontWeight: 500, color: '#1a1a1a', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
      {staff.name}
    </div>
  </div>
);

const BookingBlock = ({ booking, palette, hourHeight, onClick, onDragStart, onDragEnd, isDragging, isGhost }) => {
  const customer = CUSTOMERS.find(c => c.id === booking.customerId);
  const segs = getBookingSegments(booking);
  if (!segs.length || !customer) return null;

  const totalDuration = getBookingDuration(booking);
  const totalHeight = (totalDuration / 60) * hourHeight;
  const totalTop = ((booking.start - START_HOUR * 60) / 60) * hourHeight;
  const primary = SERVICE_COLORS[palette][segs[0].color];

  const handleClick = (e) => { e.stopPropagation(); onClick(booking); };
  const handleDragStart = (e) => onDragStart(e, booking);

  return (
    <React.Fragment>
      {/* Thin "owned by" stripe along the left margin spanning the whole booking — incl. mellemrum.
          This shows the customer owns this slot, but does NOT block other bookings from sitting in the gap. */}
      <div style={{
        position: 'absolute',
        top: totalTop, left: 0, width: 3, height: totalHeight - 2,
        background: primary.border,
        opacity: isGhost ? 0.3 : 0.55,
        borderRadius: 2,
        pointerEvents: 'none',
      }} />

      {/* Each segment rendered separately. Work segments are clickable/draggable; gap segments are passive (let other bookings sit on them). */}
      {segs.map((seg, i) => {
        const segTop = ((seg.start - START_HOUR * 60) / 60) * hourHeight;
        const segH = ((seg.end - seg.start) / 60) * hourHeight;

        if (seg.kind === 'gap') {
          return (
            <div key={i} style={{
              position: 'absolute',
              top: segTop, left: 6, right: 4, height: segH - 1,
              background: 'repeating-linear-gradient(45deg, rgba(180,170,140,0.08), rgba(180,170,140,0.08) 6px, rgba(180,170,140,0.18) 6px, rgba(180,170,140,0.18) 12px)',
              border: '1px dashed rgba(120,110,90,0.3)',
              borderRadius: 4,
              pointerEvents: 'none',
              opacity: isGhost ? 0.3 : 0.6,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontSize: 10, color: 'rgba(60,50,30,0.65)', fontStyle: 'italic',
              zIndex: 1,
              overflow: 'hidden',
            }}>
              {segH > 18 && `Mellemrum · ${seg.end - seg.start} min`}
            </div>
          );
        }

        const c = SERVICE_COLORS[palette][seg.color];
        const compactSeg = segH < 38;
        const isFirstWork = !segs.slice(0, i).some(s => s.kind === 'work');

        return (
          <div
            key={i}
            draggable
            onDragStart={handleDragStart}
            onDragEnd={onDragEnd}
            onClick={handleClick}
            style={{
              position: 'absolute',
              top: segTop, left: 6, right: 4, height: segH - 2,
              background: c.bg, color: c.text,
              borderLeft: `3px solid ${c.border}`,
              borderRadius: 5,
              padding: compactSeg ? '2px 8px' : '5px 10px',
              cursor: 'grab',
              opacity: isGhost ? 0.35 : 1,
              boxShadow: isDragging ? '0 8px 24px rgba(0,0,0,0.18)' : 'none',
              transform: isDragging ? 'scale(1.02)' : 'none',
              transition: isDragging ? 'none' : 'opacity 120ms, box-shadow 120ms',
              userSelect: 'none',
              overflow: 'hidden',
              zIndex: 2,
              display: 'flex',
              flexDirection: 'column',
              gap: compactSeg ? 0 : 2,
              lineHeight: 1.25,
            }}
          >
            {compactSeg ? (
              <div style={{
                fontSize: 11, fontWeight: 500,
                whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
              }}>
                <span style={{ opacity: 0.75, marginRight: 6 }}>{fmtTime(seg.start)}</span>
                {isFirstWork ? <strong>{customer.name}</strong> : seg.name}
              </div>
            ) : (
              <>
                <div style={{ fontSize: 10.5, fontWeight: 500, opacity: 0.8, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                  {fmtTime(seg.start)}–{fmtTime(seg.end)}
                  {isFirstWork && <span style={{ marginLeft: 6, fontWeight: 600, opacity: 1 }}>{customer.name}</span>}
                </div>
                <div style={{ fontSize: 12, fontWeight: 500, opacity: 0.92, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{seg.name}</div>
              </>
            )}
          </div>
        );
      })}
    </React.Fragment>
  );
};

const TimeColumn = ({ hourHeight, weekNum }) => (
  <div style={{
    width: 64, flexShrink: 0,
    borderRight: '1px solid #EAEAE3',
    background: '#FBFAF6',
    position: 'relative',
  }}>
    <div style={{
      height: 60, padding: '14px 0',
      textAlign: 'center', fontSize: 11, color: '#666',
      borderBottom: '1px solid #EAEAE3',
      background: '#fff',
    }}>
      <div style={{ fontSize: 10, opacity: 0.6 }}>Uge</div>
      <div style={{ fontSize: 13, fontWeight: 600, color: '#1a1a1a' }}>{weekNum}</div>
    </div>
    {Array.from({ length: END_HOUR - START_HOUR + 1 }, (_, i) => START_HOUR + i).map((h, i) => (
      <div key={h} style={{
        position: 'absolute',
        top: 60 + i * hourHeight - 8,
        right: 8,
        fontSize: 11, color: '#888', fontWeight: 500,
      }}>
        {h}:00
      </div>
    ))}
  </div>
);

const StaffColumn = ({ staff, bookings, palette, hourHeight, onSlotClick, onBookingClick, onDragStart, onDragEnd, draggingId, dropPreview, onDragOver, onDrop, onDragLeave }) => {
  const colRef = React.useRef(null);

  const handleClick = (e) => {
    const rect = colRef.current.getBoundingClientRect();
    const y = e.clientY - rect.top;
    const min = START_HOUR * 60 + (y / hourHeight) * 60;
    onSlotClick(staff.id, snapToFive(min));
  };

  const handleDragOver = (e) => {
    e.preventDefault();
    const rect = colRef.current.getBoundingClientRect();
    const y = e.clientY - rect.top;
    const min = START_HOUR * 60 + (y / hourHeight) * 60;
    onDragOver(staff.id, snapToFive(min));
  };

  const handleDrop = (e) => {
    e.preventDefault();
    onDrop(staff.id);
  };

  // Hour grid lines
  const lines = [];
  for (let i = 0; i <= END_HOUR - START_HOUR; i++) {
    lines.push(
      <div key={i} style={{
        position: 'absolute', left: 0, right: 0,
        top: i * hourHeight,
        borderTop: '1px solid #EAEAE3',
      }} />
    );
    // half-hour mark
    if (i < END_HOUR - START_HOUR) {
      lines.push(
        <div key={`h${i}`} style={{
          position: 'absolute', left: 0, right: 0,
          top: i * hourHeight + hourHeight / 2,
          borderTop: '1px dashed #F0EFE9',
        }} />
      );
    }
  }

  // Drop preview
  let preview = null;
  if (dropPreview && dropPreview.staffId === staff.id) {
    const draggedBooking = bookings.find(b => b.id === draggingId) ||
                           window.__allBookings?.find(b => b.id === draggingId);
    if (draggedBooking) {
      const dur = getBookingDuration(draggedBooking);
      const top = ((dropPreview.start - START_HOUR * 60) / 60) * hourHeight;
      const height = (dur / 60) * hourHeight;
      preview = (
        <div style={{
          position: 'absolute',
          top, left: 4, right: 4, height: height - 2,
          background: 'rgba(60, 90, 200, 0.08)',
          border: '2px dashed #6B85C8',
          borderRadius: 6,
          pointerEvents: 'none',
          fontSize: 11, color: '#3D5BA8', fontWeight: 600,
          padding: '6px 10px',
        }}>
          {fmtTime(dropPreview.start)} – {fmtTime(dropPreview.start + dur)}
        </div>
      );
    }
  }

  return (
    <div
      ref={colRef}
      onClick={handleClick}
      onDragOver={handleDragOver}
      onDragLeave={onDragLeave}
      onDrop={handleDrop}
      style={{
        flex: 1, minWidth: 180,
        position: 'relative',
        height: (END_HOUR - START_HOUR) * hourHeight,
        borderRight: '1px solid #EAEAE3',
        background: '#fff',
        cursor: 'pointer',
      }}
    >
      {lines}
      {bookings.map(b => (
        <BookingBlock
          key={b.id}
          booking={b}
          palette={palette}
          hourHeight={hourHeight}
          onClick={onBookingClick}
          onDragStart={onDragStart}
          onDragEnd={onDragEnd}
          isDragging={draggingId === b.id}
          isGhost={draggingId === b.id}
        />
      ))}
      {preview}
    </div>
  );
};

const Calendar = ({ bookings, staff, palette, hourHeight, onSlotClick, onBookingClick, onMoveBooking }) => {
  const [draggingId, setDraggingId] = React.useState(null);
  const [dropPreview, setDropPreview] = React.useState(null);
  const dragInfo = React.useRef(null);

  // Expose for drag preview
  window.__allBookings = bookings;

  const handleDragStart = (e, b) => {
    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData('text/plain', b.id);
    setDraggingId(b.id);
    dragInfo.current = { id: b.id };
  };

  const handleDragEnd = () => {
    setDraggingId(null);
    setDropPreview(null);
    dragInfo.current = null;
  };

  const handleDragOver = (staffId, start) => {
    setDropPreview({ staffId, start: Math.max(START_HOUR*60, Math.min(END_HOUR*60 - 15, start)) });
  };

  const handleDragLeave = () => {
    // We rely on dragend
  };

  const handleDrop = (staffId) => {
    if (!dragInfo.current || !dropPreview) return;
    onMoveBooking(dragInfo.current.id, staffId, dropPreview.start);
    setDraggingId(null);
    setDropPreview(null);
    dragInfo.current = null;
  };

  const weekNum = 23; // Torsdag 6. juni 2024 = uge 23

  return (
    <div style={{
      display: 'flex', flexDirection: 'column',
      height: '100%', overflow: 'hidden',
      background: '#FBFAF6',
    }}>
      {/* Staff headers row */}
      <div style={{
        display: 'flex', flexShrink: 0,
        borderBottom: '1px solid #EAEAE3',
        position: 'sticky', top: 0, zIndex: 2,
      }}>
        <div style={{ width: 64, flexShrink: 0, background: '#fff', borderRight: '1px solid #EAEAE3', height: 60 }} />
        {staff.map(s => (
          <div key={s.id} style={{ flex: 1, minWidth: 180 }}>
            <StaffHeader staff={s} />
          </div>
        ))}
      </div>

      {/* Scrollable time grid */}
      <div style={{ flex: 1, overflow: 'auto', display: 'flex', position: 'relative' }}>
        <div style={{ position: 'relative', width: 64, flexShrink: 0, height: (END_HOUR - START_HOUR) * hourHeight + 60, marginTop: -60 }}>
          <TimeColumn hourHeight={hourHeight} weekNum={weekNum} />
        </div>
        {staff.map(s => (
          <StaffColumn
            key={s.id}
            staff={s}
            bookings={bookings.filter(b => b.staffId === s.id)}
            palette={palette}
            hourHeight={hourHeight}
            onSlotClick={onSlotClick}
            onBookingClick={onBookingClick}
            onDragStart={handleDragStart}
            onDragEnd={handleDragEnd}
            draggingId={draggingId}
            dropPreview={dropPreview}
            onDragOver={handleDragOver}
            onDrop={handleDrop}
            onDragLeave={handleDragLeave}
          />
        ))}
      </div>
    </div>
  );
};

Object.assign(window, {
  Calendar, fmtTime, snapToFive, START_HOUR, END_HOUR, HOUR_HEIGHT, Avatar,
});
