import { isDataFrame, getProcessedDataFrames, getFieldDisplayName, FieldType } from '@grafana/data';
import { uniqWith, isEqual } from 'lodash';
import { map } from 'rxjs';

function toMetricFindValues(valueProp, textProp) {
  return (source) => source.pipe(
    map((panelData) => {
      const frames = panelData.series;
      if (!frames || !frames.length) {
        return [];
      }
      if (areMetricFindValues(frames)) {
        return frames;
      }
      if (frames[0].fields.length === 0) {
        return [];
      }
      const indices = validateIndices(findFieldsIndices(frames));
      const metrics = [];
      for (const frame of frames) {
        for (let index = 0; index < frame.length; index++) {
          const fieldValue = (fieldIndex) => fieldIndex !== -1 ? frame.fields[fieldIndex].values.get(index) : void 0;
          const value = fieldValue(indices.value);
          const text = fieldValue(indices.text);
          const expandable = fieldValue(indices.expandable);
          const properties = {};
          for (const p of indices.properties) {
            properties[p.name] = fieldValue(p.index);
          }
          const result = { value, text, properties };
          if (expandable !== void 0) {
            result.expandable = Boolean(expandable);
          }
          metrics.push(result);
        }
      }
      return metrics;
    })
  );
}
function findFieldsIndices(frames, valueProp, textProp) {
  const indices = {
    value: -1,
    text: -1,
    expandable: -1,
    properties: []
  };
  for (const frame of getProcessedDataFrames(frames)) {
    for (let index = 0; index < frame.fields.length; index++) {
      const field = frame.fields[index];
      const fieldName = getFieldDisplayName(field, frame, frames).toLowerCase();
      if (field.type === FieldType.string || field.type === FieldType.number) {
        if (fieldName === "value" && indices.value === -1) {
          indices.value = index;
        }
        indices.properties.push({ name: fieldName, index });
      }
      if (field.type === FieldType.string) {
        if (fieldName === "text" && indices.text === -1) {
          indices.text = index;
        }
        continue;
      }
      if (fieldName === "expandable" && (field.type === FieldType.boolean || field.type === FieldType.number) && indices.expandable === -1) {
        indices.expandable = index;
      }
    }
  }
  indices.properties = uniqWith(indices.properties, isEqual);
  return indices;
}
function validateIndices(indices) {
  const hasNoValueOrText = indices.value === -1 && indices.text === -1;
  if (!indices.properties.length) {
    throw new Error("Couldn't find any field of type string or number in the results");
  }
  if (hasNoValueOrText) {
    indices.value = indices.properties[0].index;
    indices.text = indices.properties[0].index;
  }
  if (indices.value === -1 && indices.text !== -1) {
    indices.value = indices.text;
  }
  if (indices.text === -1 && indices.value !== -1) {
    indices.text = indices.value;
  }
  return indices;
}
function areMetricFindValues(data) {
  if (!data) {
    return false;
  }
  if (!data.length) {
    return true;
  }
  const firstValue = data[0];
  if (isDataFrame(firstValue)) {
    return false;
  }
  for (const firstValueKey in firstValue) {
    if (!firstValue.hasOwnProperty(firstValueKey)) {
      continue;
    }
    const value = firstValue[firstValueKey];
    if (value !== null && typeof value !== "string" && typeof value !== "number") {
      continue;
    }
    const key = firstValueKey.toLowerCase();
    if (key === "text" || key === "value") {
      return true;
    }
  }
  return false;
}

export { toMetricFindValues };
//# sourceMappingURL=toMetricFindValues.js.map
