const express = require("express");
const app = express()
const port = 8080
require("dotenv").config();
app.use(require("body-parser").urlencoded({ extended:true }));
app.use(require("cookie-parser")());
app.use(require("express-session")({secret: 'baterkabaterka', resave: true, saveUninitialized: true}));

var passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;

const user = require("pg");
app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser(function (user, cb) {
    cb(null, user);
})

passport.deserializeUser(function (user, cb) {
    cb(null, user);
})




// Database
const { Pool, Client }  = require("pg")

const pool = new Pool({
    user: process.env["DB_USER"],
    host: process.env["DB_HOST"],
    database: process.env["DB_DATABASE"],
    password: process.env["DB_PASSWORD"],
    port: process.env["DB_PORT"]
})

// pool.query('SELECT NOW()', (err, res) => {
//     console.log(err, res)
//     pool.end()
// })

// ----------------------------------------------


// Routes

app.get('/', (req, res) => {
    let responseHtml = "<a href='/auth/facebook/'>Prihlasit/Registrovat cez Facebook</a>";
        responseHtml += " <br> <a href='/auth/google/'>Prihlasit/Registrovat cez Google</a>"
    if (req.user) {
        responseHtml += "<br> <p>Je prihlaseny uzivatel: " + req.user.id + "</p>";
    }
    res.send(responseHtml);
})

app.get('/profile', require('connect-ensure-login').ensureLoggedIn(), async (req, res) => {
    let responseHtml = '';
    let showFacebookButton = await existsFacebookUser(req.user.id);
    //console.log(showFacebookButton)
    if (showFacebookButton === false) {
        responseHtml += "<a href='/auth/facebook/'>Pridat ucet cez Facebook</a>";
    }
    let showGoogleButton = await existsGoogleUser(req.user.id);
    if (showGoogleButton === false) {
        responseHtml += "<a href='/auth/google/'>Pridat ucet cez Google</a>";
    }
    res.send(responseHtml);
})

app.get('/logout', require('connect-ensure-login').ensureLoggedIn(), (req, res) => {
    req.logout();
    res.redirect('/');
} )
// --------------------------------------------------


// Facebook
const existsFacebookUser = async (account_id) => {
    const result = await pool.query("SELECT fb_user_id FROM facebook_accounts WHERE account_id=" + account_id);
    if (result.rowCount !== 0) {
        console.log("blabla");
        return true;
    }

    console.log("blasadasdasla");
    return false;
}
const handleFacebookUser = async (req, profile, done) => {
    const sql = "SELECT account_id, fb_user_id from facebook_accounts WHERE fb_user_id = '" + profile.id + "'";


    if (req.user) {
        console.log(req.user.id)
        await registerFacebookUser(profile, req.user.id);
    }

    let result = await pool.query(sql);
    if (result.rowCount === 0){
        await registerUser(profile);
        return false; // Neprihlasi registrovaneho uzivatela.
    }
    else{
        profile.id = result.rows[0].account_id
        return done(null, profile);
    }
}

const registerFacebookUser = async (profile, account_id) => {
    await pool.query("INSERT INTO facebook_accounts (fb_user_id,account_id) VALUES ($1,$2)" , [profile.id, account_id]);
}

passport.use(new FacebookStrategy({
        clientID: process.env["FB_CLIENT_ID"],
        clientSecret: process.env["FB_CLIENT_SECRET"],
        callbackURL: process.env["FB_CALLBACKURL"],
        passReqToCallback: true
    },
    function(req, accessToken, refreshToken, profile, done) {
        return handleFacebookUser(req, profile, done);
    }
));

app.get('/auth/facebook', passport.authenticate('facebook'));

app.get('/auth/facebook/callback',
    passport.authenticate('facebook', { successRedirect: '/',
        failureRedirect: '/' }));


//Google
const existsGoogleUser = async (account_id) => {
    const result = await pool.query("SELECT google_user_id FROM google_accounts WHERE account_id=" + account_id);
    if (result.rowCount !== 0) {
        return true;
    }
    return false;
}

const registerGoogleUser = async (profile, account_id) => {
    await pool.query("INSERT INTO google_accounts (google_user_id,account_id) VALUES ($1,$2)" , [profile.id, account_id]);
}
passport.use(new GoogleStrategy({
        clientID: process.env["GOOGLE_CLIENT_ID"],
        clientSecret: process.env["GOOGLE_CLIENT_SECRET"],
        callbackURL: process.env["GOOGLE_CALLBACKURL"],
        passReqToCallback: true
    },
    function(req, accessToken, refreshToken, profile, done) {
        return handleGoogleUser(req, profile, done);
    }
));
const handleGoogleUser = async (req, profile, done) => {
    const sql = "SELECT account_id, google_user_id from google_accounts WHERE google_user_id = '" + profile.id + "'";
    if (req.user) {
        console.log(req.user.id)
        await registerGoogleUser(profile, req.user.id);
    }

    let result = await pool.query(sql);
    if (result.rowCount === 0){
        await registerUser(profile);
        return done(null, null); // Neprihlasi registrovaneho uzivatela.
    }
    else{
        profile.id = result.rows[0].account_id
        return done(null, profile);
    }
}
app.get('/auth/google',
    passport.authenticate('google', { scope: ['https://www.googleapis.com/auth/plus.login'] }));


app.get('/auth/google/callback',
    passport.authenticate('google', { failureRedirect: '/' }),
    function(req, res) {
        res.redirect('/profile');
    });

/// ACCOUNTS
const registerUser = async (profile) => {
    const sql = " INSERT INTO accounts (first_name, last_name) VALUES ('saas', 'FRE') RETURNING id AS user_id";
    let subor = await pool.query(sql)

    if (profile.provider === "facebook") {
        registerFacebookUser(profile, subor.rows[0].user_id);
    }
    else if(profile.provider === "google"){
        registerGoogleUser(profile, subor.rows[0].user_id);
    }
}
// SERVER RUN

app.listen(port, () => {
    console.log("Listening on port: " + port)
})