import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import React, { Fragment } from 'react';
import { connect } from '../../../redux/store';
import { compose, withProps } from 'recompose';
import { VictoryContainer, VictoryPie, VictoryChart, VictoryBar, VictoryGroup, VictoryTooltip, VictoryAxis } from 'victory';
import { Constants, Table, StateListWrapper } from '@kineticdata/bundle-common';
import { I18n } from '@kineticdata/react';
import moment from 'moment';
import { Record } from 'immutable';

var toInt = function toInt(value) {
  return parseInt(value, 10) || 0;
};

var toPercent = function toPercent(a, b) {
  return b !== 0 ? "".concat(Math.round(a / b * 100), "%") : '';
};

var Appointments = function Appointments(_ref) {
  var appointments = _ref.appointments;
  return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", {
    className: "section__title"
  }, /*#__PURE__*/React.createElement(I18n, null, "Appointments")), appointments.total > 0 ? /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(I18n, {
    render: function render(translate) {
      return /*#__PURE__*/React.createElement("div", {
        className: "text-center"
      }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
        className: "fa fa-square fa-fw",
        style: {
          color: Constants.COLORS.blueSky
        }
      }), "".concat(toPercent(appointments.scheduled, appointments.total), " ").concat(translate('Scheduled'), " (").concat(appointments.scheduled, ")")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
        className: "fa fa-square fa-fw",
        style: {
          color: Constants.COLORS.sunflower
        }
      }), "".concat(toPercent(appointments.walkins, appointments.total), " ").concat(translate('Walk-Ins'), " (").concat(appointments.walkins, ")")));
    }
  }), /*#__PURE__*/React.createElement(VictoryContainer, {
    className: "VictoryContainer max-height-250",
    height: 250,
    width: 250,
    style: {
      height: 'auto'
    }
  }, ' ', /*#__PURE__*/React.createElement(VictoryPie, {
    standalone: false,
    colorScale: [Constants.COLORS.blueSky, Constants.COLORS.sunflower],
    height: 250,
    width: 250,
    radius: 100,
    innerRadius: 62,
    labels: function labels() {
      return null;
    },
    data: [{
      y: appointments.scheduled
    }, {
      y: appointments.walkins
    }]
  }), /*#__PURE__*/React.createElement(VictoryPie, {
    standalone: false,
    colorScale: [Constants.COLORS.blueLake, 'whitesmoke', 'transparent'],
    height: 250,
    width: 250,
    radius: 55,
    innerRadius: 42,
    labels: function labels() {
      return null;
    },
    data: [{
      y: appointments.sameDay
    }, {
      y: appointments.scheduled - appointments.sameDay
    }, {
      y: appointments.walkins
    }]
  })), /*#__PURE__*/React.createElement("div", {
    className: "text-center"
  }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
    className: "fa fa-square fa-fw",
    style: {
      color: Constants.COLORS.blueLake
    }
  }), /*#__PURE__*/React.createElement(I18n, null, "Same Day Appointments"), " ", "(".concat(appointments.sameDay, ")")))) : /*#__PURE__*/React.createElement("div", {
    className: "text-center"
  }, /*#__PURE__*/React.createElement("em", null, /*#__PURE__*/React.createElement(I18n, null, "No Appointments"))));
};

