'use strict';

const _ = require('lodash');
const moment = require('moment');
const httpStatus = require('http-status');
const controllerHelper = require('../../helpers/controller.helper');
const crypto = require('crypto');
const securityHelper = require('../../helpers/security.helper');
const authService = require('./auth.service');
const userService = require('./user.service');
const eventInscriptionService = require('../events/events_inscriptions.service');
moment.locale('es');

////////////////////////////////////////////////////////////////////////////////
// CONSTANTS
////////////////////////////////////////////////////////////////////////////////

// Module Name
const MODULE_NAME = '[auth.controller]';

////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
////////////////////////////////////////////////////////////////////////////////

async function login(req, res, next) {
    try {
        const data = {
            id: req.user.id,
            email: req.user.email,
            phone: req.user.phoneNumber,
            fbuid: req.user.uid
        };

        const tokens = securityHelper.generateToken(data);

        const response = {
            token: tokens.token,
            refreshToken: tokens.refreshToken,
            user: req.user,
        };

        return controllerHelper.handleResultResponse(response, null, req.params, res, httpStatus.OK);      
    } catch (error) {
        return controllerHelper.handleErrorResponse(MODULE_NAME, login.name, error, res)
    }
}

async function loginWithPhone(req, res, next) {
    try {
        const appVersion = ((req && req.headers && req.headers['accept-version']) ? req.headers['accept-version'] : null);
        console.log('loginWithPhone - appVersion: ', appVersion); 

        console.log(req.user);
        const findOptions = {
            phone: req.user.phoneNumber,
            fbuid: req.user.uid
        };

        //Comprobamos si el usuario ya existe en nuestro sistema
        let _user = await authService.extraMethods.findUserByPhone(req.user.phoneNumber);
        if (_user) {
            _user = _user.toJSON();
            if (appVersion) {
                if (_user.app_version != appVersion) {
                    const result = userService._updateLastLoginAndVersionUser(_user.id, appVersion);
                    console.log('PRUEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEBA>>>> ', result);
                    _user.app_version = appVersion;
                }
            }


            const tokenData = {
                id: _user.id,
                email: _user.email,
                phone: _user.phone,
                fbuid: _user.fbuid,
            };
            const tokens = securityHelper.generateToken(tokenData);

            _user.token = tokens.token;

            //Recuperamos el número de tickets para los proximos eventos
            try {
                const result = await eventInscriptionService._getInscriptionsOfNextEventsUser(_user.id);
                console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', result);
                _user.nextTicketsCount = result;                
            } catch (error) {
                return handleErrorResponse(MODULE_NAME, 'getInscriptionsOfNextEventsCount', error, res)
            }

            return controllerHelper.handleResultResponse(_user, null, req.params, res, httpStatus.OK);
        } else {
            return controllerHelper.handleResultResponse(null, null, req.params, res, httpStatus.NOT_FOUND);
        }
    } catch (error) {
        return controllerHelper.handleErrorResponse(MODULE_NAME, login.name, error, res)
    }
}

