import _get from "lodash/fp/get";
import _findKey from "lodash/fp/findKey";
import _flatten from "lodash/fp/flatten";
import _times from "lodash/fp/times";
import _fromPairs from "lodash/fp/fromPairs";
import _omit from "lodash/fp/omit";
import _isEmpty from "lodash/fp/isEmpty";
import _values from "lodash/fp/values";
import _toPairs from "lodash/fp/toPairs";
import _map from "lodash/fp/map";
import _getOr from "lodash/fp/getOr";
import _size from "lodash/fp/size";
import _mapValues from "lodash/fp/mapValues";
import _keyBy from "lodash/fp/keyBy";
import _pipe from "lodash/fp/pipe";
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); }
import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
import { Radar, RadarChart, PolarGrid, PolarAngleAxis, ResponsiveContainer, Tooltip, PolarRadiusAxis } from 'recharts';
import { convert } from 'css-color-function';
import classnames from 'classnames';
import { isMobile as getIsMobile } from '../../util/check-is-mobile';
import ButtonLink from '../../atom/button-link';
import Provider, { GetSkinFromContext, GetTranslateFromContext } from '../../atom/provider';
import { learningProfileRadarChartPropTypes } from './types';
import style from './style.css';
/* 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.createElement("defs", null, /*#__PURE__*/React.createElement("linearGradient", {
  id: `gradient-${type}`,
  x1: "0%",
  y1: "0%",
  x2: "0%",
  y2: "100%"
}, /*#__PURE__*/React.createElement("stop", {
  offset: "0%",
  stopColor: firstColor
}), /*#__PURE__*/React.createElement("stop", {
  offset: "100%",
  stopColor: secondColor
})));
const CustomTooltip = ({
  active,
  payload,
  label
}) => active && !!payload?.length ? /*#__PURE__*/React.createElement("div", {
  className: style.tooltip
}, /*#__PURE__*/React.createElement("span", {
  className: style.tooltipLabel
}, label), /*#__PURE__*/React.createElement("span", {
  className: style.tooltipValue
}, payload[0].value, "%")) : null;
const CustomDot = ({
  cx,
  cy,
  payload,
  onDotHover,
  onDotClick,
  stroke,
  activeDot,
  dataName
}) => /*#__PURE__*/React.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) => _times(index => {
  const datakey = `value${index + 1}`;
  const dataset = `dataset-${index + 1}`;
  return /*#__PURE__*/React.createElement(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.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] = 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 : 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 : convert(`color(${primarySkinColor} a(0.07))`),
        color: hovered ? '#FFFFFF' : primarySkinColor,
        size: 16
      }
    }
  };
  const handleMouseOver = useCallback(() => setHovered(true), [setHovered]);
  const handleMouseLeave = useCallback(() => setHovered(false), [setHovered]);
  const extraOffsetY = isCurrentDotActive && index === 0 ? -25 : 0;
  return /*#__PURE__*/React.createElement("g", null, /*#__PURE__*/React.createElement("foreignObject", {
    className: classnames(style.tickeForeignObject, isCurrentDotActive && style.tickeForeignObjectFocus),
    x: x + offsetX,
    y: y + offsetY + extraOffsetY
  }, /*#__PURE__*/React.createElement("div", {
    "data-name": label,
    onClick: onLabelClick,
    className: classnames(style.tickWrapper, isCurrentDotActive && style.tickWrapperFocus, hoveredDot === label && style.tickWrapperHover),
    style: {
      ...rest,
      alignItems: alignment,
      textAlign: alignment,
      opacity: !_isEmpty(activeDot) && !isCurrentDotActive ? 0.3 : 1
    }
  }, formatedColors.map(({
    percentage: {
      color,
      background
    },
    label: {
      color: colorLabel
    }
  }, i) => /*#__PURE__*/React.createElement(Fragment, {
    key: i
  }, /*#__PURE__*/React.createElement("span", {
    className: style.tickValue,
    style: {
      color,
      background
    }
  }, percentagesValues[i]), /*#__PURE__*/React.createElement("span", {
    className: style.tickLabel,
    style: {
      color: colorLabel
    }
  }, label))), isCurrentDotActive ? /*#__PURE__*/React.createElement("div", {
    className: style.buttonWrapper,
    onMouseOver: handleMouseOver,
    onMouseLeave: handleMouseLeave,
    "data-name": "button-explore-wrapper"
  }, /*#__PURE__*/React.createElement(ButtonLink, buttonExploreProps)) : null)));
};

/* UTILS */
const CHART_CONFIGS_BY_SIDE_COUNT = _pipe(_keyBy('sideCount'), _mapValues('name'))(CHART_CONFIGS);
const formatValues = _pipe(values_ => _flatten([values_]), values_ => values_.map((val, i) => [`value${i + 1}`, val]), _fromPairs);

