"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Metric = void 0;
const classnames_1 = __importDefault(require("classnames"));
const react_1 = __importStar(require("react"));
const progress_1 = require("./progress");
const sparkline_1 = require("./sparkline");
const text_1 = require("./text");
const color_calcs_1 = require("../../../../common/color_calcs");
const color_library_wrappers_1 = require("../../../../common/color_library_wrappers");
const constants_1 = require("../../../../common/constants");
const fill_text_color_1 = require("../../../../common/fill_text_color");
const common_1 = require("../../../../utils/common");
const specs_1 = require("../../specs");
const progressBarMap = {
    4: 'small',
    8: 'medium',
    16: 'large',
};
const getTextColor = ({ metricContext: { backgroundColor, blendedColor, hasProgressBar, hasTrend }, contrastOptions, }) => {
    const highContrastTextColor = (0, fill_text_color_1.fillTextColor)(backgroundColor, hasProgressBar ? backgroundColor : blendedColor, undefined, contrastOptions);
    let finalTextColor = highContrastTextColor.color;
    if (hasTrend) {
        const { ratio, color, shade } = (0, fill_text_color_1.fillTextColor)(backgroundColor, (0, sparkline_1.getSparkLineColor)(blendedColor), undefined, contrastOptions);
        if (shade !== highContrastTextColor.shade && ratio > highContrastTextColor.ratio) {
            finalTextColor = color;
        }
    }
    return finalTextColor.keyword;
};
const getTextColors = ({ metricContext, textContrastOptions, }) => {
    return {
        highContrast: getTextColor({
            metricContext,
            contrastOptions: textContrastOptions.text,
        }),
        subtitle: getTextColor({
            metricContext,
            contrastOptions: textContrastOptions.subtitle,
        }),
        extra: getTextColor({
            metricContext,
            contrastOptions: textContrastOptions.extra,
        }),
    };
};
const CONTRAST_THRESHOLD = 3.0;
function isColorContrastOptions(options) {
    return !('text' in options);
}
const Metric = ({ chartId, hasTitles, rowIndex, columnIndex, totalColumns, totalRows, datum, style, backgroundColor: chartBackgroundColor, contrastOptions, textDimensions, onElementClick, onElementOver, onElementOut, }) => {
    const { progressBarThickness } = textDimensions.heightBasedSizes;
    const progressBarSize = progressBarMap[progressBarThickness] ?? 'medium';
    const [mouseState, setMouseState] = (0, react_1.useState)('leave');
    const [lastMouseDownTimestamp, setLastMouseDownTimestamp] = (0, react_1.useState)(0);
    const metricHTMLId = `echMetric-${chartId}-${rowIndex}-${columnIndex}`;
    const hasProgressBar = (0, specs_1.isMetricWProgress)(datum);
    const progressBarDirection = hasProgressBar ? datum.progressBarDirection : undefined;
    const hasTrend = (0, specs_1.isMetricWTrend)(datum);
    const { metricSpacing } = textDimensions;
    const containerClassName = (0, classnames_1.default)('echMetric', {
        'echMetric--rightBorder': columnIndex < totalColumns - 1,
        'echMetric--bottomBorder': rowIndex < totalRows - 1,
        'echMetric--topBorder': hasTitles && rowIndex === 0,
        'echMetric--vertical': progressBarDirection === common_1.LayoutDirection.Vertical,
        'echMetric--horizontal': progressBarDirection === common_1.LayoutDirection.Horizontal,
        [`echMetric--withProgressBar--${progressBarSize}`]: hasProgressBar,
        [`echMetric--withTargetProgressBar--${progressBarSize}`]: !(0, common_1.isNil)(datum?.target),
    });
    const lightnessAmount = mouseState === 'leave' ? 0 : mouseState === 'enter' ? 0.05 : 0.1;
    const backgroundColor = datum.background
        ? (0, color_library_wrappers_1.RGBATupleToString)((0, color_calcs_1.combineColors)((0, color_library_wrappers_1.colorToRgba)(datum.background), (0, color_library_wrappers_1.colorToRgba)(chartBackgroundColor)))
        : chartBackgroundColor;
    const blendingBackgroundColor = !style.blendingBackground
        ? (0, color_library_wrappers_1.colorToRgba)(backgroundColor)
        : (0, color_calcs_1.combineColors)((0, color_library_wrappers_1.colorToRgba)(style.blendingBackground), (0, color_library_wrappers_1.colorToRgba)(backgroundColor));
    const interactionColor = (0, color_library_wrappers_1.changeColorLightness)(hasProgressBar ? backgroundColor : datum.color, lightnessAmount, 0.8);
    const blendedColor = (0, color_library_wrappers_1.RGBATupleToString)((0, color_calcs_1.combineColors)((0, color_library_wrappers_1.colorToRgba)(datum.color), blendingBackgroundColor));
    const blendedInteractionColor = (0, color_library_wrappers_1.RGBATupleToString)((0, color_calcs_1.combineColors)((0, color_library_wrappers_1.colorToRgba)(interactionColor), blendingBackgroundColor));
    const datumWithInteractionColor = { ...datum, color: blendedInteractionColor };
    const event = { type: 'metricElementEvent', rowIndex, columnIndex };
    const containerStyle = {
        backgroundColor: hasTrend || hasProgressBar ? backgroundColor : datumWithInteractionColor.color,
        cursor: onElementClick ? 'pointer' : constants_1.DEFAULT_CSS_CURSOR,
        borderColor: style.border,
        fontFamily: style.fontFamily,
        '--echMetricPadding': `${metricSpacing.panelPadding}px`,
        '--echMetricTitleSubtitleGap': `${metricSpacing.titleSubtitleGap}px`,
        '--echMetricExtraPaddingTop': `${metricSpacing.extraPaddingTop}px`,
        '--echMetricProgressTextGap': `${metricSpacing.progressTextGap}px`,
    };
    const textContrastOptions = isColorContrastOptions(contrastOptions)
        ? {
            text: contrastOptions,
            subtitle: contrastOptions,
            extra: contrastOptions,
        }
        : contrastOptions;
    const textColors = getTextColors({
        metricContext: { backgroundColor, blendedColor, hasProgressBar, hasTrend },
        textContrastOptions,
    });
    let defaultBadgeBorderColor;
    if ((0, specs_1.isSecondaryMetricProps)(datum.extra) &&
        !!datum.extra.badgeColor &&
        datum.extra.badgeBorderColor &&
        datum.extra.badgeBorderColor.mode === 'auto') {
        const metricBackgroundColor = hasProgressBar ? backgroundColor : blendedColor;
        const borderRecommendation = (0, color_calcs_1.getContrastRecommendation)(metricBackgroundColor, datum.extra.badgeColor, {
            contrastThreshold: CONTRAST_THRESHOLD,
            borderOptions: textContrastOptions.extra,
        });
        defaultBadgeBorderColor = borderRecommendation.borderColor;
        if (hasTrend) {
            const { shade, borderColor, contrastRatio } = (0, color_calcs_1.getContrastRecommendation)((0, sparkline_1.getSparkLineColor)(blendedColor), datum.extra.badgeColor, {
                contrastThreshold: CONTRAST_THRESHOLD,
                borderOptions: textContrastOptions.extra,
            });
            if (shade !== borderRecommendation.shade && contrastRatio > borderRecommendation.contrastRatio) {
                defaultBadgeBorderColor = borderColor;
            }
        }
    }
    const onElementClickHandler = () => onElementClick && onElementClick([event]);
    const hasMouseEventsHandler = onElementOut || onElementOver || onElementClick;
    return (react_1.default.createElement("div", { role: "figure", "aria-labelledby": datum.title && metricHTMLId, className: containerClassName, style: containerStyle, onMouseLeave: () => {
            if (hasMouseEventsHandler)
                setMouseState('leave');
            if (onElementOut)
                onElementOut();
        }, onMouseEnter: () => {
            if (hasMouseEventsHandler)
                setMouseState('enter');
            if (onElementOver)
                onElementOver([event]);
        }, onMouseDown: () => {
            if (hasMouseEventsHandler)
                setMouseState('down');
            setLastMouseDownTimestamp(Date.now());
        }, onMouseUp: () => {
            if (hasMouseEventsHandler)
                setMouseState('enter');
            if (Date.now() - lastMouseDownTimestamp < 200 && onElementClick) {
                onElementClickHandler();
            }
        }, onFocus: () => {
            if (hasMouseEventsHandler)
                setMouseState('enter');
        }, onBlur: () => {
            if (hasMouseEventsHandler)
                setMouseState('leave');
        }, onClick: (e) => {
            e.stopPropagation();
        } },
        react_1.default.createElement(text_1.MetricText, { id: metricHTMLId, datum: datumWithInteractionColor, style: style, onElementClick: onElementClick ? onElementClickHandler : undefined, progressBarSize: progressBarSize, textDimensions: textDimensions, colors: textColors, defaultBadgeBorderColor: defaultBadgeBorderColor }),
        (0, specs_1.isMetricWTrend)(datumWithInteractionColor) && react_1.default.createElement(sparkline_1.SparkLine, { id: metricHTMLId, datum: datumWithInteractionColor }),
        (0, specs_1.isMetricWProgress)(datumWithInteractionColor) && (react_1.default.createElement(progress_1.ProgressBar, { datum: datumWithInteractionColor, barBackground: style.barBackground, panelBackground: backgroundColor, blendedBarColor: blendedColor, size: progressBarSize })),
        react_1.default.createElement("div", { className: "echMetric--outline", style: { color: textColors.highContrast } })));
};
exports.Metric = Metric;
//# sourceMappingURL=metric.js.map