import React, { Fragment } from 'react';
import { NextAuth } from 'next-auth/client'
import Layout from '../components/MyLayout.js'
import withStyles from '@material-ui/core/styles/withStyles';
import Paper from '@material-ui/core/Paper';
import Stepper from '@material-ui/core/Stepper';
import Step from '@material-ui/core/Step';
import StepLabel from '@material-ui/core/StepLabel';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import PushParamForm from '../components/push/PushParamForm';
import PushReview from '../components/push/PushReview';
import PushTargetForm from '../components/push/PushTargetForm';
import CircularProgress from '@material-ui/core/CircularProgress';
import axios from 'axios'
import getConfig from 'next/config'
import green from '@material-ui/core/colors/green';
import orange from '@material-ui/core/colors/orange';
import Snackbar from '@material-ui/core/Snackbar';
import SnackbarContent from '@material-ui/core/SnackbarContent';
import dynamic from 'next/dynamic'
import Link from 'next/link'
import Cookies from 'universal-cookie'
import Router from 'next/router'

const styles = theme => ({
    appBar: {
        position: 'relative',
    },
    layout: {
        width: 'auto',
        marginLeft: theme.spacing.unit * 2,
        marginRight: theme.spacing.unit * 2,
        [theme.breakpoints.up(600 + theme.spacing.unit * 2 * 2)]: {
            width: 600,
            marginLeft: 'auto',
            marginRight: 'auto',
        },
    },
    paper: {
        marginTop: theme.spacing.unit * 3,
        marginBottom: theme.spacing.unit * 3,
        padding: theme.spacing.unit * 2,
        [theme.breakpoints.up(600 + theme.spacing.unit * 3 * 2)]: {
            marginTop: theme.spacing.unit * 6,
            marginBottom: theme.spacing.unit * 6,
            padding: theme.spacing.unit * 3,
        },
    },
    stepper: {
        padding: `${theme.spacing.unit * 3}px 0 ${theme.spacing.unit * 5}px`,
    },
    buttons: {
        display: 'flex',
        justifyContent: 'flex-end',
    },
    button: {
        marginTop: theme.spacing.unit * 3,
        marginLeft: theme.spacing.unit,
    },
});


const { publicRuntimeConfig } = getConfig()

let back = ''
const steps = ['Parameters', 'Target', 'Review'];

class PushCreator extends React.Component {
    state = {
        session: this.props.session,
        isSignedIn: (this.props.session.user) ? true : false,
        activeStep: 0,
        title: '',
        body: '',
        action: publicRuntimeConfig.push.defaultAction,
        iconLink: publicRuntimeConfig.push.defaultIconLink,
        imageLink: publicRuntimeConfig.push.defaultImageLink,
        target: 'a',
        topic: '',
        loading: false,
        openSnack: false,
        error: false,
        warning: false,
        success: false,
        snackMessage: ""
    };

    static async getInitialProps({ req }) {
        let props = {};

        props.session = await NextAuth.init({ req })

        return props
    }

    constructor(props) {
        super(props);
    }
    async componentDidMount() {

    }

    getStepContent = (step) => {
        switch (step) {
            case 0:
                return <PushParamForm
                    onSelectedTitle={this.setTitle}
                    onSelectedBody={this.setBody}
                    onSelectedAction={this.setAction}
                    onSelectedImageLink={this.setImageLink}
                    onSelectedIconLink={this.setIconLink}
                    title={this.state.title}
                    body={this.state.body}
                    action={this.state.action}
                    imageLink={this.state.imageLink}
                    iconLink={this.state.iconLink}
                />;
            case 1:
                return <PushTargetForm
                    onSelectedTarget={this.setTarget}
                    onSelectedTopic={this.setTopic}
                    target={this.state.target}
                    topic={this.state.topic} />;
            case 2:
                return <PushReview
                    title={this.state.title}
                    body={this.state.body}
                    action={this.state.action}
                    imageLink={this.state.imageLink}
                    iconLink={this.state.iconLink}
                    target={this.state.target} />;
            default:
                throw new Error('Unknown step');
        }
    }

    setTitle = (title) => {
        this.setState(state => ({
            title
        }));
    }

    setBody = (body) => {
        this.setState(state => ({
            body
        }));
    }

    setAction = (action) => {
        this.setState(state => ({
            action
        }));
    }
    setImageLink = (imageLink) => {
        this.setState(state => ({
            imageLink
        }));
    }
    setIconLink = (iconLink) => {
        this.setState(state => ({
            iconLink
        }));
    }
    setTarget = (target) => {
        this.setState(state => ({
            target
        }));
    }
    setTopic = (topic) => {
        this.setState(state => ({
            topic
        }));
    }
    async componentDidMount() {
        //loading lib for client side only
        let result = await import("../src/backSync.js")
        back = result.default

        const cookies = new Cookies()
        cookies.set('redirect_url', window.location.pathname, { path: '/' })
    }

