// Unified Calendar — Gantt multi-department itinerary
const CAL_START_HOUR = 0;
const CAL_END_HOUR = 24;
const CELL_W = 64; // px per hour — narrower to fit 24h comfortably

const Calendar = ({ onOpenAppt, dayId, setDayId, laneMode, setLaneMode, apptOverrides, setApptOverrides, disruptions, refreshKey }) => {
  const { DEPARTMENTS, DOCTORS, ROOMS, APPOINTMENTS, PATIENTS, fmt } = window.MOCK;
  const [deptFilter, setDeptFilter] = useState('all');
  const [dragging, setDragging] = useState(null);
  const trackRefs = useRef({});

  const appts = useMemo(() => {
    return APPOINTMENTS
      .filter(a => a.dayId === dayId)
      .map(a => apptOverrides[a.id] ? { ...a, ...apptOverrides[a.id] } : a)
      .filter(a => deptFilter === 'all' || a.dept === deptFilter);
  }, [dayId, deptFilter, apptOverrides, refreshKey]);

  const lanes = useMemo(() => {
    if (laneMode === 'dept') {
      return DEPARTMENTS
        .filter(d => deptFilter === 'all' || d.id === deptFilter)
        .map(d => ({
          id: d.id,
          name: d.name,
          sub: `${APPOINTMENTS.filter(a => a.dayId === dayId && a.dept === d.id).length} appts`,
          color: d.color,
          match: (a) => a.dept === d.id,
        }));
    }
    if (laneMode === 'doctor') {
      return DOCTORS
        .filter(d => deptFilter === 'all' || d.dept === deptFilter)
        .map(d => ({
          id: d.id,
          name: d.name,
          sub: d.title,
          color: DEPARTMENTS.find(x => x.id === d.dept).color,
          match: (a) => a.docId === d.id,
          status: d.status,
        }));
    }
    // room
    return ROOMS
      .filter(r => deptFilter === 'all' || r.dept === deptFilter)
      .map(r => ({
        id: r.id,
        name: r.name,
        sub: r.type,
        color: DEPARTMENTS.find(x => x.id === r.dept).color,
        match: (a) => a.roomId === r.id,
      }));
  }, [laneMode, deptFilter]);

  const totalHours = CAL_END_HOUR - CAL_START_HOUR;
  const trackWidth = totalHours * CELL_W;
  const minToX = (min) => ((min - CAL_START_HOUR * 60) / 60) * CELL_W;

  // Now line (for today only)
  const nowMin = 11 * 60 + 42;
  const showNow = dayId === 'wed';

  const onApptDown = (e, a) => {
    e.stopPropagation();
    const startX = e.clientX;
    const startMin = a.start;
    setDragging({ id: a.id });
    const onMove = (ev) => {
      const dx = ev.clientX - startX;
      const dMin = Math.round((dx / CELL_W) * 60 / 15) * 15;
      const newStart = Math.max(CAL_START_HOUR * 60, Math.min((CAL_END_HOUR - 1) * 60, startMin + dMin));
      setApptOverrides(prev => ({ ...prev, [a.id]: { start: newStart, end: newStart + a.duration, startLabel: fmt(newStart), endLabel: fmt(newStart + a.duration) } }));
    };
    const onUp = () => {
      setDragging(null);
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('mouseup', onUp);
    };
    window.addEventListener('mousemove', onMove);
    window.addEventListener('mouseup', onUp);
  };

  // Chain dependency lines
  const chainLines = useMemo(() => {
    const lines = [];
    const chained = appts.filter(a => a.chain);
    chained.forEach(a => {
      if (a.chain.next) {
        const nxt = appts.find(x => x.id === a.chain.next);
        if (nxt) lines.push({ from: a, to: nxt });
      }
    });
    return lines;
  }, [appts]);

  return (
    <div className="cal-wrap">
      <div className="cal-controls">
        <div className="seg">
          {DAYS.map(d => (
            <button key={d.id} className={dayId === d.id ? 'active' : ''} onClick={() => setDayId(d.id)}>
              {d.label} <span className="muted" style={{ marginLeft: 4, fontSize: 11 }}>{d.date}</span>
            </button>
          ))}
        </div>
        <div className="seg">
          <button className={laneMode === 'dept' ? 'active' : ''} onClick={() => setLaneMode('dept')}>By department</button>
          <button className={laneMode === 'doctor' ? 'active' : ''} onClick={() => setLaneMode('doctor')}>By doctor</button>
          <button className={laneMode === 'room' ? 'active' : ''} onClick={() => setLaneMode('room')}>By room</button>
        </div>
        <select className="select" style={{ width: 160 }} value={deptFilter} onChange={e => setDeptFilter(e.target.value)}>
          <option value="all">All departments</option>
          {DEPARTMENTS.map(d => <option key={d.id} value={d.id}>{d.name}</option>)}
        </select>
        <div style={{ flex: 1 }} />
        <Pill tone="accent"><Icon name="workflow" size={11} /> Chain view on</Pill>
        {disruptions.length > 0 && (
          <Pill tone="warn"><Icon name="warn" size={11} /> {disruptions.length} disruption{disruptions.length > 1 ? 's' : ''}</Pill>
        )}
      </div>

      <div className="cal-scroll">
        <div className="gantt" style={{ minWidth: 240 + trackWidth, '--cell-w': `${CELL_W}px` }}>
          <div className="gantt-head">
            <div className="lane-label">
              {laneMode === 'dept' ? 'Department' : laneMode === 'doctor' ? 'Provider' : 'Room'}
            </div>
            <div className="gantt-timescale" style={{ width: trackWidth }}>
              {Array.from({ length: totalHours + 1 }, (_, i) => {
                const h = CAL_START_HOUR + i;
                const hh = ((h + 11) % 12) + 1;
                const ap = h < 12 ? 'AM' : 'PM';
                return (
                  <div key={i} className="tick" style={{ left: i * CELL_W }}>
                    {hh}:00 {ap}
                  </div>
                );
              })}
            </div>
          </div>

          {lanes.map(lane => {
            const laneAppts = appts.filter(lane.match);
            return (
              <div key={lane.id} className="lane">
                <div className="lane-header">
                  <div className="swatch" style={{ background: lane.color }} />
                  <div style={{ minWidth: 0, flex: 1 }}>
                    <div className="lane-name">{lane.name}</div>
                    <div className="lane-meta">
                      {lane.sub}
                      {lane.status && lane.status !== 'on-time' && (
                        <Pill tone="warn" style={{ marginLeft: 6 }}>⏱ {lane.status}</Pill>
                      )}
                    </div>
                  </div>
                </div>
                <div
                  className="lane-track"
                  style={{ width: trackWidth }}
                  ref={el => trackRefs.current[lane.id] = el}
                >
                  {laneAppts.map(a => {
                    const dept = DEPARTMENTS.find(x => x.id === a.dept);
                    const p = PATIENTS.find(x => x.id === a.patientId);
                    const left = minToX(a.start);
                    const width = (a.duration / 60) * CELL_W - 2;
                    const isConflict = a.id === 'a30' || a.id === 'a31'; // mock conflict pair
                    return (
                      <div
                        key={a.id}
                        className={`appt ${a.status} ${dragging?.id === a.id ? 'dragging' : ''} ${isConflict ? 'conflict' : ''}`}
                        style={{
                          left, width,
                          background: dept.color,
                        }}
                        onMouseDown={(e) => onApptDown(e, a)}
                        onClick={(e) => { e.stopPropagation(); if (!dragging) onOpenAppt(a); }}
                        title={`${p.name} — ${a.typeLabel} · ${a.startLabel}`}
                      >
                        <div className="t">{a.startLabel} · {a.typeLabel}</div>
                        <div className="p">{p.name}{a.chain && ` · step ${a.chain.step}/${a.chain.of}`}</div>
                      </div>
                    );
                  })}
                </div>
              </div>
            );
          })}

          {/* Single unified NOW line across all lanes */}
          {showNow && (
            <div className="now-line" style={{ position: 'absolute', left: 240 + minToX(nowMin), top: 40, bottom: 0, zIndex: 5 }}>
              <div className="now-pill"><span className="now-dot" /> NOW</div>
            </div>
          )}

          {/* Chain dependency overlay */}
          <svg style={{ position: 'absolute', top: 40, left: 240, pointerEvents: 'none', width: trackWidth, height: '100%' }}>
            {chainLines.map((l, i) => {
              const fromLaneIdx = lanes.findIndex(ln => ln.match(l.from));
              const toLaneIdx = lanes.findIndex(ln => ln.match(l.to));
              if (fromLaneIdx < 0 || toLaneIdx < 0) return null;
              const y1 = fromLaneIdx * 52 + 26;
              const y2 = toLaneIdx * 52 + 26;
              const x1 = minToX(l.from.end);
              const x2 = minToX(l.to.start);
              const midX = (x1 + x2) / 2;
              return (
                <g key={i}>
                  <path
                    d={`M${x1},${y1} C${midX},${y1} ${midX},${y2} ${x2},${y2}`}
                    fill="none"
                    stroke="var(--accent)"
                    strokeWidth="1.5"
                    strokeDasharray="4 3"
                    opacity="0.7"
                  />
                  <circle cx={x2} cy={y2} r="3" fill="var(--accent)" />
                </g>
              );
            })}
          </svg>
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { Calendar });
