require('dotenv').config()

const express = require('express')
const http = require('http')
const session = require('express-session')
//const cookieParser = require('cookie-parser')
//const io = require('socket.io')(server)
const path = require('path')
const passport = require('passport')
    , LocalStrategy = require('passport-local').Strategy

//const redis = require('redis-url').connect()
//const RedisStore = require('connect-redis')(session)
/*const passportSocketIo = require('passport.socketio')*/

const indexRouter = require('./routes/index')

//const cors = require('cors')

const JamiRestApi = require('./routes/jami')
const JamiDaemon = require('./JamiDaemon')

//const sessionStore = new RedisStore({ client: redis })
const sessionStore = new session.MemoryStore()

const app = express()
console.log(`Loading server for ${app.get('env')}`)
const development = app.get('env') === 'development'

if (development) {
    const webpack = require('webpack')
    const webpackConfig = require('./client/webpack.config.js')
    const compiler = webpack(webpackConfig)
    app.use(require('webpack-dev-middleware')(compiler, {
        publicPath: webpackConfig.output.publicPath
    }));
    app.use(require('webpack-hot-middleware')(compiler));
}

/*
    Configuation for Passeport Js
*/
app.disable('x-powered-by');

app.use(session({
    store: sessionStore,
    resave: false,
    saveUninitialized: true,
    cookie: {
        secure: false,//process.env.ENVIRONMENT !== 'development' && process.env.ENVIRONMENT !== 'test',
        maxAge: 2419200000
    },
    secret: process.env.SECRET_KEY_BASE
}));
app.use(passport.initialize());
app.use(passport.session());
// app.use(app.router);
//app.use(cors())

/*
    Share sessions between Passport.js and Socket.io
*/

function logSuccess() {
    console.log("passportSocketIo authorized user with Success 😁");
}

function logFail() {
    console.log("passportSocketIo failed to authorized user 👺");
}

/*
io.use(passportSocketIo.authorize({
    key: 'connect.sid',
    secret: process.env.SECRET_KEY_BASE,
    store: sessionStore,
    passport: passport,
    cookieParser: cookieParser,
    //success: logSuccess(),
    // fail: logFail(),
}));
*/

/*

    tempAccounts holds users accounts while tempting to authenticate them on Jams.
    connectedUsers  holds users accounts after they got authenticated by Jams.

    Users should be removed from connectedUsers when receiving a disconnect
    web socket call

*/
const tempAccounts = {};
const connectedUsers = {};

const jami = new JamiDaemon();
const apiRouter = new JamiRestApi(jami).getRouter()

passport.serializeUser((user, done) => {
    console.log(user)
    connectedUsers[user.accountId] = user;
    console.log("=============================SerializeUser called " + user.accountId)
    done(null, user.accountId);
});

const deserializeUser = (id, done) => {
    console.log("=============================DeserializeUser called on: " + id + " " + connectedUsers[id])
    done(null, connectedUsers[id]);
};
passport.deserializeUser(deserializeUser);

//var tempAccountId = '';

const jamsStrategy = new LocalStrategy(
    (username, password, done) => {

        const newUser = {};
        newUser.username = username;
        //newUser.socketid =

        const accountId = jami.addAccount({
            'managerUri': 'https://jams.savoirfairelinux.com',
            'managerUsername': username,
            'archivePassword': password
        });

        const newProps = jami.getAccount(accountId).details;
        console.log(newProps);
        //Object.entries(newProps).forEach(v => console.log(v[0], v[1]))
        //tempAccountId = accountId;
        newUser.accountId = accountId;
        console.log("AccountId: " + accountId);
        connectedUsers[accountId] = newUser;
        tempAccounts[accountId] = { done, newUser };

        //return done(null, newUser);

        /*User.findOne({ username: username }, function (err, user) {
            if (err) { return done(err); }
            if (!user) {
                return done(null, false, { message: 'Incorrect username.' });
            }
            if (!user.validPassword(password)) {
                return done(null, false, { message: 'Incorrect password.' });
            }
            return done(null, user);
        });*/
    }
);
jamsStrategy.name = "jams";

const localStrategy = new LocalStrategy(
    (username, password, done) => {
        console.log("localStrategy: " + username + " " + password);

        const newUser = {};
        newUser.accountId = jami.getAccountList()[0].getId();
        console.log("Local AccountId: " + newUser.accountId);
        connectedUsers[newUser.accountId] = newUser;
        done(null, newUser);
    }
);

passport.use(jamsStrategy);
passport.use(localStrategy);

const secured = (req, res, next) => {
    console.log(`isSecured ${req.user}`);
    if (req.user && req.user.accountId) {
        return next();
    }
    res.status(401).end()
};
const securedRedirect = (req, res, next) => {
    if (req.user && req.user.accountId) {
        return next();
    }
    req.session.returnTo = req.originalUrl;
    res.redirect('/login');
};

app.post('/auth', passport.authenticate('jams'), (req, res) => {
    res.json({ loggedin: true })
});
app.post('/api/localLogin', passport.authenticate('local'), (req, res) => {
    res.json({ loggedin: true })
});

app.use('/api', secured, apiRouter);

app.use('/', indexRouter);

/* GET React App */

app.use(express.static(path.join(__dirname, 'client', 'dist')))

app.use((req, res, next) => {
    res.sendFile(path.join(__dirname, 'client', 'dist', 'index.html'));
});

const server = http.Server(app);
server.listen(3000);

/*
io.on('connection', (socket) => {
    console.log("Client just connected !")
    socket.on('SendMessage', (data) => {
        console.log("Message " + data.text + " sent to " + data.destinationId + " by " + socket.session.user.accountId);
        const msgMap = new jami.dring.StringMap();
        msgMap.set('text/plain', data.text);
        jami.dring.sendAccountTextMessage(socket.session.user.accountId, data.destinationId, msgMap);
    });
});

io.use((socket, next) => {
    cookieParser(socket.handshake, {}, (err) => {
        if (err) {
            console.log("error in parsing cookie");
            return next(err);
        }
        if (!socket.handshake.signedCookies) {
            console.log("no secureCookies|signedCookies found");
            return next(new Error("no secureCookies found"));
        }
        sessionStore.get(socket.handshake.signedCookies["connect.sid"], (err, session) => {
            socket.session = session;
            if (!err && !session) err = new Error('session not found');
            if (err) {
                console.log('failed connection to socket.io:', err);
            } else {
                console.log(session);
                console.log('successful connection to socket.io ' + session.passport.user);
                const userKey = session.passport.user;
                deserializeUser(userKey, (err, user) => {
                    console.log("deserializeUser: " + user)
                    if (err)
                        return next(err, true);
                    if (!user)
                        return next("User not found", false);

                    console.log("User associated socket id: " + socket.id)
                    user.socketId = socket.id;
                    socket.session.user = user;
                    console.log("User added to session --------> " + user.accountId);
                    //auth.success(data, accept);
                    next(err, true);
                });
            }
        });
    });
});
*/
