/**
 * 工具类
 */
export const setDocumentTitle = title => {
  /**
   * 修改浏览器title 兼容ios
   */
  document.title = title;
  if (window.Env.isIos) {
    const i = document.createElement('iframe');
    i.src = '/favicon.ico';
    i.style.display = 'none';
    i.onload = () => {
      setTimeout(() => {
        i.remove();
      }, 10);
    };
    setTimeout(() => {
      document.body.appendChild(i);
    }, 500);
  }
};
export const setCookie = (name, value, time) => {
  const exp = new Date();
  exp.setTime(exp.getTime() + time * 1000);
  document.cookie = `${name}=${escape(value)};expires=${exp.toGMTString()};path=/`;
};
export const getCookie = name => {
  const reg = new RegExp(`(^| )${name}=([^;]*)(;|$)`);
  const arr = reg;
  if (arr === document.cookie.match(reg)) {
    return unescape(arr[2]);
  }
  return null;
};
export const delCookie = name => {
  const exp = new Date();
  exp.setTime(exp.getTime() - 1);
  const cval = window.getCookie(name);
  if (cval != null) {
    document.cookie = `${name}=${cval};expires=${exp.toGMTString()};path=/`;
  }
};
export const getQuery = name => {
  /**
   * 获取url参数
   */
  const reg = new RegExp(`(^|\\?|&)${name}=([^&]*)(&|$)`);
  const r = window.location.href.substr(1).match(reg);
  if (r != null) return unescape(r[2]);
  return null;
};
export function formatUrl(path, query) {
  let url = query ? `${path}?` : path;
  if (query) {
    Object.keys(query).forEach(i => {
      if (query[i] instanceof Object && query[i].length > 0) {
        query[i].forEach(k => {
          url += `${i}[]=${k}&`;
        });
      } else if (query[i] || query[i] === 0) {
        url += `${i}=${query[i]}&`;
      }
    });
  }
  return url;
}
export function checkMobile(s) {
  const { length } = s;
  if (length === 11 && /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1})|(14[0-9]{1})|)+\d{8})$/.test(s)) {
    return true;
  }
  return false;
}
export function checkEmail(s) {
  if (/^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(s)) {
    return true;
  }
  return false;
}
export function loadScript(url, callback) {
  const script = document.createElement('script');
  script.type = 'text/javascript';
  script.async = true;
  script.defer = true;
  if (script.readyState) {
    script.onreadystatechange = function () {
      if (script.readyState === 'loaded' || script.readyState === 'complete') {
        script.onreadystatechange = null;
        if (callback) callback();
      }
    };
  } else {
    script.onload = function () {
      if (callback) callback();
    };
  }
  script.src = url;
  const head = document.getElementsByTagName('head')[0];
  head.appendChild(script);
}

export function uuid(len, radix) {
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
  const id = [];
  radix = radix || chars.length;
  if (len) {
    for (let i = 0; i < len; i += 1) id[i] = chars[0 | (Math.random() * radix)];
  } else {
    id[8] = id[13] = id[18] = id[23] = '-';
    id[14] = '4';
    for (let i = 0; i < 36; i += 1) {
      if (!id[i]) {
        const r = 0 | (Math.random() * 16);
        id[i] = chars[i === 19 ? (r & 0x3) | 0x8 : r];
      }
    }
  }
  return id.join('');
}

export function SortBy(a, b, asc, type) {
  if (!a && a !== 0) {
    return 1;
  }
  if (!b && b !== 0) {
    return -1;
  }
  if (a === b) {
    return 0;
  }
  if (a === '') {
    return 1;
  }
  if (b === '') {
    return -1;
  }
  a = `${a}`;
  b = `${b}`;
  return (
    (type === 'number'
      ? a.localeCompare(b, undefined, { numeric: true })
      : a.localeCompare(b, 'zh', { co: 'pinyin' })) * asc
  );
}

export function SortByProps(item1, item2, props) {
  const cps = [];
  for (let i = 0; i < props.length; i += 1) {
    const prop = props[i];
    const asc = prop.direction > 0 ? 1 : -1;
    cps.push(SortBy(item1[prop.key], item2[prop.key], asc, prop.type));
  }

  for (let j = 0; j < cps.length; j += 1) {
    if (cps[j] === 1 || cps[j] === -1) {
      return cps[j];
    }
  }
  return false;
}

export function getMap(list, key = 'value', value = null) {
  const map = {};
  for (let i = 0; i < list.length; i += 1) {
    map[list[i][key]] = value ? list[i][value] : list[i];
  }
  return map;
}

export function searchKeyword(data, key, keyword, limit) {
  const list = [];
  const tmp = {};
  for (let i = 0; i < data.length; i += 1) {
    const item = key ? data[i][key] : data[i];
    if (item && !tmp[item] && item.indexOf(keyword) >= 0) {
      list.push(item);
      tmp[item] = true;
      if (limit && list.length >= limit) break;
    }
  }
  return list;
}

export function search(data = [], key, value) {
  const index = -1;
  for (let i = 0; i < data.length; i += 1) {
    if ((key && data[i][key] === value) || data[i] === value) {
      return i;
    }
  }
  return index;
}

export function formatSecond(value) {
  let secondTime = parseInt(value, 10); // 秒
  let minuteTime = 0;
  let hourTime = 0;
  if (secondTime > 60) {
    minuteTime = parseInt(secondTime / 60, 10);
    secondTime = parseInt(secondTime % 60, 10);
    hourTime = parseInt(minuteTime / 60, 10);
    minuteTime = parseInt(minuteTime % 60, 10);
  }
  if (hourTime >= 10) {
    hourTime = `${hourTime}`;
  } else {
    hourTime = `0${hourTime}`;
  }
  if (minuteTime >= 10) {
    minuteTime = `${minuteTime}`;
  } else {
    minuteTime = `0${minuteTime}`;
  }
  if (secondTime >= 10) {
    secondTime = `${secondTime}`;
  } else {
    secondTime = `0${secondTime}`;
  }
  return `${hourTime}:${minuteTime}:${secondTime}`;
}

