import {Component} from 'react'
import render from './render'

const update = typeof window === 'undefined' ? doRender : updateOnClient
let components = []
let updatePromise

// includes desktop and iOS, based on
// https://github.com/DamonOehlman/detect-browser/blob/master/lib/detectBrowser.js
const isSafari = typeof window === 'undefined' ?
  false : /Version\/[0-9._]+.*Safari/.test(window.navigator.userAgent)

export default class extends Component {
  componentWillMount() {
    mount(this)
  }

  componentWillUpdate() {
    update()
  }

  componentWillUnmount() {
    unmount(this)
  }

  render() {
    return null
  }
}

export function flush() {
  const ret = {}

  for (const {props} of components) {
    ret[props.styleId] = props.css
  }

  components = []

  return ret
}

function mount(component) {
  components.push(component)
  update()
}

function unmount(component) {
  const i = components.indexOf(component)
  if (i < 0) {
    return
  }

  components.splice(i, 1)
  update()
}

function updateOnClient() {
  if (isSafari) {
    // debouncing causes FOUC in Safari
    doRender()
    return
  }

  // Debounce calls and only render once the latest promise resolves.
  // Promise#then() ensures micro task enqueuing of styles update before paint.
  const promise = updatePromise = Promise.resolve().then(() => {
    if (promise === updatePromise) {
      updatePromise = null
      doRender()
    }
  })
}

function doRender() {
  render(components)
}

@@ -60,360 +60,27 @@
 r'%0A%0A
-const update = typeof window === 'undefined' ? doRender : updateOnClient%0Alet components = %5B%5D%0Alet updatePromise%0A%0A// includes desktop and iOS, based on%0A// https://github.com/DamonOehlman/detect-browser/blob/master/lib/detectBrowser.js%0Aconst isSafari = typeof window === 'undefined' ?%0A  false : /Version%5C/%5B0-9._%5D+.*Safari/.test(window.navigator.userAgent)
+let components = %5B%5D
 %0A%0Aex
@@ -684,437 +684,8 @@
 date
-OnClient() %7B%0A  if (isSafari) %7B%0A    // debouncing causes FOUC in Safari%0A    doRender()%0A    return%0A  %7D%0A%0A  // Debounce calls and only render once the latest promise resolves.%0A  // Promise#then() ensures micro task enqueuing of styles update before paint.%0A  const promise = updatePromise = Promise.resolve().then(() =%3E %7B%0A    if (promise === updatePromise) %7B%0A      updatePromise = null%0A      doRender()%0A    %7D%0A  %7D)%0A%7D%0A%0Afunction doRender
 () %7B

Remove batched styles updates (#139)