var Feedback = function Feedback(_ref2) {
  var feedback = _ref2.feedback;
  return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", {
    className: "section__title"
  }, /*#__PURE__*/React.createElement(I18n, null, "Feedback")), feedback.total > 0 ? /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(I18n, {
    render: function render(translate) {
      return /*#__PURE__*/React.createElement("div", {
        className: "text-center"
      }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
        className: "fa fa-square fa-fw",
        style: {
          color: Constants.COLORS.green
        }
      }), "".concat(toPercent(feedback.positive, feedback.total), " ").concat(translate('Happy'), " (").concat(feedback.positive, ")")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
        className: "fa fa-square fa-fw",
        style: {
          color: Constants.COLORS.red
        }
      }), "".concat(toPercent(feedback.negative, feedback.total), " ").concat(translate('Unhappy'), " (").concat(feedback.negative, ")")));
    }
  }), /*#__PURE__*/React.createElement(VictoryPie, {
    containerComponent: /*#__PURE__*/React.createElement(VictoryContainer, {
      className: "VictoryContainer max-height-250",
      height: 250,
      width: 250,
      style: {
        height: 'auto'
      }
    }),
    colorScale: [Constants.COLORS.green, Constants.COLORS.red],
    height: 250,
    width: 250,
    radius: 100,
    innerRadius: 62,
    labels: function labels() {
      return null;
    },
    data: [{
      y: feedback.positive
    }, {
      y: feedback.negative
    }]
  })) : /*#__PURE__*/React.createElement("div", {
    className: "text-center"
  }, /*#__PURE__*/React.createElement("em", null, /*#__PURE__*/React.createElement(I18n, null, "No Feedback"))));
};

var Utilization = function Utilization(_ref3) {
  var utilization = _ref3.utilization;
  return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", {
    className: "section__title"
  }, /*#__PURE__*/React.createElement(I18n, null, "Utilization")), utilization.available > 0 ? /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", {
    className: "text-center"
  }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
    className: "fa fa-square fa-fw",
    style: {
      color: Constants.COLORS.blueSky
    }
  }), toPercent(utilization.scheduled, utilization.available), ' ', /*#__PURE__*/React.createElement(I18n, null, "Scheduled")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
    className: "fa fa-square fa-fw",
    style: {
      color: Constants.COLORS.greenGrass
    }
  }), toPercent(utilization.actual, utilization.available), ' ', /*#__PURE__*/React.createElement(I18n, null, "Actual"))), /*#__PURE__*/React.createElement(VictoryContainer, {
    className: "VictoryContainer max-height-250",
    height: 250,
    width: 250,
    style: {
      height: 'auto'
    }
  }, "}", /*#__PURE__*/React.createElement(VictoryPie, {
    standalone: false,
    colorScale: [Constants.COLORS.greenGrass, 'whitesmoke'],
    height: 250,
    width: 250,
    radius: 100,
    innerRadius: 62,
    labels: function labels() {
      return null;
    },
    data: [{
      y: utilization.actual
    }, {
      y: utilization.available - utilization.actual
    }]
  }), /*#__PURE__*/React.createElement(VictoryPie, {
    standalone: false,
    colorScale: [Constants.COLORS.blueSky, 'whitesmoke'],
    height: 250,
    width: 250,
    radius: 55,
    innerRadius: 17,
    labels: function labels() {
      return null;
    },
    data: [{
      y: utilization.scheduled
    }, {
      y: utilization.available - utilization.scheduled
    }]
  }))) : /*#__PURE__*/React.createElement("div", {
    className: "text-center"
  }, /*#__PURE__*/React.createElement("em", null, /*#__PURE__*/React.createElement(I18n, null, "No Availability"))));
};