export function formatFormError(data, err, prefix = '') {
  const r = {};
  Object.keys(err).forEach(field => {
    r[`${prefix}${field}`] = { value: data[field], errors: err[field].map(e => new Error(e)) };
  });
  return r;
}

export function formatDate(time, format = 'YYYY-MM-DD HH:mm:ss') {
  const date = new Date(time);
  const o = {
    'M+': date.getMonth() + 1,
    'D+': date.getDate(),
    'H+': date.getHours(),
    'm+': date.getMinutes(),
    's+': date.getSeconds(),
    'q+': Math.floor((date.getMonth() + 3) / 3),
    S: date.getMilliseconds(),
  };
  if (/(y+)/.test(format)) format = format.replace(RegExp.$1, `${date.getFullYear()}`.substr(4 - RegExp.$1.length));
  Object.keys(o).forEach(k => {
    if (new RegExp(`('${k}')`).test(format)) {
      format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : `00${o[k]}`.substr(`${o[k]}`.length));
    }
  });
  return format;
}

export function formatPercent(child, mother) {
  if (!mother || !child) return '0%';
  return `${Math.floor((child * 100) / mother)}%`;
}

export function formatTreeData(list, key = 'id', title = 'title', index = 'parent_id') {
  const map = getMap(list, key);
  const result = [];
  list.forEach(row => {
    row.children = [];
    row.title = row[title];
    row.key = `${row[key]}`;
    row.value = row[key];
  });
  list.forEach(row => {
    if (row[index] && map[row[index]]) {
      if (!map[row[index]].children) map[row[index]].children = [];
      map[row[index]].children.push(row);
    } else {
      result.push(row);
    }
  });
  return result;
}

export function flattenObject(ob, prefix = '') {
  const toReturn = {};
  if (prefix) prefix = `${prefix}.`;
  Object.keys(ob).forEach(i => {
    if (typeof ob[i] === 'object' && ob[i] !== null) {
      const flatObject = flattenObject(ob[i]);
      Object.keys(flatObject).forEach(x => {
        toReturn[`${prefix}${i}.${x}`] = flatObject[x];
      });
    } else {
      toReturn[`${prefix}${i}`] = ob[i];
    }
  });
  return toReturn;
}

function _formatMoney(s, n) {
  if (!s) s = 0;
  n = n > 0 && n <= 20 ? n : 2;
  s = `${parseFloat(`${s}`.replace(/[^\d.-]/g, '')).toFixed(n)}`;
  const l = s
    .split('.')[0]
    .split('')
    .reverse();
  const r = s.split('.')[1];
  let t = '';
  for (let i = 0; i < l.length; i += 1) {
    t += l[i] + ((i + 1) % 3 === 0 && i + 1 !== l.length ? ',' : '');
  }
  return `${t
    .split('')
    .reverse()
    .join('')}.${r}`;
}

export function formatMoney(price) {
  if (typeof price === 'object') {
    return `${price.symbol}${_formatMoney(price.value, 2)}`;
  }
  return `¥${_formatMoney(price, 2)}`;
}

export function bindTags(targetList, field, render, def, notFound) {
  let index = -1;
  targetList.forEach((row, i) => {
    if (row.key === field) index = i;
  });
  targetList[index].notFoundContent = notFound;
  targetList[index].select = (def || []).map(row => {
    return render(row);
  });
}

export function bindSearch(targetList, field, Component, listFunc, render, def, notFound) {
  let index = -1;
  targetList.forEach((row, i) => {
    if (row.key === field) index = i;
  });
  const key = `lastFetchId${field}${index}`;
  if (!Component[key]) Component[key] = 0;
  const searchFunc = (data) => {
    Component[key] += 1;
    const fetchId = Component[key];
    Component.setState({ fetching: true });
    listFunc(data).then(result => {
      if (fetchId !== Component[key]) {
        // for fetch callback order
        return;
      }
      targetList[index].select = (result.list || result || []).map(row => {
        return render(row);
      });
      Component.setState({ fetching: false });
    });
  };
  const item = {
    showSearch: true,
    showArrow: true,
    filterOption: false,
    onSearch: keyword => {
      searchFunc({ page: 1, number: 5, keyword });
    },
    notFoundContent: notFound,
  };
  targetList[index] = Object.assign(targetList[index], item);
  if (def) {
    searchFunc({ ids: def, page: 1, number: def.length });
  } else {
    item.onSearch();
  }
}

export function generateSearch(field, prop, Component, listFunc, render, def, notFound) {
  const key = `lastFetchId${field}`;
  if (!Component[key]) Component[key] = 0;
  let item = {
    showSearch: true,
    showArrow: true,
    filterOption: false,
    notFoundContent: notFound,
  };
  const searchFunc = (data) => {
    Component[key] += 1;
    const fetchId = Component[key];
    Component.setState({ fetching: true });
    listFunc(data).then(result => {
      if (fetchId !== Component[key]) {
        // for fetch callback order
        return;
      }
      item.select = result.list.map(row => {
        return render(row);
      });
      Component.setState({ [field]: prop, fetching: false });
    });
  };
  item.onSearch = (keyword) => {
    searchFunc({ page: 1, number: 5, keyword });
  };
  item = Object.assign(prop || {}, item);
  if (def) {
    searchFunc({ ids: def, page: 1, number: def.length });
  } else {
    item.onSearch();
  }
  Component.setState({ [field]: prop });
}
