if (process.env.UNI_USING_V3) {
  module.exports = require('./index.v3.js')
} else {
  const postcss = require('postcss')
  const selectorParser = require('postcss-selector-parser')
  const valueParser = require('postcss-value-parser')

  const {
    parseTheme,
    getJson,
    getPlatformCssVars
  } = require('@dcloudio/uni-cli-shared')

  const CSS_TAGS = require('./tags')
  const {
    unit,
    walk
  } = valueParser

  const defaultOpts = {
    px: false
  }

  const cssVars = getPlatformCssVars()
  const pageJson = getJson('pages.json', true)

  const transformSelector = (complexSelector, transformer) => {
    return selectorParser(transformer).processSync(complexSelector)
  }

  const parseWord = function (node, opts) {
    const pair = unit(node.value)
    if (pair) {
      const num = Number(pair.number)
      let u = pair.unit.toLowerCase()
      if (u === 'px' && process.UNI_TRANSFORM_PX) { // TODO px 转换为 upx
        u = 'upx'
      }
      if (process.env.UNI_PLATFORM === 'h5') {
        if (u === 'upx' || u === 'rpx') {
          node.value = `%?${num}?%`
        }
      } else {
        if (u === 'upx') {
          node.value = num + 'rpx'
        }
        // fixed 百度目前1rpx会转换成小数点 vw，导致边框之类的显示有问题
        if (process.env.UNI_PLATFORM === 'mp-baidu') {
          if (num === 1 && (u === 'upx' || u === 'rpx')) {
            node.value = '1px'
          }
        }
      }
    }
  }

  const isInsideKeyframes = function (rule) {
    return (
      rule.parent && rule.parent.type === 'atrule' && /^(-\w+-)?keyframes$/.test(rule.parent.name)
    )
  }

  const tranformValue = function (value, opts) {
    return valueParser(value)
      .walk(node => {
        if (node.type === 'word') {
          parseWord(node, opts)
        } else if (node.type === 'function') {
          if (node.value === 'url') {
            return false
          }
          if (node.value === 'var') {
            let cssVarValue = false
            walk(node.nodes, n => {
              if (n.type === 'word') {
                if (Object.prototype.hasOwnProperty.call(cssVars, n.value)) { // 目前仅考虑 nodes 长度为0
                  cssVarValue = cssVars[n.value]
                }
              }
            })
            if (cssVarValue !== false) {
              node.type = 'word'
              node.value = cssVarValue
              delete node.before
              delete node.after
              delete node.nodes
            }
            return false
          } else {
            walk(node.nodes, n => {
              if (n.type === 'word') {
                parseWord(n, opts)
              }
            })
          }
        }
      })
      .toString()
  }

  const TAGS = [
    'ad',
    'audio',
    'button',
    'camera',
    'canvas',
    'checkbox',
    'checkbox-group',
    'cover-image',
    'cover-view',
    'editor',
    'form',
    'functional-page-navigator',
    'icon',
    'image',
    'input',
    'label',
    'live-player',
    'live-pusher',
    'map',
    'movable-area',
    'movable-view',
    'navigator',
    'official-account',
    'open-data',
    'picker',
    'picker-view',
    'picker-view-column',
    'progress',
    'radio',
    'radio-group',
    'rich-text',
    'scroll-view',
    'slider',
    'swiper',
    'swiper-item',
    'switch',
    'text',
    'textarea',
    'video',
    'view',
    'web-view'
  ]

  const BG_PROPS = [
    'background',
    'background-clip',
    'background-color',
    'background-image',
    'background-origin',
    'background-position',
    'background-repeat',
    'background-size',
    'background-attachment'
  ]

  let rewriteUrl
  /**
   * 转换 upx
   * 转换 px
   */
  const fn = function (opts) {
    opts = {
      ...defaultOpts,
      ...opts
    }
    return function (root, result) {
      if (!rewriteUrl) {
        rewriteUrl = require('@dcloudio/uni-cli-shared/lib/url-loader').rewriteUrl
      }
      rewriteUrl(root)

      if (process.env.UNI_PLATFORM === 'h5') {
        // Transform CSS AST here

        // darkmode
        if (
          process.env.VUE_APP_DARK_MODE === 'true' &&
          root.source.input.file.indexOf('App.vue') !== -1
        ) {
          const pageBGC = (pageJson.globalStyle || {}).backgroundColor || ''
          if (pageBGC.indexOf('@') === 0) {
            ['dark', 'light'].forEach(theme => {
              const { backgroundColor } = parseTheme({ backgroundColor: pageBGC }, theme)
              if (backgroundColor !== 'undefined') {
                const mediaRoot = postcss.parse(`
                  @media (prefers-color-scheme: ${theme}) {
                    body,
                    uni-page-body {
                      background-color: ${backgroundColor};
                    }
                  }
                `)
                root.nodes = [...mediaRoot.nodes, ...root.nodes]
              }
            })
          }
        }

        root.walkRules(rule => {
          let hasPage = false
          // Transform each rule here
          if (!isInsideKeyframes(rule)) {
            // rule.selectors == comma seperated selectors
            // a, b.c {} => ["a", "b.c"]
            rule.selectors = rule.selectors.map(complexSelector => {
              // complexSelector => simpleSelectors
              // "a.b#c" => ["a", ".b", "#c"]
              if (complexSelector === 'page') {
                hasPage = true
              }
              return transformSelector(complexSelector, simpleSelectors =>
                // only process type selector, leave alone class & id selectors
                simpleSelectors.walkTags(tag => {
                  if (tag.value === 'page') {
                    tag.value = 'uni-page-body'
                  } else if (~TAGS.indexOf(tag.value) && tag.value.substring(
                    0, 4) !== 'uni-') {
                    tag.value = 'uni-' + tag.value
                  }
                })
              )
            })
          }
          const bgDecls = []
          // handle upx unit
          rule.walkDecls(decl => {
            if (hasPage) {
              if (BG_PROPS.indexOf(decl.prop) !== -1) {
                bgDecls.push(decl.clone())
              }
            }
            // Transform each property declaration here
            decl.value = tranformValue(decl.value, opts)
          })

          // handle body background rule
          if (bgDecls.length) {
            const bodyRule = postcss.rule({
              selector: 'body.?%PAGE?%'
            })
            bgDecls.forEach(decl => bodyRule.append(decl))
            rule.after(bodyRule)
          }
        })

        root.walkAtRules(rule => {
          if (rule.name === 'media') {
            rule.params = tranformValue(rule.params, opts)
          }
        })
      } else {
        root.walkRules(rule => {
          const selectors = transformSelector(rule.selectors.join(','), function (selectors) {
            selectors.walkUniversals(node => {
              node.parent.remove()
            })
          })
          if (!selectors) {
            return rule.remove()
          }
          rule.selectors = selectors.split(',')

          // handle upx unit
          rule.walkDecls(decl => {
            const raws = decl.raws
            if (raws) {
              if (raws.before && raws.before.indexOf(';') !== -1) {
                raws.before = raws.before.replace(/;/g, '')
              }
              if (raws.after && raws.after.indexOf(';') !== -1) {
                raws.after = raws.after.replace(/;/g, '')
              }
            }
            // Transform each property declaration here
            decl.value = tranformValue(decl.value, opts)
          })
          if (process.env.UNI_PLATFORM !== 'quickapp-native') {
            rule.selectors = rule.selectors.map(complexSelector => {
              return transformSelector(complexSelector, simpleSelectors => {
                return simpleSelectors.walkTags(tag => {
                  const k = tag.value
                  const v = CSS_TAGS[k]
                  if (v) {
                    tag.value = v === 'r'
                      ? `._${k}` : v
                  }
                })
              })
            })
          }
        })
      }
    }
  }

  const version = Number(require('postcss/package.json').version.split('.')[0])

  if (version < 8) {
    module.exports = postcss.plugin('postcss-uniapp-plugin', fn)
  } else {
    module.exports = function (opts) {
      return {
        postcssPlugin: 'postcss-uniapp-plugin',
        Once: fn(opts)
      }
    }

    module.exports.postcss = true
  }
}