var TimeOfVisit = function TimeOfVisit(_ref4) {
  var timeOfVisit = _ref4.timeOfVisit;
  var scheduledData = Object.keys(timeOfVisit.scheduled).reduce(function (d, hour) {
    d[toInt(hour)] = timeOfVisit.scheduled[hour];
    return d;
  }, Array(24).fill(0));
  var walkinsData = Object.keys(timeOfVisit.walkins).reduce(function (d, hour) {
    d[toInt(hour)] = timeOfVisit.walkins[hour];
    return d;
  }, Array(24).fill(0));
  return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", {
    className: "section__title"
  }, /*#__PURE__*/React.createElement(I18n, null, "Time of Visit")), Object.keys(timeOfVisit.scheduled).length > 0 || Object.keys(timeOfVisit.walkins).length > 0 ? /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(I18n, {
    render: function render(translate) {
      return /*#__PURE__*/React.createElement(VictoryChart, {
        containerComponent: /*#__PURE__*/React.createElement(VictoryContainer, {
          className: "VictoryContainer max-height-350",
          style: {
            height: 'auto'
          },
          zoomDimension: "x"
        }),
        width: 900,
        height: 350,
        domainPadding: 14
      }, /*#__PURE__*/React.createElement(VictoryGroup, {
        colorScale: [Constants.COLORS.blueSky, Constants.COLORS.sunflower],
        offset: 14,
        labelComponent: /*#__PURE__*/React.createElement(VictoryTooltip, null)
      }, /*#__PURE__*/React.createElement(VictoryBar, {
        barWidth: 14,
        data: scheduledData.map(function (count, index) {
          return {
            x: moment(index, 'H').format('LT'),
            y: count,
            label: function label(d) {
              return "".concat(d.x, ": ").concat(d.y, " ").concat(translate('Scheduled'));
            }
          };
        })
      }), /*#__PURE__*/React.createElement(VictoryBar, {
        barWidth: 14,
        data: walkinsData.map(function (count, index) {
          return {
            x: moment(index, 'H').format('LT'),
            y: count,
            label: function label(d) {
              return "".concat(d.x, ": ").concat(d.y, " ").concat(d.y !== 1 ? translate('Walk-Ins') : translate('Walk-In'));
            }
          };
        })
      })), /*#__PURE__*/React.createElement(VictoryAxis, {
        style: {
          tickLabels: {
            angle: 45,
            verticalAnchor: 'middle',
            textAnchor: 'start',
            padding: 5,
            fontSize: 14
          }
        }
      }), /*#__PURE__*/React.createElement(VictoryAxis, {
        dependentAxis: true,
        style: {
          tickLabels: {
            padding: 5,
            fontSize: 14
          },
          ticks: {
            stroke: Constants.COLORS.black,
            size: 5
          }
        }
      }));
    }
  }), /*#__PURE__*/React.createElement("div", {
    className: "text-center"
  }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
    className: "fa fa-square fa-fw",
    style: {
      color: Constants.COLORS.blueSky
    }
  }), /*#__PURE__*/React.createElement(I18n, null, "Scheduled")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
    className: "fa fa-square fa-fw",
    style: {
      color: Constants.COLORS.sunflower
    }
  }), /*#__PURE__*/React.createElement(I18n, null, "Walk-Ins")))) : /*#__PURE__*/React.createElement("div", {
    className: "text-center"
  }, /*#__PURE__*/React.createElement("em", null, /*#__PURE__*/React.createElement(I18n, null, "No Visits"))));
};

