"use strict";

exports.__esModule = true;
exports.formatData = exports.default = exports.LearningProfileRadarChart = void 0;
var _get2 = _interopRequireDefault(require("lodash/fp/get"));
var _findKey2 = _interopRequireDefault(require("lodash/fp/findKey"));
var _flatten2 = _interopRequireDefault(require("lodash/fp/flatten"));
var _times2 = _interopRequireDefault(require("lodash/fp/times"));
var _fromPairs2 = _interopRequireDefault(require("lodash/fp/fromPairs"));
var _omit2 = _interopRequireDefault(require("lodash/fp/omit"));
var _isEmpty2 = _interopRequireDefault(require("lodash/fp/isEmpty"));
var _values2 = _interopRequireDefault(require("lodash/fp/values"));
var _toPairs2 = _interopRequireDefault(require("lodash/fp/toPairs"));
var _map2 = _interopRequireDefault(require("lodash/fp/map"));
var _getOr2 = _interopRequireDefault(require("lodash/fp/getOr"));
var _size2 = _interopRequireDefault(require("lodash/fp/size"));
var _mapValues2 = _interopRequireDefault(require("lodash/fp/mapValues"));
var _keyBy2 = _interopRequireDefault(require("lodash/fp/keyBy"));
var _pipe2 = _interopRequireDefault(require("lodash/fp/pipe"));
var _react = _interopRequireWildcard(require("react"));
var _recharts = require("recharts");
var _cssColorFunction = require("css-color-function");
var _classnames = _interopRequireDefault(require("classnames"));
var _checkIsMobile = require("../../util/check-is-mobile");
var _buttonLink = _interopRequireDefault(require("../../atom/button-link"));
var _provider = _interopRequireWildcard(require("../../atom/provider"));
var _types = require("./types");
var _style = _interopRequireDefault(require("./style.css"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
/* TICK_POSITIONS */
const top = {
  offset: {
    x: -100,
    y: -75
  },
  alignment: 'center',
  margin: 'auto'
};
const bottom = {
  offset: {
    x: -100,
    y: 10
  },
  alignment: 'center',
  margin: 'auto'
};
const right = {
  offset: {
    x: 30,
    y: -10
  },
  alignment: 'start',
  marginRight: 'auto'
};
const left = {
  offset: {
    x: -230,
    y: -10
  },
  alignment: 'end',
  marginLeft: 'auto'
};

/* CONSTANTS */
const BLACK = '#000000ff';
const WHITE = '#ffffffff';
const DEFAULT_MAIN_COLOR = '#0062ffff';
const DEFAULT_COLORS = {
  gradient: {
    fill: [DEFAULT_MAIN_COLOR, DEFAULT_MAIN_COLOR],
    stroke: [DEFAULT_MAIN_COLOR, DEFAULT_MAIN_COLOR]
  },
  percentage: {
    color: BLACK,
    background: WHITE
  },
  label: {
    color: BLACK
  }
};
const CHART_CONFIGS = {
  triangle: {
    name: 'triangle',
    ticks: [top, right, left],
    sideCount: 3
  },
  quadrilateral: {
    name: 'quadrilateral',
    ticks: [top, right, bottom, left],
    sideCount: 4
  },
  pentagon: {
    name: 'pentagon',
    ticks: [top, right, right, left, left],
    sideCount: 5
  },
  hexagon: {
    name: 'hexagon',
    ticks: [top, right, right, bottom, left, left],
    sideCount: 6
  }
};
const DOT_DEFAULT_PROPS = {
  strokeWidth: 2,
  strokeOpacity: 0.4,
  fill: '#fff',
  r: 4,
  pointerEvents: 'all',
  style: {
    cursor: 'pointer'
  }
};
const DOT_ACTIVE_PROPS = {
  fill: '#fff',
  r: 6,
  strokeWidth: 4,
  strokeOpacity: 0.6
};
const RADAR_DEFAULT_PROPS = {
  strokeWidth: 3,
  strokeOpacity: 0.2,
  fillOpacity: 0.2
};

/* COMPONENTS */
const Gradient = ({
  type,
  colors: [firstColor, secondColor]
}) => /*#__PURE__*/_react.default.createElement("defs", null, /*#__PURE__*/_react.default.createElement("linearGradient", {
  id: `gradient-${type}`,
  x1: "0%",
  y1: "0%",
  x2: "0%",
  y2: "100%"
}, /*#__PURE__*/_react.default.createElement("stop", {
  offset: "0%",
  stopColor: firstColor
}), /*#__PURE__*/_react.default.createElement("stop", {
  offset: "100%",
  stopColor: secondColor
})));
const CustomTooltip = ({
  active,
  payload,
  label
}) => active && !!payload?.length ? /*#__PURE__*/_react.default.createElement("div", {
  className: _style.default.tooltip
}, /*#__PURE__*/_react.default.createElement("span", {
  className: _style.default.tooltipLabel
}, label), /*#__PURE__*/_react.default.createElement("span", {
  className: _style.default.tooltipValue
}, payload[0].value, "%")) : null;
const CustomDot = ({
  cx,
  cy,
  payload,
  onDotHover,
  onDotClick,
  stroke,
  activeDot,
  dataName
}) => /*#__PURE__*/_react.default.createElement("circle", _extends({}, DOT_DEFAULT_PROPS, payload?.payload.subject === activeDot?.label && DOT_ACTIVE_PROPS, {
  stroke,
  cx,
  cy,
  onTouchStart: () => {
    if (!payload?.name) return;
    onDotClick(payload.name);
  },
  onClick: e => {
    e.stopPropagation();
    if (!payload?.name) return;
    onDotClick(payload.name);
  },
  onMouseOver: () => {
    if (!payload?.name) return;
    onDotHover(payload.name);
  },
  onMouseLeave: () => onDotHover(''),
  'data-name': dataName
}));
const buildRadars = (totalDataset, handleDotHover, handleOnDotClick, activeDot) => (0, _times2.default)(index => {
  const datakey = `value${index + 1}`;
  const dataset = `dataset-${index + 1}`;
  return /*#__PURE__*/_react.default.createElement(_recharts.Radar, _extends({}, RADAR_DEFAULT_PROPS, {
    fill: `url(#gradient-fill-${index})`,
    stroke: `url(#gradient-stroke-${index})`,
    key: dataset,
    name: dataset,
    dataKey: datakey,
    activeDot: {
      ...DOT_ACTIVE_PROPS,
      stroke: `url(#gradient-stroke-${index})`
    }
    // only on mobile
    // to handle dot style on hover (convert to click)
    // use with the tooltip component
    ,
    dot: /*#__PURE__*/_react.default.createElement(CustomDot, {
      onDotHover: handleDotHover,
      onDotClick: handleOnDotClick,
      activeDot: activeDot,
      dataKey: datakey,
      stroke: `url(#gradient-stroke-${index})`,
      dataName: `dot-${dataset}`
    })
  }));
}, totalDataset);
const CustomLabel = ({
  index,
  x,
  y,
  percentagesValues,
  label,
  activeDot,
  chartType,
  formatedColors,
  primarySkinColor,
  exploreLocale,
  hoveredDot,
  onClick,
  onExploreClick
}) => {
  const [hovered, setHovered] = (0, _react.useState)(false);
  const isCurrentDotActive = activeDot?.label === label;
  const {
    offset: {
      x: offsetX,
      y: offsetY
    },
    alignment,
    ...rest
  } = CHART_CONFIGS[chartType].ticks[index];
  function onLabelClick(e) {
    e.stopPropagation();
    onClick(label);
  }
  function handleExploreClick() {
    onExploreClick(label);
  }
  const buttonExploreProps = {
    customStyle: {
      height: '36px',
      backgroundColor: hovered ? primarySkinColor : (0, _cssColorFunction.convert)(`color(${primarySkinColor} a(0.07))`),
      color: hovered ? '#FFFFFF' : primarySkinColor,
      transition: 'background-color 0.15s ease-in-out, color 0.15s ease-in-out'
    },
    onClick: handleExploreClick,
    'aria-label': `${label}, ${exploreLocale}`,
    label: exploreLocale,
    'data-name': 'learner-skill-card-explore-button',
    icon: {
      position: 'left',
      faIcon: {
        name: 'compass',
        backgroundColor: hovered ? primarySkinColor : (0, _cssColorFunction.convert)(`color(${primarySkinColor} a(0.07))`),
        color: hovered ? '#FFFFFF' : primarySkinColor,
        size: 16
      }
    }
  };
  const handleMouseOver = (0, _react.useCallback)(() => setHovered(true), [setHovered]);
  const handleMouseLeave = (0, _react.useCallback)(() => setHovered(false), [setHovered]);
  const extraOffsetY = isCurrentDotActive && index === 0 ? -25 : 0;
  return /*#__PURE__*/_react.default.createElement("g", null, /*#__PURE__*/_react.default.createElement("foreignObject", {
    className: (0, _classnames.default)(_style.default.tickeForeignObject, isCurrentDotActive && _style.default.tickeForeignObjectFocus),
    x: x + offsetX,
    y: y + offsetY + extraOffsetY
  }, /*#__PURE__*/_react.default.createElement("div", {
    "data-name": label,
    onClick: onLabelClick,
    className: (0, _classnames.default)(_style.default.tickWrapper, isCurrentDotActive && _style.default.tickWrapperFocus, hoveredDot === label && _style.default.tickWrapperHover),
    style: {
      ...rest,
      alignItems: alignment,
      textAlign: alignment,
      opacity: !(0, _isEmpty2.default)(activeDot) && !isCurrentDotActive ? 0.3 : 1
    }
  }, formatedColors.map(({
    percentage: {
      color,
      background
    },
    label: {
      color: colorLabel
    }
  }, i) => /*#__PURE__*/_react.default.createElement(_react.Fragment, {
    key: i
  }, /*#__PURE__*/_react.default.createElement("span", {
    className: _style.default.tickValue,
    style: {
      color,
      background
    }
  }, percentagesValues[i]), /*#__PURE__*/_react.default.createElement("span", {
    className: _style.default.tickLabel,
    style: {
      color: colorLabel
    }
  }, label))), isCurrentDotActive ? /*#__PURE__*/_react.default.createElement("div", {
    className: _style.default.buttonWrapper,
    onMouseOver: handleMouseOver,
    onMouseLeave: handleMouseLeave,
    "data-name": "button-explore-wrapper"
  }, /*#__PURE__*/_react.default.createElement(_buttonLink.default, buttonExploreProps)) : null)));
};

/* UTILS */
const CHART_CONFIGS_BY_SIDE_COUNT = (0, _pipe2.default)((0, _keyBy2.default)('sideCount'), (0, _mapValues2.default)('name'))(CHART_CONFIGS);
const formatValues = (0, _pipe2.default)(values_ => (0, _flatten2.default)([values_]), values_ => values_.map((val, i) => [`value${i + 1}`, val]), _fromPairs2.default);

/* this convert incoming component data to rechart data structure */
const formatData = (legend, data_) => (0, _pipe2.default)(_toPairs2.default, (0, _map2.default)(([ref, values_]) => ({
  ...formatValues(values_),
  subject: legend[ref]
})))(data_);
exports.formatData = formatData;
const LearningProfileRadarChart = ({
  data,
  legend,
  totalDataset,
  colors: colorsProps,
  onClick,
  onExploreClick,
  width,
  height,
  margin
}, legacyContext) => {
  const [isMobile, setIsMobile] = (0, _react.useState)(false);
  const [activeDot, setActiveDot] = (0, _react.useState)();
  const [hoveredDot, setHoveredDot] = (0, _react.useState)('');
  const skin = (0, _provider.GetSkinFromContext)(legacyContext);
  const translate = (0, _provider.GetTranslateFromContext)(legacyContext);
  const primarySkinColor = (0, _get2.default)('common.primary', skin);
  const formatedColors = (0, _times2.default)(i => {
    if (!colorsProps?.length) return DEFAULT_COLORS;
    const colors = colorsProps[i];
    return colors ? Object.assign({}, DEFAULT_COLORS, colors) : DEFAULT_COLORS;
  })(totalDataset);
  const chartType = (0, _react.useMemo)(() => (0, _getOr2.default)('hexagon', (0, _size2.default)(data), CHART_CONFIGS_BY_SIDE_COUNT), [data]);
  const gradients = (0, _react.useMemo)(() => formatedColors.map(({
    gradient: {
      fill,
      stroke
    }
  }, index) => /*#__PURE__*/_react.default.createElement("svg", {
    key: `gradient-${index}`
  }, /*#__PURE__*/_react.default.createElement(Gradient, {
    type: `fill-${index}`,
    colors: fill
  }), /*#__PURE__*/_react.default.createElement(Gradient, {
    type: `stroke-${index}`,
    colors: stroke
  }))), [formatedColors]);
  const userAgent = navigator?.userAgent;
  const isMobile_ = (0, _react.useMemo)(() => (0, _checkIsMobile.isMobile)(userAgent), [userAgent]);
  const setIsMobile_ = (0, _react.useCallback)(() => {
    setIsMobile(isMobile_);
  }, [isMobile_]);
  (0, _react.useEffect)(() => setIsMobile_(), [setIsMobile_]);
  (0, _react.useEffect)(() => {
    const handleClick = () => {
      setActiveDot(undefined);
      onClick(undefined);
    };
    !(0, _isEmpty2.default)(activeDot) && window.addEventListener('click', handleClick);
    return () => {
      window.removeEventListener('click', handleClick);
    };
  }, [activeDot, onClick, setActiveDot]);
  function handleOnActiveDotClick() {
    setActiveDot(undefined);
    onClick(undefined);
  }
  function handleOnDotClick(label) {
    if (!(0, _isEmpty2.default)(activeDot) && activeDot?.label === label) {
      handleOnActiveDotClick();
      return;
    }
    const payload = formatedData.find(({
      subject
    }) => subject === label);
    if (!payload) return;
    const index = formatedData.indexOf(payload);
    const datakey = `value${index + 1}`;
    const skillRef = (0, _findKey2.default)(val => val === payload?.subject, legend);
    if (skillRef) {
      setActiveDot({
        key: datakey,
        value: payload[datakey],
        label: payload.subject
      });
      onClick(skillRef);
    }
  }
  function handleExploreClick(label) {
    const payload = formatedData.find(({
      subject
    }) => subject === label);
    if (!payload) return;
    const skillRef = (0, _findKey2.default)(val => val === payload?.subject, legend);
    if (skillRef) {
      onExploreClick(skillRef);
    }
  }
  function renderCustomLabel(props) {
    const {
      x,
      y,
      payload: {
        value: label
      },
      index
    } = props;
    const currentData = formatedData.find(({
      subject
    }) => subject === label);
    const percentagesValues = (0, _pipe2.default)((0, _omit2.default)('subject'), (0, _mapValues2.default)(value => `${value}%`), _values2.default)(currentData);
    return /*#__PURE__*/_react.default.createElement(CustomLabel, {
      index: index,
      x: x,
      y: y,
      percentagesValues: percentagesValues,
      label: label,
      activeDot: activeDot,
      chartType: chartType,
      formatedColors: formatedColors,
      primarySkinColor: primarySkinColor,
      exploreLocale: translate('Explore'),
      hoveredDot: hoveredDot,
      onClick: handleOnDotClick,
      onExploreClick: handleExploreClick
    });
  }
  const formatedData = (0, _react.useMemo)(() => formatData(legend, data), [legend, data]);
  return /*#__PURE__*/_react.default.createElement(_recharts.RadarChart, {
    width: width,
    height: height,
    margin: margin ?? (isMobile ? {
      top: 80
    } : {
      top: 180
    }),
    cx: "50%",
    cy: "50%",
    outerRadius: "80%",
    data: formatedData
  }, gradients, /*#__PURE__*/_react.default.createElement(_recharts.PolarGrid, {
    strokeDasharray: 10,
    strokeWidth: 2,
    radialLines: false
  }), /*#__PURE__*/_react.default.createElement(_recharts.PolarAngleAxis, {
    dataKey: "subject",
    tick: !isMobile && renderCustomLabel
  }), /*#__PURE__*/_react.default.createElement(_recharts.PolarRadiusAxis, {
    tick: false,
    axisLine: false,
    domain: [0, 100]
  }), buildRadars(totalDataset, setHoveredDot, handleOnDotClick, activeDot), isMobile ? /*#__PURE__*/_react.default.createElement(_recharts.Tooltip, {
    cursor: false,
    content: /*#__PURE__*/_react.default.createElement(CustomTooltip, null)
  }) : null);
};
exports.LearningProfileRadarChart = LearningProfileRadarChart;
const ResponsiveLearningProfileRadarChart = props => /*#__PURE__*/_react.default.createElement(_recharts.ResponsiveContainer, {
  width: "100%",
  height: "100%"
}, /*#__PURE__*/_react.default.createElement(LearningProfileRadarChart, props));
LearningProfileRadarChart.contextTypes = {
  skin: _provider.default.childContextTypes.skin,
  translate: _provider.default.childContextTypes.translate
};
LearningProfileRadarChart.propTypes = process.env.NODE_ENV !== "production" ? _types.learningProfileRadarChartPropTypes : {};
ResponsiveLearningProfileRadarChart.propTypes = process.env.NODE_ENV !== "production" ? _types.learningProfileRadarChartPropTypes : {};
var _default = exports.default = ResponsiveLearningProfileRadarChart;
//# sourceMappingURL=index.js.map