async function register(req, res, next) {

    function cleanAdminData(user) {
        let cUser = user;
        delete cUser.lastLogin;
        delete cUser.state;
        delete cUser.createdAt;
        delete cUser.updatedAt;
        return cUser;
    }

    const values = {
        phone: req.body.phone,
        fbuid: req.body.fbuid 
    };

    const appVersion = ((req && req.headers && req.headers['accept-version']) ? req.headers['accept-version'] : null);
    console.log('loginWithPhone - appVersion: ', appVersion); 


    //Comprobamos si el usuario ya existe en nuestro sistema
    let newUser = await authService.extraMethods.findUserByPhone(values.phone);
console.log('COMPROBAMOS IS EXISTE EN NUESTRO SISTEMA', newUser);    
    if (!newUser) {
        try {
            const data = {
                //refresh_token: tokens.refreshToken,
                phone: req.body.phone,
                fbuid: req.body.fbuid,
                email: req.body.email, 
                name: req.body.name,
                surname: req.body.surname,
                entityid: req.body.entityid,
                accessibility: req.body.accesssibility,
                app_version: appVersion,
                lastlogin: moment().utc(),
            };

            newUser = await authService.extraMethods.createUser(data);            
console.log('CREAMOS EL USUARIO EN NUESTRO SISTEMA', newUser);                
        } catch (error) {
            console.error(error);
            return controllerHelper.handleErrorResponse(MODULE_NAME, register.name, error, res);
        }
    };

    if (newUser) {
        newUser = newUser.toJSON();
        newUser = cleanAdminData(newUser);
        if (appVersion) {
            if (newUser.app_version != appVersion) {
                const result = userService._updateLastLoginAndVersionUser(newUser.id, appVersion);
                console.log('PRUEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEBA>>>> ', result);
                newUser.app_version = appVersion;
            }
        }


        const tokenData = {
            phone: values.phone,
            fbuid: values.fbuid,
            id: newUser.id,
            email: newUser.email,
        };
        const tokens = securityHelper.generateToken(tokenData);

        newUser.token = tokens.token;
 console.log('COMO YA EXISTE CREAMOS EL TOKEN Y LO ASIGNAMOS', newUser);                        
    }
    
    return controllerHelper.handleResultResponse(newUser, null, req.params, res, httpStatus.OK);    
}

async function regenerateToken(req, res, next) {
    const refreshToken = req.body.refreshToken;
    const phone = req.body.phone;
    const user = await authService.extraMethods.findUserByRefreshToken(refreshToken);

    if (user && user.phone === phone) {
        const values = {
            phone: user.phone,
            fbuid: user.fbuid,
            id: user.id,
            email: user.email,
        };
        
        try {
            const tokens = securityHelper.generateToken(values);
            await authService.extraMethods.updateUserRefreshToken(user.id, tokens.refreshToken);
            const result = { token: tokens.token };
            return controllerHelper.handleResultResponse(result, null, req.params, res, httpStatus.OK);
        } catch(error) {
            return controllerHelper.handleErrorResponse(MODULE_NAME, regenerateToken.name, error, res);
        }
    } else {
        return controllerHelper.handleResultResponse(null, null, req.params, res, httpStatus.UNAUTHORIZED);
    }
}

async function rejectToken(req, res, next) {
    const refreshToken = req.body.refreshToken;
    const user = await authService.extraMethods.findUserByRefreshToken(refreshToken);

    if (user && user.token === refreshToken ) {        
        try {
            await authService.extraMethods.deleteRefreshToken(refreshToken);
            return controllerHelper.handleResultResponse(result, null, req.params, res, httpStatus.OK);
        } catch (error) {
            return controllerHelper.handleErrorResponse(MODULE_NAME, rejectToken.name, error, res);
        }    
    } else {
        return controllerHelper.handleResultResponse(null, null, req.params, res, httpStatus.NOT_FOUND);
    }
}

// Registro por email y por password
async function singup(req, res, next) {
    var newUser = undefined;

    try {
        const data = {
            email: req.body.email,
            name: req.body.name,
            surname: req.body.surname,
            level: 8,
            password: crypto.createHash('sha512').update(req.body.password).digest('hex')
        };

        newUser = await authService.extraMethods.createUser(data);

    } catch (error) {
        console.error(error);
        return controllerHelper.handleErrorResponse(MODULE_NAME, register.name, error, res);
    }

    if (newUser) {
        newUser = newUser.toJSON();

        const tokenData = {
            phone: undefined,
            fbuid: undefined,
            id: newUser.id,
            email: newUser.email,
        };
        const tokens = securityHelper.generateToken(tokenData);

        newUser.token = tokens.token;
    }

    return controllerHelper.handleResultResponse(newUser, null, req.params, res, httpStatus.OK);    
}

function verify(req, res, next) {
    return controllerHelper.handleResultResponse('OK', null, req.params, res, httpStatus.OK);    
}


module.exports = {
    login,
    loginWithPhone,
    register,
    regenerateToken,
    rejectToken,
    singup,
    verify,
    MODULE_NAME
}