import curry from 'ramda/src/curry'
import { html2json } from 'wechat_common/wxParse/html2json'
import { getProductList } from 'root/selectors/presentation/productSelector'
import { getStatusByPath } from 'wechat_common/selectors/entityStatusSelector'
import { iconPath } from 'root/constants/presentation/iconPath'
import moment from 'wechat_common/lib/moment'

const DAYS = [1, 7, 30, 90]
const DATE_TYPE = 'YYYY-MM-DD'
const RENDER_COLOR = ['#B6628E', '#CE605D', '#66B67A', '#DCBD73', '#5E77AF']

export function getCacheTime(duration) {
  return new Date().getTime() + duration
}

export function getQnUrl(image, options) {
  if (!image) {
    return null
  }
  if (image.url && image.url !== '!') {
    return image.url
  }
  if (image.storageKey && image.storageKey.charAt(0) === '/') {
    image.storageKey = image.storageKey.slice(1)
  }
  const _options = options
    ? options
    : `imageMogr2/strip/thumbnail/1200x9000>/format/${image.format}`

  if (NODE_ENV !== 'production') {
    return `https://okzg4jwn8.qnssl.com/${image.storageKey}?${_options}`
  }

  return `https://user-assets.sxlcdn.com/${image.storageKey}?${_options}`
}

export function formatProtocol(url) {
  let _url = url
  if (!url) {
    return 'https://assets.sxlcdn.com/images/ecommerce/ecommerce-default-image.png'
  }
  if (typeof url === 'object') {
    _url = getQnUrl(url)
  }
  _url = _url.replace('http:', '').replace('https:', '')
  return `https:${_url}`
}

export function formatFactory(method, key = 'url') {
  let assertError = ''
  if (typeof method !== 'function') {
    assertError = new TypeError(
      `method pass into formatFactory must be a function, but get ${typeof method}`,
    )
  }
  return function(obj) {
    if (assertError) {
      throw assertError
    }

    return Object.assign({}, obj, {
      [key]: method(obj[key]),
    })
  }
}

export function caculateShortcuts(shortcuts) {
  let shortcutsFirstLine
  let shortcutsSecondLine
  let shortcutsSecondLineWrapperClass
  if (shortcuts && shortcuts.length > 5) {
    const center = Math.ceil(shortcuts.length / 2)
    shortcutsFirstLine = shortcuts.slice(0, center)
    shortcutsSecondLine = shortcuts.slice(center)

    const firstLineLength = shortcutsFirstLine.length
    const secondLineLength = shortcutsSecondLine.length
    if (firstLineLength !== secondLineLength) {
      if (secondLineLength === 3) {
        shortcutsSecondLineWrapperClass = 'shortcut-placeholder-junior'
      } else if (secondLineLength === 4) {
        shortcutsSecondLineWrapperClass = 'shortcut-placeholder-senior'
      }
    } else {
      shortcutsSecondLineWrapperClass = ' '
    }
  } else {
    shortcutsFirstLine = []
    shortcutsSecondLine = []
    shortcutsSecondLineWrapperClass = ' '
  }
  return [
    shortcutsFirstLine,
    shortcutsSecondLine,
    shortcutsSecondLineWrapperClass,
  ]
}

function strNumDiscode(str) {
  str = str.replace(/&forall;/g, '∀')
  str = str.replace(/&part;/g, '∂')
  str = str.replace(/&exists;/g, '∃')
  str = str.replace(/&empty;/g, '∅')
  str = str.replace(/&nabla;/g, '∇')
  str = str.replace(/&isin;/g, '∈')
  str = str.replace(/&notin;/g, '∉')
  str = str.replace(/&ni;/g, '∋')
  str = str.replace(/&prod;/g, '∏')
  str = str.replace(/&sum;/g, '∑')
  str = str.replace(/&minus;/g, '−')
  str = str.replace(/&lowast;/g, '∗')
  str = str.replace(/&radic;/g, '√')
  str = str.replace(/&prop;/g, '∝')
  str = str.replace(/&infin;/g, '∞')
  str = str.replace(/&ang;/g, '∠')
  str = str.replace(/&and;/g, '∧')
  str = str.replace(/&or;/g, '∨')
  str = str.replace(/&cap;/g, '∩')
  str = str.replace(/&cap;/g, '∪')
  str = str.replace(/&int;/g, '∫')
  str = str.replace(/&there4;/g, '∴')
  str = str.replace(/&sim;/g, '∼')
  str = str.replace(/&cong;/g, '≅')
  str = str.replace(/&asymp;/g, '≈')
  str = str.replace(/&ne;/g, '≠')
  str = str.replace(/&le;/g, '≤')
  str = str.replace(/&ge;/g, '≥')
  str = str.replace(/&sub;/g, '⊂')
  str = str.replace(/&sup;/g, '⊃')
  str = str.replace(/&nsub;/g, '⊄')
  str = str.replace(/&sube;/g, '⊆')
  str = str.replace(/&supe;/g, '⊇')
  str = str.replace(/&oplus;/g, '⊕')
  str = str.replace(/&otimes;/g, '⊗')
  str = str.replace(/&perp;/g, '⊥')
  str = str.replace(/&sdot;/g, '⋅')
  return str
}

