// Редактируемый таймлайн: активный КА (drag/resize включений), дорожки видимости
// (цели/станции), контекст других КА (read-only). Конфликты подсвечиваются.
const { useRef: useRefET, useState: useStateET, useEffect: useEffectET, useMemo: useMemoET } = React;

const ET_LABEL_W = 168;
const ET_AXIS_H = 40;
const ET_ACTIVE_H = 66;
const ET_VIS_H = 22;
const ET_OTHER_H = 30;
const SNAP_MS = 60 * 1000; // минута

function kindColor(kind, scType) {
  if (kind === "shoot") return TYPE_COLOR[scType];
  if (kind === "downlink") return "var(--accent)";
  if (kind === "calib") return "oklch(0.78 0.02 200)";
  return "var(--ink-3)";
}
function kindLabel(kind) {
  return kind === "shoot" ? "Съёмка" : kind === "downlink" ? "Сброс" : kind === "calib" ? "Калибровка" : "Служебная";
}

function EditorTimeline(props) {
  const { activeSc, draft, selectedWorkId, onSelectWork, t0, t1, now,
    onChangeWork, otherLanes, visTracks, conflicts } = props;

  const wrapRef = useRefET(null);
  const [w, setW] = useStateET(900);
  const drag = useRefET(null);

  useEffectET(() => {
    const el = wrapRef.current; if (!el) return;
    const ro = new ResizeObserver(() => setW(el.clientWidth - ET_LABEL_W));
    ro.observe(el); setW(el.clientWidth - ET_LABEL_W);
    return () => ro.disconnect();
  }, []);

  const span = t1 - t0;
  const pxPerMs = w / span;
  const X = (t) => (t - t0) * pxPerMs;
  const T = (x) => t0 + x / pxPerMs;

  // Засечки времени.
  const ticks = useMemoET(() => niceTicks(t0, t1, pxPerMs, 72), [t0, t1, pxPerMs]);
  const days = useMemoET(() => {
    const out = []; const d0 = new Date(t0);
    let t = Date.UTC(d0.getUTCFullYear(), d0.getUTCMonth(), d0.getUTCDate());
    while (t <= t1) { out.push(t); t += 86400000; }
    return out;
  }, [t0, t1]);

  // ---- drag / resize ----
  const startDrag = (e, work, mode) => {
    e.stopPropagation(); e.preventDefault();
    drag.current = { id: work.id, mode, startX: e.clientX, t0: work.start, t1: work.end };
    onSelectWork(work.id);
    window.addEventListener("mousemove", onMove);
    window.addEventListener("mouseup", onUp);
  };
  const onMove = (e) => {
    const d = drag.current; if (!d) return;
    const dt = Math.round(((e.clientX - d.startX) / pxPerMs) / SNAP_MS) * SNAP_MS;
    let ns = d.t0, ne = d.t1;
    if (d.mode === "move") { ns = d.t0 + dt; ne = d.t1 + dt; }
    else if (d.mode === "l") { ns = Math.min(d.t1 - SNAP_MS, d.t0 + dt); }
    else if (d.mode === "r") { ne = Math.max(d.t0 + SNAP_MS, d.t1 + dt); }
    onChangeWork(d.id, { start: ns, end: ne });
  };
  const onUp = () => {
    drag.current = null;
    window.removeEventListener("mousemove", onMove);
    window.removeEventListener("mouseup", onUp);
  };

  const totalOtherH = otherLanes.reduce((a) => a + ET_OTHER_H, 0);
  const visH = visTracks.length * ET_VIS_H;

  const lane = (top, h, children, label, sub, bg, key) => (
    <React.Fragment key={key}>
      <div style={{ position: "absolute", left: 0, top, width: ET_LABEL_W, height: h, borderBottom: "1px solid var(--line-soft)", borderRight: "1px solid var(--line)", background: bg || "var(--bg-1)", display: "flex", flexDirection: "column", justifyContent: "center", padding: "0 10px", gap: 1 }}>
        {label}
        {sub}
      </div>
      <div style={{ position: "absolute", left: ET_LABEL_W, top, width: w, height: h, borderBottom: "1px solid var(--line-soft)" }}>
        {children}
      </div>
    </React.Fragment>
  );

  let yCursor = ET_AXIS_H;
  const activeTop = yCursor; yCursor += ET_ACTIVE_H;
  const visTop = yCursor; yCursor += visH;
  const dividerTop = yCursor; yCursor += otherLanes.length ? 22 : 0;
  const othersTop = yCursor;
  const totalH = ET_AXIS_H + ET_ACTIVE_H + visH + (otherLanes.length ? 22 : 0) + totalOtherH + 8;

  return (
    <div ref={wrapRef} style={{ position: "relative", width: "100%", height: "100%", overflow: "auto", background: "var(--bg-0)" }}>
      <div style={{ position: "relative", width: ET_LABEL_W + w, height: Math.max(totalH, 200) }}>
        {/* фон-сетка по дням/часам */}
        <div style={{ position: "absolute", left: ET_LABEL_W, top: ET_AXIS_H, width: w, bottom: 0 }}>
          {ticks.ticks.map((tk, i) => (
            <div key={i} style={{ position: "absolute", left: X(tk.t), top: 0, bottom: 0, borderLeft: "1px solid var(--grid)" }} />
          ))}
        </div>

        {/* ОСЬ */}
        <div style={{ position: "absolute", left: 0, top: 0, width: ET_LABEL_W, height: ET_AXIS_H, background: "var(--bg-1)", borderRight: "1px solid var(--line)", borderBottom: "1px solid var(--line)", display: "flex", alignItems: "flex-end", padding: "0 10px 6px" }}>
          <span className="mono" style={{ fontSize: 9, color: "var(--ink-3)", letterSpacing: ".08em" }}>ВРЕМЯ (UTC)</span>
        </div>
        <div style={{ position: "absolute", left: ET_LABEL_W, top: 0, width: w, height: ET_AXIS_H, background: "var(--bg-1)", borderBottom: "1px solid var(--line)" }}>
          {days.map((d, i) => (
            <div key={"d" + i} style={{ position: "absolute", left: X(d), top: 2, borderLeft: "1px solid var(--line)", paddingLeft: 5, height: 14, display: "flex", alignItems: "center", gap: 4 }}>
              <span style={{ fontSize: 10, fontWeight: 600, color: "var(--ink-1)" }}>{pad(new Date(d).getUTCDate())}</span>
              <span style={{ fontSize: 9, color: "var(--ink-3)" }}>{MONTHS[new Date(d).getUTCMonth()]}</span>
            </div>
          ))}
          {ticks.ticks.map((tk, i) => (
            <div key={i} style={{ position: "absolute", left: X(tk.t), top: 18, height: 20, borderLeft: "1px solid var(--grid)", paddingLeft: 3, display: "flex", alignItems: "center" }}>
              <span className="mono" style={{ fontSize: 8.5, color: "var(--ink-3)" }}>{fmtTime(tk.t)}</span>
            </div>
          ))}
        </div>

        {/* линия СЕЙЧАС */}
        {now >= t0 && now <= t1 && (
          <div style={{ position: "absolute", left: ET_LABEL_W + X(now), top: ET_AXIS_H, height: totalH - ET_AXIS_H, width: 0, borderLeft: "1.5px dashed var(--now)", zIndex: 8, pointerEvents: "none" }}>
            <span className="mono" style={{ position: "absolute", top: -1, left: 3, fontSize: 8, fontWeight: 600, color: "var(--bg-0)", background: "var(--now)", padding: "0 4px", borderRadius: 3, whiteSpace: "nowrap" }}>СЕЙЧАС</span>
          </div>
        )}

        {/* АКТИВНЫЙ КА */}
        {lane(activeTop, ET_ACTIVE_H,
          <React.Fragment>
            {draft.map((wk) => {
              const left = X(wk.start), bw = Math.max(6, X(wk.end) - X(wk.start));
              const col = kindColor(wk.kind, activeSc.type);
              const sel = wk.id === selectedWorkId;
              const confl = conflicts[wk.id];
              return (
                <div key={wk.id} onMouseDown={(e) => startDrag(e, wk, "move")} onClick={(e) => { e.stopPropagation(); onSelectWork(wk.id); }}
                  title={`${kindLabel(wk.kind)} · ${fmtDateTime(wk.start)}–${fmtTime(wk.end)}`}
                  style={{
                    position: "absolute", left, width: bw, top: 12, height: ET_ACTIVE_H - 24,
                    background: `color-mix(in oklch, ${col} 24%, var(--bg-1))`,
                    border: `1px solid ${confl ? "var(--now)" : `color-mix(in oklch, ${col} 55%, var(--bg-1))`}`,
                    borderLeft: `3px solid ${col}`, borderRadius: 5, cursor: "grab", zIndex: sel ? 6 : 4,
                    outline: sel ? "1.5px solid var(--accent)" : "none",
                    boxShadow: sel ? "0 0 0 3px oklch(0.82 0.13 200 / 0.18)" : "none",
                    overflow: "hidden", userSelect: "none",
                  }}>
                  {confl && <div className="hatch" style={{ position: "absolute", inset: 0, opacity: 0.5, pointerEvents: "none" }} />}
                  {/* ручки resize */}
                  <div onMouseDown={(e) => startDrag(e, wk, "l")} style={{ position: "absolute", left: 0, top: 0, bottom: 0, width: 7, cursor: "ew-resize", zIndex: 7 }} />
                  <div onMouseDown={(e) => startDrag(e, wk, "r")} style={{ position: "absolute", right: 0, top: 0, bottom: 0, width: 7, cursor: "ew-resize", zIndex: 7 }} />
                  <div style={{ padding: "3px 8px", pointerEvents: "none" }}>
                    <div style={{ display: "flex", alignItems: "center", gap: 4 }}>
                      <span style={{ width: 6, height: 6, borderRadius: 2, background: col, flex: "none" }} />
                      {bw > 56 && <span className="mono" style={{ fontSize: 9.5, color: "var(--ink)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{wk.label}</span>}
                      {wk.isNew && <span className="mono" style={{ fontSize: 7.5, color: "var(--now)", border: "1px solid var(--now)", borderRadius: 3, padding: "0 2px", flex: "none" }}>NEW</span>}
                    </div>
                    {bw > 70 && <div className="mono tnum" style={{ fontSize: 8.5, color: "var(--ink-3)", marginTop: 2 }}>{fmtTime(wk.start)}–{fmtTime(wk.end)}</div>}
                  </div>
                </div>
              );
            })}
          </React.Fragment>,
          <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
            <TypeDot type={activeSc.type} size={8} />
            <span className="mono" style={{ fontSize: 11.5, fontWeight: 600, color: "var(--ink)" }}>{activeSc.short}</span>
          </div>,
          <span style={{ fontSize: 9, color: "var(--accent)" }}>редактируется</span>,
          "var(--bg-2)", "active"
        )}

        {/* ДОРОЖКИ ВИДИМОСТИ */}
        {visTracks.map((vt, idx) => lane(visTop + idx * ET_VIS_H, ET_VIS_H,
          <React.Fragment>
            {vt.windows.map((win, i) => {
              const left = X(win.start), bw = Math.max(2, X(win.end) - X(win.start));
              if (win.end < t0 || win.start > t1) return null;
              return (
                <div key={i} title={`Видимость ${vt.label}: ${fmtTime(win.start)}–${fmtTime(win.end)}`}
                  style={{ position: "absolute", left, width: bw, top: 4, height: ET_VIS_H - 8, borderRadius: 3,
                    background: `color-mix(in oklch, ${vt.color} 28%, transparent)`, border: `1px solid ${vt.color}` }} />
              );
            })}
          </React.Fragment>,
          <span style={{ fontSize: 10, color: "var(--ink-2)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", display: "flex", alignItems: "center", gap: 5 }}>
            <span style={{ width: 8, height: 8, borderRadius: 2, background: vt.color, flex: "none" }} />{vt.label}
          </span>,
          <span style={{ fontSize: 8, color: "var(--ink-3)" }}>{vt.kind === "target" ? "цель · видимость" : "станция · видимость"}</span>,
          "var(--bg-1)", "vis-" + vt.id
        ))}

        {/* разделитель */}
        {otherLanes.length > 0 && (
          <div style={{ position: "absolute", left: 0, top: dividerTop, width: ET_LABEL_W + w, height: 22, background: "var(--bg-0)", borderBottom: "1px solid var(--line)", borderTop: "1px solid var(--line)", display: "flex", alignItems: "center", padding: "0 10px" }}>
            <span className="mono" style={{ fontSize: 8.5, color: "var(--ink-3)", letterSpacing: ".1em" }}>ДРУГИЕ КА · КОНТЕКСТ (read-only)</span>
          </div>
        )}

        {/* ДРУГИЕ КА */}
        {otherLanes.map((ln, idx) => lane(othersTop + idx * ET_OTHER_H, ET_OTHER_H,
          <React.Fragment>
            {ln.works.map((wk) => {
              const left = X(wk.start), bw = Math.max(3, X(wk.end) - X(wk.start));
              if (wk.end < t0 || wk.start > t1) return null;
              const col = kindColor(wk.kind, ln.sc.type);
              return (
                <div key={wk.id} title={`${ln.sc.short} · ${kindLabel(wk.kind)} · ${fmtTime(wk.start)}–${fmtTime(wk.end)}`}
                  style={{ position: "absolute", left, width: bw, top: 7, height: ET_OTHER_H - 14, borderRadius: 3,
                    background: `color-mix(in oklch, ${col} 16%, var(--bg-1))`, borderLeft: `2px solid ${col}`, opacity: 0.62 }} />
              );
            })}
          </React.Fragment>,
          <span className="mono" style={{ fontSize: 10.5, color: "var(--ink-2)", display: "flex", alignItems: "center", gap: 5 }}>
            <TypeDot type={ln.sc.type} size={6} />{ln.sc.short}
          </span>,
          null, "var(--bg-1)", "other-" + ln.sc.id
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { EditorTimeline, kindColor, kindLabel });