/* this convert incoming component data to rechart data structure */
export const formatData = (legend, data_) => _pipe(_toPairs, _map(([ref, values_]) => ({
  ...formatValues(values_),
  subject: legend[ref]
})))(data_);
export const LearningProfileRadarChart = ({
  data,
  legend,
  totalDataset,
  colors: colorsProps,
  onClick,
  onExploreClick,
  width,
  height,
  margin
}, legacyContext) => {
  const [isMobile, setIsMobile] = useState(false);
  const [activeDot, setActiveDot] = useState();
  const [hoveredDot, setHoveredDot] = useState('');
  const skin = GetSkinFromContext(legacyContext);
  const translate = GetTranslateFromContext(legacyContext);
  const primarySkinColor = _get('common.primary', skin);
  const formatedColors = _times(i => {
    if (!colorsProps?.length) return DEFAULT_COLORS;
    const colors = colorsProps[i];
    return colors ? Object.assign({}, DEFAULT_COLORS, colors) : DEFAULT_COLORS;
  })(totalDataset);
  const chartType = useMemo(() => _getOr('hexagon', _size(data), CHART_CONFIGS_BY_SIDE_COUNT), [data]);
  const gradients = useMemo(() => formatedColors.map(({
    gradient: {
      fill,
      stroke
    }
  }, index) => /*#__PURE__*/React.createElement("svg", {
    key: `gradient-${index}`
  }, /*#__PURE__*/React.createElement(Gradient, {
    type: `fill-${index}`,
    colors: fill
  }), /*#__PURE__*/React.createElement(Gradient, {
    type: `stroke-${index}`,
    colors: stroke
  }))), [formatedColors]);
  const userAgent = navigator?.userAgent;
  const isMobile_ = useMemo(() => getIsMobile(userAgent), [userAgent]);
  const setIsMobile_ = useCallback(() => {
    setIsMobile(isMobile_);
  }, [isMobile_]);
  useEffect(() => setIsMobile_(), [setIsMobile_]);
  useEffect(() => {
    const handleClick = () => {
      setActiveDot(undefined);
      onClick(undefined);
    };
    !_isEmpty(activeDot) && window.addEventListener('click', handleClick);
    return () => {
      window.removeEventListener('click', handleClick);
    };
  }, [activeDot, onClick, setActiveDot]);
  function handleOnActiveDotClick() {
    setActiveDot(undefined);
    onClick(undefined);
  }
  function handleOnDotClick(label) {
    if (!_isEmpty(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 = _findKey(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 = _findKey(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 = _pipe(_omit('subject'), _mapValues(value => `${value}%`), _values)(currentData);
    return /*#__PURE__*/React.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 = useMemo(() => formatData(legend, data), [legend, data]);
  return /*#__PURE__*/React.createElement(RadarChart, {
    width: width,
    height: height,
    margin: margin ?? (isMobile ? {
      top: 80
    } : {
      top: 180
    }),
    cx: "50%",
    cy: "50%",
    outerRadius: "80%",
    data: formatedData
  }, gradients, /*#__PURE__*/React.createElement(PolarGrid, {
    strokeDasharray: 10,
    strokeWidth: 2,
    radialLines: false
  }), /*#__PURE__*/React.createElement(PolarAngleAxis, {
    dataKey: "subject",
    tick: !isMobile && renderCustomLabel
  }), /*#__PURE__*/React.createElement(PolarRadiusAxis, {
    tick: false,
    axisLine: false,
    domain: [0, 100]
  }), buildRadars(totalDataset, setHoveredDot, handleOnDotClick, activeDot), isMobile ? /*#__PURE__*/React.createElement(Tooltip, {
    cursor: false,
    content: /*#__PURE__*/React.createElement(CustomTooltip, null)
  }) : null);
};
const ResponsiveLearningProfileRadarChart = props => /*#__PURE__*/React.createElement(ResponsiveContainer, {
  width: "100%",
  height: "100%"
}, /*#__PURE__*/React.createElement(LearningProfileRadarChart, props));
LearningProfileRadarChart.contextTypes = {
  skin: Provider.childContextTypes.skin,
  translate: Provider.childContextTypes.translate
};
LearningProfileRadarChart.propTypes = process.env.NODE_ENV !== "production" ? learningProfileRadarChartPropTypes : {};
ResponsiveLearningProfileRadarChart.propTypes = process.env.NODE_ENV !== "production" ? learningProfileRadarChartPropTypes : {};
export default ResponsiveLearningProfileRadarChart;
//# sourceMappingURL=index.js.map