import React from 'react';
import {withContextConsumer} from "@formanta/react";
import {addHeader, ApiRequest, POST, rmHeader} from "../lib/ApiRequest";
import {withApiControl} from "../component/ApiControl";

const AuthContext = React.createContext({});

class AuthProviderBase extends React.Component {
    constructor(props) {
        super(props);

        this.logout = () => {
            window.localStorage.removeItem('jwt');

            rmHeader('AUTHORIZATION');

            this.setState({
                loggedIn: false,
                authToken: false,
            });
        };

        this.logIn = (authToken) => {
            window.localStorage.setItem('jwt', authToken);

            addHeader('AUTHORIZATION', 'Bearer ' + authToken);

            this.setState({
                loggedIn: true,
                authToken
            });
        };

        let authToken = false;
        let loggedIn = false;
        let tmp_token = window.localStorage.getItem('jwt');
        if(null !== tmp_token && '' !== tmp_token.trim()) {
            authToken = tmp_token;
            loggedIn = true;

            addHeader('AUTHORIZATION', 'Bearer ' + authToken);
        }

        this.state = {
            loggedIn,
            authToken,
            authVerify: this.authVerify,
            logout: this.logout,
            logIn: this.logIn,
        };
    }

    authVerify = (data, onLoggedIn) => {
        return (new ApiRequest('auth', POST, 'verify', data))
            .debug(true)
            .header({})
            .exec()
            .then((res) => {
                return new Promise((resolve, reject) => {
                    if(res && res.data) {
                        if(res.data.token) {
                            this.logIn(res.data.token);

                            if(onLoggedIn) {
                                onLoggedIn();
                            }

                            resolve();
                        }
                        if(res.data.error) {
                            // todo: optimize error message after it is developed in FormApi
                            reject({
                                clientErr: 'auth-failed'
                            });
                        }
                        /*this.setState({
                            //last_id: res.data.created
                        });*/
                    } else {
                        reject({
                            clientErr: 'invalid',
                        });
                    }
                });
            })
            .catch(err => {
                if(err.clientErr) {
                    throw err;
                }

                this.props.handleApiFail(err, 'Login', false);

                const ConnectionError = {backendErr: 'connection-error'};
                throw ConnectionError;
            });
    };

    componentDidUpdate(prevProps, prevState) {
        if(!prevState.loggedIn && prevState.loggedIn !== this.state.loggedIn) {
            // just logged in
        } else if(prevState.loggedIn && prevState.loggedIn !== this.state.loggedIn) {
            // just logged out
        }
    }

    render() {
        return (
            <AuthContext.Provider value={this.state}>
                {this.props.children}
            </AuthContext.Provider>
        );
    }
}

const withAuth = withContextConsumer(AuthContext.Consumer);

const AuthProvider = withApiControl(AuthProviderBase);

export {AuthProvider, withAuth};