import React, { Component, Fragment } from 'react'
import PropTypes from 'prop-types'
import { connect } from "react-redux";
import { subscribeUserToPushRequest } from '../../actions/user'
import getConfig from 'next/config'


import { urlB64ToUint8Array, payloadFromSubscription } from './Utility'

var swRegistration = null

const WebPushContext = React.createContext()

function WebPushConsumer(props) {
  return (
    <WebPushContext.Consumer {...props}>
      {context => {
        if (!context) {
          throw new Error(
            `Webpush.Consumer cannot be rendered outside the Webpush component`,
          )
        }
        return props.children(context)
      }}
    </WebPushContext.Consumer>
  )
}

const { publicRuntimeConfig } = getConfig()
class WebPush extends Component {
  static Consumer = WebPushConsumer;

  state = {
    on: false,
  }

  constructor(props) {
    super(props)
  }

  componentDidMount() {
    if (swRegistration === null) {
      this.onRegisterServiceWorker()
    }
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    console.log("isUserSubscribedToPush ::: " + nextProps.isUserSubscribedToPush);
    if (this.props.subscriveUserEnabled != nextProps.subscriveUserEnabled && nextProps.subscriveUserEnabled) {
      this.onSubscribeUser()
    }
    if (!!nextProps.isUserSubscribedToPush) {
      this.setState({ on: true })
    }
  }


  onUpdateSubscriptionOnServer = (subscription) => {
    console.log("onUpdateSubscriptionOnServer:", subscription)
    var payload = payloadFromSubscription(subscription)
    console.log("payload:", JSON.stringify(payload))
    this.setState({ subscription: subscription })

    this.props.subscribeUserToPushRequest(payload);

    this.setState(({ on }) => ({ on: !on }))
  }

  onSubscriptionFailed = (error) => {
    console.log("onSubscriptionFailed:", error)
    this.setState(({ on }) => ({ on: false }))
  }

  toggleSubscription = () => {
    console.log(this.state.on)
    if (!this.state.on) {
      this.onSubscribeUser()
    }
    else {
      this.onUnSubscribeUser()
    }
  }

  onSubscribeUser = () => {
    if (swRegistration == null) {
      return
    }

    swRegistration.pushManager.getSubscription()
      .then((subscription) => {
        var isSubscribed = !(subscription === null)
        if (isSubscribed) {
          this.onUpdateSubscriptionOnServer(subscription)
        } else {
          const applicationServerKey = urlB64ToUint8Array(publicRuntimeConfig.applicationServerPublicKey)
          swRegistration.pushManager.subscribe({
            userVisibleOnly: true,
            applicationServerKey: applicationServerKey
          })
            .then((subscription) => {
              console.log('User is subscribed.')
              if (this.onUpdateSubscriptionOnServer) {
                this.onUpdateSubscriptionOnServer(subscription)
              }
            })
            .catch((err) => {
              console.log('Failed to subscribe the user: ', err)
              if (onSubscribeFailed) {
                this.onSubscriptionFailed(err)
              }
            });
        }
      })
  }

  onUnSubscribeUser = () => {
    swRegistration.pushManager.getSubscription()

      .then((subscription) => {
        if (subscription) {

          return subscription.unsubscribe();
        }
      })
      .then(() =>
        this.setState(({ on }) => ({ on: false })))
      //TODO: facultatif update DB
      // .then(() => {
      //   return fetch(//, {
      //     method: 'POST',
      //     headers: {
      //       'Content-Type': 'application/json'
      //     },
      //     body: JSON.stringify(subscription)
      //   })
      //     .then((response) => {
      //       if (!response.ok) {
      //         throw new Error('Bad status code from server.');
      //       }
      //       ///TODO bind UI
      //       return true;
      //     })

      // })
      .catch((err) => {
        console.error('Failed to unsubscribe the user.', err);

      });
  }

  onRegisterServiceWorker = () => {
    navigator.serviceWorker.register('/static/js/Edeclic-service-worker.js')
      .then(function (swReg) {
        console.info('Service Worker is registered', swReg);

        swRegistration = swReg;
      })
  }

  render() {
    return (<WebPushContext.Provider
      value={{ on: this.state.on, toggleSubscription: this.toggleSubscription }}
      {...this.props}
    />)
  }
}

WebPush.propTypes = {
}

function mapStateToProps(state) {
  return {
    isUserSubscribedToPush: state.user.isUserSubscribedToPush
  };
}

export default connect(mapStateToProps, { subscribeUserToPushRequest })(WebPush);