// HTML 支持的希腊字母
function strGreeceDiscode(str) {
  str = str.replace(/&Alpha;/g, 'Α')
  str = str.replace(/&Beta;/g, 'Β')
  str = str.replace(/&Gamma;/g, 'Γ')
  str = str.replace(/&Delta;/g, 'Δ')
  str = str.replace(/&Epsilon;/g, 'Ε')
  str = str.replace(/&Zeta;/g, 'Ζ')
  str = str.replace(/&Eta;/g, 'Η')
  str = str.replace(/&Theta;/g, 'Θ')
  str = str.replace(/&Iota;/g, 'Ι')
  str = str.replace(/&Kappa;/g, 'Κ')
  str = str.replace(/&Lambda;/g, 'Λ')
  str = str.replace(/&Mu;/g, 'Μ')
  str = str.replace(/&Nu;/g, 'Ν')
  str = str.replace(/&Xi;/g, 'Ν')
  str = str.replace(/&Omicron;/g, 'Ο')
  str = str.replace(/&Pi;/g, 'Π')
  str = str.replace(/&Rho;/g, 'Ρ')
  str = str.replace(/&Sigma;/g, 'Σ')
  str = str.replace(/&Tau;/g, 'Τ')
  str = str.replace(/&Upsilon;/g, 'Υ')
  str = str.replace(/&Phi;/g, 'Φ')
  str = str.replace(/&Chi;/g, 'Χ')
  str = str.replace(/&Psi;/g, 'Ψ')
  str = str.replace(/&Omega;/g, 'Ω')

  str = str.replace(/&alpha;/g, 'α')
  str = str.replace(/&beta;/g, 'β')
  str = str.replace(/&gamma;/g, 'γ')
  str = str.replace(/&delta;/g, 'δ')
  str = str.replace(/&epsilon;/g, 'ε')
  str = str.replace(/&zeta;/g, 'ζ')
  str = str.replace(/&eta;/g, 'η')
  str = str.replace(/&theta;/g, 'θ')
  str = str.replace(/&iota;/g, 'ι')
  str = str.replace(/&kappa;/g, 'κ')
  str = str.replace(/&lambda;/g, 'λ')
  str = str.replace(/&mu;/g, 'μ')
  str = str.replace(/&nu;/g, 'ν')
  str = str.replace(/&xi;/g, 'ξ')
  str = str.replace(/&omicron;/g, 'ο')
  str = str.replace(/&pi;/g, 'π')
  str = str.replace(/&rho;/g, 'ρ')
  str = str.replace(/&sigmaf;/g, 'ς')
  str = str.replace(/&sigma;/g, 'σ')
  str = str.replace(/&tau;/g, 'τ')
  str = str.replace(/&upsilon;/g, 'υ')
  str = str.replace(/&phi;/g, 'φ')
  str = str.replace(/&chi;/g, 'χ')
  str = str.replace(/&psi;/g, 'ψ')
  str = str.replace(/&omega;/g, 'ω')
  str = str.replace(/&thetasym;/g, 'ϑ')
  str = str.replace(/&upsih;/g, 'ϒ')
  str = str.replace(/&piv;/g, 'ϖ')
  str = str.replace(/&middot;/g, '·')
  return str
}

