"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.CaseTimeline = void 0;

var _preact = require("preact");

var _classnames = _interopRequireDefault(require("classnames"));

var _date = require("./utils/date");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

const labels = {
  caseStart: 'Started Monitoring',
  vitalsEnd: 'Stopped Monitoring Vitals',
  ivStart: 'IV Started',
  ivEnd: 'IV Removed',
  surgeryStart: 'Procedure Start',
  surgeryEnd: 'Procedure End',
  anesthesiaStart: 'Anes. Start',
  anesthesiaEnd: 'Anes. End',
  recoveryStart: 'Recovery Start',
  end: 'Recovery Completed'
};

const toPx = num => num + 'px';

const toPercent = num => num * 100 + '%';

const toMinutes = milliseconds => Math.floor(milliseconds / 60000);
/**
 * @typedef {{
 *   caseStart?: number
 *   vitalsEnd?: number
 *   ivStart?: number
 *   ivEnd?: number
 *   surgeryStart?: number
 *   surgeryEnd?: number
 *   anesthesiaStart?: number
 *   anesthesiaEnd?: number
 *   recoveryStart?: number
 *   end?: number
 * }} CaseDataEvents
 */


const bars = [{
  start: 'caseStart',
  end: 'vitalsEnd',
  name: 'Monitoring',
  color: 'washed-yellow'
}, {
  start: 'ivStart',
  end: 'ivEnd',
  name: 'IV',
  color: 'washed-blue'
}, {
  start: 'surgeryStart',
  end: 'surgeryEnd',
  name: 'Procedure',
  color: 'washed-red'
}, {
  start: 'anesthesiaStart',
  end: 'anesthesiaEnd',
  name: 'Anesthesia',
  color: 'light-green'
}, {
  start: 'recoveryStart',
  end: 'end',
  name: 'Recovery',
  color: 'near-white'
}];
/**
 * @param {{ events: CaseDataEvents; relativeMax?: number }} opts
 * @returns {JSX.Element}
 */

const CaseTimeline = (_ref) => {
  let {
    events,
    relativeMax,
    timeLabels
  } = _ref,
      rest = _objectWithoutProperties(_ref, ["events", "relativeMax", "timeLabels"]);

  const now = Date.now();
  let min = Infinity;
  let max = 0;
  const newArray = bars.map(({
    start,
    end,
    name,
    color
  }) => {
    const startTime = typeof events[start] === 'number' ? events[start] : null;
    const endTime = typeof events[end] === 'number' ? events[end] : null;
    const hasStartTime = startTime !== null;
    const hasEndTime = endTime !== null;
    let status;
    let showBar = true;
    let duration = null;
    let description = '';

    if (hasStartTime) {
      min = Math.min(min, startTime);
    }

    if (hasEndTime) {
      max = Math.max(max, endTime);
    }

    if (hasEndTime && !hasStartTime) {
      status = 'noStart';
      showBar = false;
      description = "(missing start)";
    } else if (!hasEndTime && !hasStartTime) {
      status = 'noData';
      showBar = false;
      description = '(no data)';
    } else if (hasStartTime && !hasEndTime) {
      status = 'noEnd';
      description = '(no end time)';
    } else {
      duration = endTime - startTime;

      if (duration <= 0) {
        status = 'startBeforeEnd';
        showBar = false;
      } else {
        status = 'ok';
        description = "".concat(toMinutes(duration), "m");
      }
    }

    return {
      name,
      status,
      showBar,
      duration,
      color,
      description,
      hasStartTime,
      hasEndTime,
      start: startTime,
      end: endTime
    };
  });
  const hasMin = min !== Infinity;
  const hasMax = max > 0;
  const duration = hasMax && hasMin ? max - min : null;
  const durToCompare = relativeMax || duration || now;
  newArray.forEach(entry => {
    if (entry.status === 'ok') {
      entry.left = (entry.start - min) / durToCompare;
      entry.width = entry.duration / durToCompare;
    }

    if (entry.status === 'noEnd') {
      const left = (entry.start - min) / durToCompare;
      entry.left = left;
      entry.width = 1 - left;
    }
  });
  const asArray = [];

  for (const name in events) {
    asArray.push({
      name,
      time: events[name],
      label: labels[name]
    });
  }

  const periodHeight = 28;
  return (0, _preact.h)("div", rest, (0, _preact.h)("div", {
    className: "f6"
  }, timeLabels && (0, _preact.h)("div", {
    style: {
      marginLeft: '5rem'
    },
    className: "flex items-center justify-between"
  }, (0, _preact.h)("div", {
    class: "bl b--light-gray pa1"
  }, min !== Infinity ? (0, _date.toTimeString)(min) : '(no start time)'), (0, _preact.h)("div", {
    class: "br b--light-gray pa1"
  }, max > 0 ? (0, _date.toTimeString)(max) : '(no end time)')), (0, _preact.h)("div", {
    className: "flex"
  }, (0, _preact.h)("div", {
    className: "flex-shrink-0",
    style: {
      width: '5rem'
    }
  }, newArray.map(item => (0, _preact.h)("div", {
    className: (0, _classnames.default)('flex items-center'),
    style: {
      height: toPx(periodHeight)
    },
    key: item.name
  }, item.name, ":"))), (0, _preact.h)("div", {
    className: "relative ba bg-white b--light-gray br1 w-100 border-box"
  }, newArray.map(item => {
    const width = toPercent(item.width);
    const left = toPercent(item.left);
    const height = toPx(periodHeight);
    return (0, _preact.h)("div", {
      className: (0, _classnames.default)('h-100 relative'),
      style: {
        height
      },
      key: item.name
    }, (0, _preact.h)("div", {
      className: (0, _classnames.default)("w-100 tc black-40 bg-".concat(item.color, " ba b--light-gray transition"), !item.showBar && 'hidden'),
      style: {
        transform: "translateX(".concat(left, ") scaleX(").concat(width, ")"),
        transformOrigin: 'top left',
        height
      }
    }), (0, _preact.h)("div", {
      className: (0, _classnames.default)('absolute top-0 flex items-center ph2 black-50', item.width < 0.2 && 'dn'),
      style: {
        height,
        width,
        left
      }
    }, (0, _preact.h)("span", {
      className: (0, _classnames.default)('truncate', item.status !== 'ok' && 'red')
    }, item.showBar ? item.name : null, item.description ? " ".concat(item.description) : null)));
  })))));
};

exports.CaseTimeline = CaseTimeline;