var Duration = function Duration(_ref5) {
  var durations = _ref5.durations,
      techBars = _ref5.techBars;
  return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", {
    className: "section__title"
  }, /*#__PURE__*/React.createElement(I18n, null, "Average Durations")), durations.length > 0 ? /*#__PURE__*/React.createElement(I18n, {
    render: function render(translate) {
      return /*#__PURE__*/React.createElement(Table, {
        "class": "table-settings",
        data: durations.map(function (d) {
          var techBar = techBars.find(function (t) {
            return t.values['Id'] === d.schedulerId;
          });
          var schedulerName = techBar ? techBar.values['Name'] : d.schedulerId;
          var actualAverage = d.quantity > 0 ? Math.round(d.actual / d.quantity) : null;
          return _objectSpread(_objectSpread({}, d), {}, {
            actualAverage: actualAverage,
            variance: d.quantity > 0 ? (actualAverage - d.duration) / d.duration : null,
            waitTimeAverage: d.quantity > 0 ? Math.round(d.waitTime / d.quantity) : null,
            schedulerName: schedulerName,
            sortValue: "".concat(schedulerName, " ").concat(d.type)
          });
        }),
        columns: [{
          title: 'Event Type',
          value: 'sortValue',
          renderBodyCell: function renderBodyCell(_ref6) {
            var value = _ref6.value,
                row = _ref6.row;
            return /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("div", null, translate(row.type)), /*#__PURE__*/React.createElement("small", {
              className: "text-muted"
            }, translate(row.schedulerName)));
          }
        }, {
          title: 'Scheduled',
          value: 'duration',
          renderBodyCell: function renderBodyCell(_ref7) {
            var value = _ref7.value;
            return /*#__PURE__*/React.createElement("td", null, "".concat(value, " ").concat(translate('min')));
          }
        }, {
          title: 'Actual',
          value: 'actualAverage',
          renderBodyCell: function renderBodyCell(_ref8) {
            var value = _ref8.value;
            return /*#__PURE__*/React.createElement("td", null, value !== null ? "".concat(value, " ").concat(translate('min')) : '');
          }
        }, {
          title: 'Variance',
          value: 'variance',
          renderBodyCell: function renderBodyCell(_ref9) {
            var value = _ref9.value,
                row = _ref9.row;
            return /*#__PURE__*/React.createElement("td", null, value !== null ? toPercent(value, 1) : '');
          }
        }, {
          title: 'Wait Time',
          value: 'waitTimeAverage',
          renderBodyCell: function renderBodyCell(_ref10) {
            var value = _ref10.value;
            return /*#__PURE__*/React.createElement("td", null, value !== null ? "".concat(value, " ").concat(translate('min')) : '');
          }
        }, {
          title: 'Qty',
          value: 'quantity',
          width: '1%'
        }],
        filtering: false,
        pagination: false,
        render: function render(_ref11) {
          var table = _ref11.table;
          return /*#__PURE__*/React.createElement("div", {
            className: "table-wrapper"
          }, table);
        }
      });
    }
  }) : /*#__PURE__*/React.createElement("div", {
    className: "text-center"
  }, /*#__PURE__*/React.createElement("em", null, /*#__PURE__*/React.createElement(I18n, null, "No Event Types"))));
};