    sendPush(url, payload) {
        axios.post(url, {
            payload
        }).then(response => {
            this.setState({ success: true, error: false, warning: false, message: '', snackMessage: "Votre message à bien été envoyé.", loading: false, openSnack: false })
        }).catch(error => {
            if (error.status != 500) {
                if (process.browser) {
                    // client-side-only code
                    back.saveEventDataLocally([{ message: this.state.message }]);
                }
            }
            this.setState({ success: false, error: false, warning: true, snackMessage: "📴 Votre message n'a pas pu aboutir, mais a été sauvegardé. Nous l'enverrons lorsque nous aurons une meilleure connectivité.", loading: false, openSnack: true })
        });
    }

    async sendSingleMessage(payload) {
        let EdeclicLib = (await import('../components/firebase-client.js')).default
        if (!EdeclicLib.messaging)
            return
        payload.message.token = await EdeclicLib.askForToken();

        this.sendPush("/push/message", payload)
    }

    sendToAll(payload) {
        this.sendPush("/push/allsubscribers", payload)
    }

    sendToTopic(payload) {
        payload.message.topic = this.state.topic
        this.sendPush("/push/message", payload)
    }

    handleNext = async () => {
        "use strict";
        if (this.state.activeStep == 2) {
            //TODO: verify infos
            let payload = {
                message: {
                    webpush: {
                        headers: {
                            Urgency: "high"
                        },
                        notification: {
                            title: this.state.title,
                            body: this.state.body,
                            icon: this.state.iconLink,
                            image: this.state.imageLink,
                            click_action: this.state.action
                        }
                    }
                }
            }
            //single
            if (this.state.target === 'a') {
                this.sendSingleMessage(payload)
            }//to All
            else if (this.state.target === 'b') {
                this.sendToAll(payload.message)
            }//to topics
            else if (this.state.target === 'c') {
                this.sendToTopic(payload)
            }

        }
        this.setState(state => ({
            activeStep: state.activeStep + 1,
        }));
    };

    handleBack = () => {
        this.setState(state => ({
            activeStep: state.activeStep - 1,
        }));
    };

    handleReset = () => {
        this.setState({
            activeStep: 0,
        });
    };

    handleClose = () => {
        this.setState({ openSnack: false })
    }

    render() {
        const { classes } = this.props;
        const { activeStep } = this.state;

        return (
            <Layout menu={this.props.menu}>
                {(this.state.isSignedIn) &&
                    (<Fragment>
                        <main className={classes.layout}>
                            <Paper className={classes.paper}>
                                {this.state.loading && (
                                    <div className="alert alert-info">
                                        <CircularProgress color="secondary" />Verification en cours...
                                </div>
                                )}
                                <Typography component="h1" variant="h4" align="center">
                                    Push Notification Launcher
                            </Typography>
                                <Stepper activeStep={activeStep} className={classes.stepper}>
                                    {steps.map(label => (
                                        <Step key={label}>
                                            <StepLabel>{label}</StepLabel>
                                        </Step>
                                    ))}
                                </Stepper>
                                <Fragment>
                                    {activeStep === steps.length ? (
                                        <Fragment>
                                            <Typography variant="h5" gutterBottom>
                                                Votre push a été envoyé sur firebase.
                                        </Typography>
                                            <Typography variant="subtitle1">
                                                Il devrait être soumis dans quelques instants.
                                        </Typography>
                                            <div className={classes.buttons}>
                                                <Button
                                                    variant="contained"
                                                    color="primary"
                                                    onClick={this.handleReset} className={classes.button}>
                                                    Nouveau 🏭
                                        </Button>
                                            </div>
                                        </Fragment>
                                    ) : (
                                            <Fragment>
                                                {this.getStepContent(activeStep)}
                                                <div className={classes.buttons}>
                                                    {activeStep !== 0 && (
                                                        <Button onClick={this.handleBack} className={classes.button}>
                                                            Retour
                                                    </Button>
                                                    )}
                                                    <Button
                                                        variant="contained"
                                                        color="primary"
                                                        onClick={this.handleNext}
                                                        className={classes.button}
                                                    >
                                                        {activeStep === steps.length - 1 ? 'Launch 🚀' : 'Next'}
                                                    </Button>
                                                </div>
                                            </Fragment>
                                        )}
                                </Fragment>
                            </Paper>
                        </main>
                    </Fragment>
                    )}
                {(!this.state.isSignedIn) &&
                    (<Button
                        variant="contained"
                        color="primary"
                        className={classes.button}
                        onClick={() => Router.push('/auth/credentials')}>Sign in to use that feature</Button>)
                }
                <Snackbar
                    autoHideDuration={6000}
                    anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
                    open={this.state.openSnack}
                    onClose={this.handleClose}
                >
                    <SnackbarContent
                        className={classes[this.state.error ? 'error' : this.state.warning ? 'warning' : 'success']}
                        message={<span id="message-id">{this.state.snackMessage}</span>}
                    /></Snackbar>
            </Layout>
        );
    }
}


export default withStyles(styles)(PushCreator);