function strcharacterDiscode(str) {
  // 加入常用解析
  str = str.replace(/&nbsp;&nbsp;/g, ' ')
  str = str.replace(/&yen;/g, '¥')
  str = str.replace(/&quot;/g, "'")
  str = str.replace(/&amp;/g, '&')
  // str = str.replace(/&lt;/g, '‹');
  // str = str.replace(/&gt;/g, '›');

  str = str.replace(/&lt;/g, '<')
  str = str.replace(/&gt;/g, '>')
  str = str.replace(/&#8226;/g, '•')

  return str
}

// HTML 支持的其他实体
function strOtherDiscode(str) {
  str = str.replace(/&OElig;/g, 'Œ')
  str = str.replace(/&oelig;/g, 'œ')
  str = str.replace(/&Scaron;/g, 'Š')
  str = str.replace(/&scaron;/g, 'š')
  str = str.replace(/&Yuml;/g, 'Ÿ')
  str = str.replace(/&fnof;/g, 'ƒ')
  str = str.replace(/&circ;/g, 'ˆ')
  str = str.replace(/&tilde;/g, '˜')
  str = str.replace(/&ensp;/g, '')
  str = str.replace(/&emsp;/g, '')
  str = str.replace(/&thinsp;/g, '')
  str = str.replace(/&zwnj;/g, '')
  str = str.replace(/&zwj;/g, '')
  str = str.replace(/&lrm;/g, '')
  str = str.replace(/&rlm;/g, '')
  str = str.replace(/&ndash;/g, '–')
  str = str.replace(/&mdash;/g, '—')
  str = str.replace(/&lsquo;/g, '‘')
  str = str.replace(/&rsquo;/g, '’')
  str = str.replace(/&sbquo;/g, '‚')
  str = str.replace(/&ldquo;/g, '“')
  str = str.replace(/&rdquo;/g, '”')
  str = str.replace(/&bdquo;/g, '„')
  str = str.replace(/&dagger;/g, '†')
  str = str.replace(/&Dagger;/g, '‡')
  str = str.replace(/&bull;/g, '•')
  str = str.replace(/&hellip;/g, '…')
  str = str.replace(/&permil;/g, '‰')
  str = str.replace(/&prime;/g, '′')
  str = str.replace(/&Prime;/g, '″')
  str = str.replace(/&lsaquo;/g, '‹')
  str = str.replace(/&rsaquo;/g, '›')
  str = str.replace(/&oline;/g, '‾')
  str = str.replace(/&euro;/g, '€')
  str = str.replace(/&trade;/g, '™')

  str = str.replace(/&larr;/g, '←')
  str = str.replace(/&uarr;/g, '↑')
  str = str.replace(/&rarr;/g, '→')
  str = str.replace(/&darr;/g, '↓')
  str = str.replace(/&harr;/g, '↔')
  str = str.replace(/&crarr;/g, '↵')
  str = str.replace(/&lceil;/g, '⌈')
  str = str.replace(/&rceil;/g, '⌉')

  str = str.replace(/&lfloor;/g, '⌊')
  str = str.replace(/&rfloor;/g, '⌋')
  str = str.replace(/&loz;/g, '◊')
  str = str.replace(/&spades;/g, '♠')
  str = str.replace(/&clubs;/g, '♣')
  str = str.replace(/&hearts;/g, '♥')

  str = str.replace(/&diams;/g, '♦')
  str = str.replace(/&#39;/g, "'")
  return str
}

export function generateEditorContentHTML(items) {
  return items
    .map(item => {
      if (item.type === 'Image') {
        return `<img
                  src="${getQnUrl(item)}"
                  width="${item.w}"
                  height="${item.h}" />`
      } else if (item.type === 'RichText') {
        return `<p>${item.value}</p>`
      } else if (item.type === 'Video') {
        const attrs = Object.entries(item)
          .map(([key, value]) => `${key}="${value}"`)
          .join(' ')
        return `<video ${attrs}></video>`
      }
    })
    .join('')
}

export function parseString(str) {
  str = strNumDiscode(str)
  str = strGreeceDiscode(str)
  str = strcharacterDiscode(str)
  str = strOtherDiscode(str)
  return str
}

export function sortWithOrder(orderList = {}) {
  return function(a, b) {
    const aIndex = orderList[a.id] || -a.id
    const bIndex = orderList[b.id] || -b.id
    return aIndex - bIndex
  }
}

export const sortWithOrderList = curry((orderList, data) => {
  data.sort((a, b) => {
    const aIndex = orderList[a.id] || -a.id
    const bIndex = orderList[b.id] || -b.id
    return aIndex - bIndex
  })
  return data
})

export const checkProtocol = product => {
  if (product.picture.length > 0) {
    product.picture[0].thumbnailUrl = formatProtocol(
      product.picture[0].thumbnailUrl,
    )
  } else {
    product.picture = [
      {
        thumbnailUrl: formatProtocol(),
      },
    ]
  }
  return product
}

export const matchNameInProduct = (productList, name) =>
  productList.filter(product => (product.categories || []).includes(name))

export const convertProductDetailData = product => {
  if (product.detailEnabled && product.detail) {
    const { items } = product.detail
    if (items) {
      const parsedHtml = generateEditorContentHTML(items)
      const contentTemp = parsedHtml.replace(
        /&nbsp;/g,
        '<em class="dump">z</em>',
      )
      const content = html2json(parseString(contentTemp))
      product.detail.content = content
      product.detailNodes = content.nodes
    }
  }

  return product
}

export const getFirstProduct = products => {
  const state = wx.store.getState()
  const { ids } = getStatusByPath(state, ['product', 'category', 'all'])
  const productList = getProductList(state, ids)
  if (productList && productList.length > 0) {
    return productList[0]
  } else {
    return null
  }
}

// there is no route in the return of getCurrentPages in wept
// so using pageName to predicate current page
export const isInProductsPage = () =>
  getCurrentPages().pop().data.pageName === 'productIndex'

// there is no route in the return of getCurrentPages in wept
// so using pageName to predicate current page
export const isInProductDetailPage = () =>
  getCurrentPages().pop().data.pageName === 'productDetail'

export function getTeamMemberAvatar(image) {
  if (!image) {
    return `${iconPath.DEFAULT_AVATAR}&random=${Math.random()}`
  }

  return getQnUrl(image, `imageView2/1/w/300/h/400/format/${image.format}`)
}

export function getRoundTeamMemberAvatar(image) {
  if (!image) {
    return `${iconPath.DEFAULT_ROUND_AVATAR}&random=${Math.random()}`
  }

  return getQnUrl(
    image,
    `imageView2/1/w/300/h/300/format/${image.format}|roundPic/radius/!50p`,
  )
}

export function getRoundImage(imageUrl) {
  return `${imageUrl}|roundPic/radius/!50p`
}

export function replaceWithDownloadFileDomain(url) {
  return url && url.replace('nzr2ybsda.qnssl.com', 'user-assets.sxlcdn.com')
}

export const getPeriodTimeByNumber = days => {
  const startDate = moment()
    .add(-days, 'days')
    .format(DATE_TYPE)
  const endDate = moment().format(DATE_TYPE)
  return {
    startDate,
    endDate,
  }
}

export const formatChartsData = charts => {
  let expandedCharts = []
  if (charts.length > 0) {
    expandedCharts = charts.map((item, index) => {
      item.data = parseFloat(item.data) || 0
      item.stroke = true
      item.color = RENDER_COLOR[index]
      return item
    })
  }
  return expandedCharts
}

export const formatGroupChartData = chartsData => {
  const { groupArticleAnalytics, groupProductAnalytics } = chartsData
  const articleCharts = formatChartsData(groupArticleAnalytics)
  const productCharts = formatChartsData(groupProductAnalytics)
  return {
    groupArticleAnalytics: articleCharts,
    groupProductAnalytics: productCharts,
  }
}

export const filterEnableChartList = chartsList => {
  const enableRenderChartList = []
  if (chartsList.length) {
    chartsList.forEach(item => {
      if (item.series && item.series.length > 0) {
        enableRenderChartList.push(item)
      }
    })
  }
  return enableRenderChartList
}

export const getDaysByTabStatus = tabStatus => {
  let days
  switch (tabStatus) {
    case 'yesterday':
      days = DAYS[0]
      break
    case '7days':
      days = DAYS[1]
      break
    case '30days':
      days = DAYS[2]
      break
    case '90days':
      days = DAYS[3]
      break
    default:
  }
  return days
}