export var MetricsSummaryComponent = function MetricsSummaryComponent(_ref12) {
  var error = _ref12.error,
      metrics = _ref12.metrics,
      data = _objectWithoutProperties(_ref12, ["error", "metrics"]);

  return /*#__PURE__*/React.createElement(StateListWrapper, {
    data: data,
    loading: !metrics,
    error: error
  }, function (_ref13) {
    var summary = _ref13.summary,
        techBars = _ref13.techBars;
    return /*#__PURE__*/React.createElement("div", {
      className: "row"
    }, /*#__PURE__*/React.createElement("div", {
      className: "col-md-4 mb-5"
    }, /*#__PURE__*/React.createElement(Appointments, {
      appointments: summary.appointments
    })), /*#__PURE__*/React.createElement("div", {
      className: "col-md-4 mb-5"
    }, /*#__PURE__*/React.createElement(Feedback, {
      feedback: summary.feedback
    })), /*#__PURE__*/React.createElement("div", {
      className: "col-md-4 mb-5"
    }, /*#__PURE__*/React.createElement(Utilization, {
      utilization: summary.utilization
    })), /*#__PURE__*/React.createElement("div", {
      className: "col-xl-6 mb-5"
    }, /*#__PURE__*/React.createElement(TimeOfVisit, {
      timeOfVisit: summary.timeOfVisit
    })), /*#__PURE__*/React.createElement("div", {
      className: "col-xl-6 mb-5"
    }, /*#__PURE__*/React.createElement(Duration, {
      durations: summary.durations,
      techBars: techBars
    })));
  });
};
export var mapStateToProps = function mapStateToProps(state, props) {
  return {
    error: state.metrics.error,
    metrics: state.metrics.data
  };
};
var Summary = Record({
  appointments: {
    walkins: 0,
    scheduled: 0,
    sameDay: 0
  },
  feedback: {
    positive: 0,
    negative: 0
  },
  utilization: {
    available: 0,
    actual: 0,
    scheduled: 0
  },
  timeOfVisit: {
    scheduled: {},
    walkins: {}
  },
  durations: [] // { quantity, actual, duration, schedulerId, type }

});
export var MetricsSummary = compose(connect(mapStateToProps), withProps(function (_ref14) {
  var schedulerId = _ref14.schedulerId,
      eventType = _ref14.eventType,
      metrics = _ref14.metrics;

  if (!metrics) {
    return {
      summary: Summary()
    };
  }

  var records = schedulerId ? metrics.filter(function (m) {
    return m.schedulerId === schedulerId;
  }) : metrics;
  var summary = records.reduce(function (summary, _ref15) {
    var data = _ref15.data;
    // Add total available minutes
    summary.utilization.available += toInt(data.totalMinutesAvailable); // If event type is not specified, add feedback results not associated to events

    if (!eventType) {
      summary.feedback.positive += toInt(data.feedback.Positive);
      summary.feedback.negative += toInt(data.feedback.Negative);
    } // Iterate through all the event types


    return data.eventTypes // If event type is selected, filter to only that type
    .filter(function (event) {
      return !eventType || eventType === event.type;
    }).reduce(function (s, event) {
      // Add appointment counts
      s.appointments.scheduled += toInt(event.scheduledAppointments);
      s.appointments.walkins += toInt(event.walkins);
      s.appointments.sameDay += toInt(event.sameDayAppointments); // Add feedback counts

      s.feedback.positive += toInt(event.feedback.Positive);
      s.feedback.negative += toInt(event.feedback.Negative); // Add total scheduled minutes and actual minutes

      s.utilization.scheduled += parseInt(event.scheduledAppointments, 10) * toInt(event.duration);
      s.utilization.actual += toInt(event.scheduledTotalDuration); // Add time of visit counts for scheduled appointments

      Object.keys(event.scheduledAppointmentTimes).forEach(function (time) {
        if (!s.timeOfVisit.scheduled[time]) {
          s.timeOfVisit.scheduled[time] = toInt(event.scheduledAppointmentTimes[time]);
        } else {
          s.timeOfVisit.scheduled[time] += toInt(event.scheduledAppointmentTimes[time]);
        }
      }); // Add time of visit counts for walkin appointments

      Object.keys(event.walkinAppointmentTimes).forEach(function (time) {
        if (!s.timeOfVisit.walkins[time]) {
          s.timeOfVisit.walkins[time] = toInt(event.walkinAppointmentTimes[time]);
        } else {
          s.timeOfVisit.walkins[time] += toInt(event.walkinAppointmentTimes[time]);
        }
      }); // Add duration info

      var existingDuration = s.durations.find(function (d) {
        return d.schedulerId === data.schedulerId && d.type === event.type;
      });

      if (existingDuration) {
        existingDuration.quantity += toInt(event.scheduledAppointments) + toInt(event.walkins);
        existingDuration.actual += toInt(event.walkinTotalDuration) + toInt(event.scheduledTotalDuration);
        existingDuration.waitTime += toInt(event.walkinTotalWaitTime) + toInt(event.scheduledTotalWaitTime);
      } else {
        s.durations.push({
          type: event.type,
          schedulerId: data.schedulerId,
          duration: toInt(event.duration),
          quantity: toInt(event.scheduledAppointments) + toInt(event.walkins),
          actual: toInt(event.walkinTotalDuration) + toInt(event.scheduledTotalDuration),
          waitTime: toInt(event.walkinTotalWaitTime) + toInt(event.scheduledTotalWaitTime)
        });
      }

      return s;
    }, summary);
  }, Summary().toJS()); // Total appointments and feedback

  summary.appointments.total = summary.appointments.scheduled + summary.appointments.walkins;
  summary.feedback.total = summary.feedback.positive + summary.feedback.negative;
  return {
    summary: summary
  };
}))(MetricsSummaryComponent);