import _isString from 'lodash/isString';
import _isArray from 'lodash/isArray';
import _isPlainObject from 'lodash/isPlainObject';

export function arrayToHexString(byteArray) {
  return byteArray.reduce((output, elem) => output + ('0' + elem.toString(16)).slice(-2), '').toUpperCase();
}

export function hexStringToArray(inputString) {
  var hex = inputString.toString();
  var res = [];
  for (var n = 0; n < hex.length; n += 2) {
    res.push(parseInt(hex.substr(n, 2), 16));
  }
  return res;
}

export function parseCellValue(value) {
  if (!_isString(value)) return value;

  if (value == '(NULL)') return null;

  const mHex = value.match(/^0x([0-9a-fA-F][0-9a-fA-F])+$/);
  if (mHex) {
    return {
      type: 'Buffer',
      data: hexStringToArray(value.substring(2)),
    };
  }

  const mOid = value.match(/^ObjectId\("([0-9a-f]{24})"\)$/);
  if (mOid) {
    return { $oid: mOid[1] };
  }

  return value;
}

export function stringifyCellValue(value) {
  if (value === null) return '(NULL)';
  if (value === undefined) return '(NoField)';
  if (value?.type == 'Buffer' && _isArray(value.data)) return '0x' + arrayToHexString(value.data);
  if (value?.$oid) return `ObjectId("${value?.$oid}")`;
  if (_isPlainObject(value) || _isArray(value)) return JSON.stringify(value);
  return value;
}

export function safeJsonParse(json, defaultValue?, logError = false) {
  if (_isArray(json) || _isPlainObject(json)) {
    return json;
  }
  try {
    return JSON.parse(json);
  } catch (err) {
    if (logError) {
      console.error(`Error parsing JSON value "${json}"`, err);
    }
    return defaultValue;
  }
}

export function isJsonLikeLongString(value) {
  return _isString(value) && value.length > 100 && value.match(/^\s*\{.*\}\s*$|^\s*\[.*\]\s*$/);
}

export function getIconForRedisType(type) {
  switch (type) {
    case 'dir':
      return 'img folder';
    case 'string':
      return 'img type-string';
    case 'hash':
      return 'img type-hash';
    case 'set':
      return 'img type-set';
    case 'list':
      return 'img type-list';
    case 'zset':
      return 'img type-zset';
    case 'stream':
      return 'img type-stream';
    case 'binary':
      return 'img type-binary';
    case 'ReJSON-RL':
      return 'img type-rejson';
    default:
      return null;
  }
}

export function isWktGeometry(s) {
  if (!_isString(s)) return false;

  // return !!s.match(/^POINT\s*\(|/)
  return !!s.match(
    /^POINT\s*\(|^LINESTRING\s*\(|^POLYGON\s*\(|^MULTIPOINT\s*\(|^MULTILINESTRING\s*\(|^MULTIPOLYGON\s*\(|^GEOMCOLLECTION\s*\(|^GEOMETRYCOLLECTION\s*\(/
  );
}

export function arrayBufferToBase64(buffer) {
  var binary = '';
  var bytes = [].slice.call(new Uint8Array(buffer));
  bytes.forEach(b => (binary += String.fromCharCode(b)));
  return btoa(binary);
}

export function getAsImageSrc(obj) {
  if (obj?.type == 'Buffer' && _isArray(obj?.data)) {
    return `data:image/png;base64, ${arrayBufferToBase64(obj?.data)}`;
  }

  if (_isString(obj) && (obj.startsWith('http://') || obj.startsWith('https://'))) {
    return obj;
  }

  return null;
}

export function parseSqlDefaultValue(value: string) {
  if (!value) return undefined;
  if (!_isString(value)) return undefined;
  if (value.startsWith("'") && value.endsWith("'")) {
    return value.slice(1, -1);
  }
  if (!isNaN(value as any) && !isNaN(parseFloat(value))) {
    return parseFloat(value);
  }
  return undefined;
}
