import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _extends from "@babel/runtime/helpers/esm/extends";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

import React, { forwardRef, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { clamp, filter, identity, join, o, path } from 'ramda';
import { Transition } from 'react-transition-group';
import useTheme from '../hooks/useTheme';
import Box from '../Box';
import Text from '../Text';
import { cos, sin } from '../utils/math';
var joinWithDash = o(join('-'), filter(Boolean));

var getCirmcumference = function getCirmcumference(radius) {
  return 2 * radius * Math.PI;
};

var getArcCircumference = function getArcCircumference(C) {
  return function (arcAngle) {
    return arcAngle / 360 * C;
  };
};

var coord = function coord(x, y) {
  return {
    x: x,
    y: y
  };
};

var equalCoord = function equalCoord(x) {
  return {
    x: x,
    y: x
  };
};

var getArcProps = function getArcProps(_ref) {
  var radius = _ref.radius,
      arcAngle = _ref.arcAngle;
  var C = getCirmcumference(radius);
  var CArc = getArcCircumference(C)(arcAngle);
  var offset = C - CArc;
  return {
    CArc: CArc,
    C: C,
    offset: offset
  };
};

export var SvgGradient = function SvgGradient(_ref2) {
  var variant = _ref2.variant,
      rest = _objectWithoutProperties(_ref2, ["variant"]);

  var theme = useTheme();
  var gradient = path(['gauge', variant, 'gradient'].filter(Boolean))(theme);
  return /*#__PURE__*/React.createElement("linearGradient", _extends({
    x1: "0%",
    y1: "0%",
    x2: "100%",
    y2: "0%"
  }, rest), gradient.map(function (_ref3) {
    var _ref4 = _slicedToArray(_ref3, 2),
        offset = _ref4[0],
        stopColor = _ref4[1];

    return /*#__PURE__*/React.createElement("stop", _extends({
      key: "".concat(offset, "-").concat(stopColor)
    }, {
      offset: offset,
      stopColor: stopColor
    }));
  }));
};
process.env.NODE_ENV !== "production" ? SvgGradient.propTypes = {
  variant: PropTypes.string
} : void 0;
var Gauge = /*#__PURE__*/forwardRef(function (_ref5, ref) {
  var _ref5$arcAngle = _ref5.arcAngle,
      arcAngle = _ref5$arcAngle === void 0 ? 240 : _ref5$arcAngle,
      _ref5$animationDurati = _ref5.animationDuration,
      animationDuration = _ref5$animationDurati === void 0 ? 1000 : _ref5$animationDurati,
      _ref5$size = _ref5.size,
      size = _ref5$size === void 0 ? 256 : _ref5$size,
      _ref5$rimStrokeWidth = _ref5.rimStrokeWidth,
      rimStrokeWidth = _ref5$rimStrokeWidth === void 0 ? 1 : _ref5$rimStrokeWidth,
      _ref5$gaugeStrokeWidt = _ref5.gaugeStrokeWidth,
      gaugeStrokeWidth = _ref5$gaugeStrokeWidt === void 0 ? 4 : _ref5$gaugeStrokeWidt,
      _ref5$value = _ref5.value,
      value = _ref5$value === void 0 ? 0 : _ref5$value,
      valueProps = _ref5.valueProps,
      _ref5$min = _ref5.min,
      min = _ref5$min === void 0 ? 0 : _ref5$min,
      _ref5$max = _ref5.max,
      max = _ref5$max === void 0 ? 1 : _ref5$max,
      _ref5$format = _ref5.format,
      format = _ref5$format === void 0 ? identity : _ref5$format,
      _ref5$formatLegend = _ref5.formatLegend,
      formatLegend = _ref5$formatLegend === void 0 ? identity : _ref5$formatLegend,
      title = _ref5.title,
      legendPropsProp = _ref5.legendProps,
      variant = _ref5.variant,
      rest = _objectWithoutProperties(_ref5, ["arcAngle", "animationDuration", "size", "rimStrokeWidth", "gaugeStrokeWidth", "value", "valueProps", "min", "max", "format", "formatLegend", "title", "legendProps", "variant"]);

  // hack to run animation after mount
  var _useState = useState(false),
      _useState2 = _slicedToArray(_useState, 2),
      inProp = _useState2[0],
      setInProp = _useState2[1];

  useEffect(function () {
    setInProp(true);
  }, []);
  var svgSize = 32; // Angle between horizontal axis and the start of gauge

  var alpha = (arcAngle - 180) / 2; // Labels needs to be moved a bit

  var alphaLabels = alpha + 10; // We need to move SVG Circle's zero angle
  // so the gauge stroke is visually symmetric.

  var rotateForSymmetryAngle = -alpha - 180; // Normalized value between 0-1

  var valueNormalized = clamp(0, 1)((value - min) / (max - min)); // Coords of center of the canvas

  var center = equalCoord(svgSize / 2);
  var radiusRim = center.x - rimStrokeWidth / 2;
  var radiusGauge = center.x - (rimStrokeWidth + gaugeStrokeWidth / 2);
  var rimProps = getArcProps({
    radius: radiusRim,
    arcAngle: arcAngle
  });
  var gaugeProps = getArcProps({
    radius: radiusGauge,
    arcAngle: arcAngle * valueNormalized
  });
  var circleProps = {
    transform: "rotate(".concat(rotateForSymmetryAngle, " ").concat(center.x, " ").concat(center.y, ")")
  };

  var legendProps = _objectSpread({
    fill: '#000000',
    stroke: 'none',
    fontSize: '2px'
  }, legendPropsProp);

  var legend = coord(radiusRim * cos(alphaLabels), radiusRim * sin(alphaLabels));
  var transitionStyles = {
    entering: {
      strokeDashoffset: gaugeProps.offset
    },
    entered: {
      strokeDashoffset: gaugeProps.offset
    },
    exiting: {
      strokeDashoffset: gaugeProps.C
    },
    exited: {
      strokeDashoffset: gaugeProps.C
    }
  };
  var gradientId = joinWithDash(['gradient-arc', variant]);
  return /*#__PURE__*/React.createElement(Box, _extends({
    ref: ref,
    __css: {
      position: 'relative',
      width: "".concat(size, "px"),
      height: "".concat(size, "px")
    }
  }, rest), /*#__PURE__*/React.createElement(Box, _extends({
    mt: 0,
    mb: 0,
    fontSize: 8,
    __css: {
      whiteSpace: 'nowrap',
      transform: 'translate(-50%, -50%)',
      position: 'absolute',
      left: '50%',
      top: '50%'
    }
  }, valueProps), format(value)), /*#__PURE__*/React.createElement(Box, {
    as: "svg",
    viewBox: "0 0 ".concat(svgSize, " ").concat(svgSize),
    width: size,
    height: size,
    fill: "none",
    stroke: "currentcolor",
    role: "img",
    "aria-valuenow": value,
    "aria-valuemin": min,
    "aria-valuemax": max,
    __css: {
      color: 'primary'
    }
  }, /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement(SvgGradient, {
    variant: variant,
    id: gradientId
  })), title && /*#__PURE__*/React.createElement("title", null, title), /*#__PURE__*/React.createElement(Text, _extends({
    variant: "",
    as: "text",
    x: center.x - legend.x,
    y: center.y + legend.y,
    textAnchor: "start"
  }, legendProps), formatLegend(min)), /*#__PURE__*/React.createElement(Text, _extends({
    variant: "",
    as: "text",
    x: center.x + legend.x,
    y: center.y + legend.y,
    textAnchor: "end"
  }, legendProps), formatLegend(max)), /*#__PURE__*/React.createElement("circle", _extends({
    strokeWidth: rimStrokeWidth,
    opacity: 4 / 5,
    cx: center.x,
    cy: center.y,
    r: radiusRim,
    stroke: "url(#".concat(gradientId, ")"),
    strokeDasharray: rimProps.C,
    strokeDashoffset: rimProps.offset
  }, circleProps)), /*#__PURE__*/React.createElement(Transition, {
    "in": inProp,
    timeout: {
      enter: animationDuration,
      exit: animationDuration
    },
    appear: true
  }, function (state) {
    return /*#__PURE__*/React.createElement(Box, _extends({
      as: "circle",
      cx: center.x,
      cy: center.y,
      r: radiusGauge,
      opacity: 1 / 3,
      stroke: "url(#".concat(gradientId, ")"),
      strokeWidth: gaugeStrokeWidth,
      strokeDasharray: gaugeProps.C,
      __css: {
        transition: "stroke-dashoffset ".concat(animationDuration, "ms cubic-bezier(0, 0, 0.2, 1)")
      }
    }, transitionStyles[state], circleProps));
  })));
});
Gauge.displayName = 'Gauge';
process.env.NODE_ENV !== "production" ? Gauge.propTypes = {
  animationDuration: PropTypes.number,
  arcAngle: PropTypes.number,
  format: PropTypes.func,
  formatLegend: PropTypes.func,
  gaugeStrokeWidth: PropTypes.number,
  legendProps: PropTypes.object,
  max: PropTypes.number,
  min: PropTypes.number,
  rimStrokeWidth: PropTypes.number,
  size: PropTypes.number,
  title: PropTypes.string,
  value: PropTypes.number,
  valueProps: PropTypes.object,
  variant: PropTypes.string
} : void 0;
export default Gauge;