const express = require( 'express' );
const path = require( 'path' );

// Classes
const Pagans = require( '../models/Pagans.js' );
// Middlewares
const checkHeaders = require( '../middlewares/checkHeaders' );
const isAuthenticated = require( '../middlewares/isAuthenticated' );
const hasAccessrighton = require( '../middlewares/hasAccessrighton' );
const router = express.Router();
/*
models/Pagans.js
Managed:
/data/tribee/client-Id/users/uuid.json
/searchindex/emails.json {email:uuid}
            /login.json  {login:uuid}
            /uids.json  {uuid;[[
              login,
              email,
              encrypted psw,
              accessrights]}

ACCESSRIGHTS = {
app:{"tribeid:appname":"profil"},
data:{"tribeid":{object:"CRUDO"}}
}
ACCESSRIGHTS is store into the token and is load into req.session.header.accessrights by hasAccessrighton() middleware

appname is a website space object /sitewebsrc/appname
website live is strored into /dist source in /src

This can be managed by maildigitcreator or not.
apixtribe/sitewebs/webapp is the webinterface of apixtribe

profil: admin / manager / user are key word to give specific access to data into model. Any kind of other profil can exist. It is usefull to manage specific menu in an app.
It is also possible to authorize update a field's object depending of rule into dataManagement/object/
{ field:X
  nouserupdate: "!(['admin','manager'].includes(contexte.profil))",
}

data allow a user to access tribeid with Create Read Update Delete Own (CRUDO) on each object of a tribeid independantly of any app.

Create allow to create a new object respecting rules defined into /referentials/dataManagement/object/name.json
Update idem
Delete idem
Owner means it can be Write/Delete if field OWNER contain the UUID that try to act on this object. Usefull to allow someone to fully manage its objects.

*/
router.get( '/isauth', checkHeaders, isAuthenticated, ( req, res ) => {
	if( req.session.header.xpaganid == "1" ) {
		return res.status( 401 )
			.send( { info: "not authenticate" } );
	} else return res.status( 200 )
		.send( { info: "well authenticated" } )
} )
router.post( '/login', checkHeaders, async ( req, res ) => {
	// logger.info('POST /users/login with: ', req.app.locals.header);
	/*
	Check un mot de passe pour un login pour obtenir un token d'authentification
	valable 1 hour, 1 day
	@header
	@body.LOGIN
	@body.PASSWORD
	@checkpsw = true check si les 2 mot de passe cryptés correspondent
	            false bypass le contrôle et permet de générer un token
	            utile le temps de reinitialisé son mot de passe.
	@return
	*/
	logger.info( 'login for ', req.body, "in", req.session.header )
	const log = await Pagans.loginUser( req.session.header, req.body, true );
	logger.info( "log user login", log );
	if( log.status == 200 ) {
		// update req.app.locals.tokens for this uuid just after login success then next isAuth will be valid
		req.app.locals.tokens[ log.data.user.UUID ] = { TOKEN: log.data.user.TOKEN, ACCESSRIGHTS: log.data.user.ACCESSRIGHTS }
		logger.info( req.app.locals )
	}
	return res.status( log.status )
		.send( log.data );
} );


router.get( '/getlinkwithoutpsw/:email', checkHeaders, async ( req, res ) => {
	/*
	Permet pour un email existant de renvoyer un email avec un lien valable 1h
	@email est le compte pour lequel on demande un accès
	Réponse:
	Si email n'existe pas on n'envoie pas d'email
	Si email existe on envoie un email avec un lien dont le token est valable 1h

	@return
	{status:200 ou erreur ,
	  payload:{
	    info:[list de key to appear in correct requester langue],
	    model:'Pagans',
	    moreinfo: 'texte pour log '
	  }
	}
	*/
	logger.info( `GET /users/getlinkwithoutpsw for email: ${req.params.email} tribeid :${req.header('X-Client-Id')}` );
	if( !req.params.email ) {
		return res.status( 404 )
			.send( {
				info: [ 'emailmissing' ],
				model: 'Pagans'
			} );
	} else {
		try {
			const getlink = await Pagans.getlinkwithoutpsw( req.params.email, req.session.header );
			logger.info( 'getlink', getlink )
			//met à jour le token créer pour le uuid
			req.app.locals.tokens[ getlink.data.info.xuuid ] = getlink.data.info.token;
			// attention si on relance le serveur le token temporaire est perdu
			return res.status( getlink.status )
				.send( getlink.data );
		} catch ( err ) {
			logger.info( err )
			return res.status( 500 )
				.send( { info: [ 'errServer' ], model: 'Pagans' } );
		}
	}
} );
router.post( '/register', checkHeaders, async ( req, res ) => {
	logger.info( `POST /users for ${req.session.header.xtribe}` );
	if( req.session.header.xauth == '123123' ) {
		// Creation d'un utilisateur avec information de base aucun droit
		// On modifie le contenu du form pour n egarder que login/email et psw
		// pour le client_id permet de traiter un user en attente de validation
		logger.info( 'req du post', req );
	}
} );
router.get( '/info/:listindex', checkHeaders, isAuthenticated, hasAccessrighton( 'users', 'R' ), async ( req, res ) => {
	logger.info( `get users info on tribeid ${req.session.header.xworkon} for ${req.params.listindex} with accessright`, req.session.header.accessrights.data );
	const result = await Pagans.getinfoPagans( req.session.header.xpresworkon, req.session.header.accessrights, req.params.listindex );
	res.status( result.status )
		.send( result.data );
} );
router.get( '/list/:filter/:field', checkHeaders, isAuthenticated, hasAccessrighton( 'users', 'R' ), async ( req, res ) => {
	logger.info( 'GET /users/list/filtre/champs list for ' + req.session.header.xworkon );
	if(
    [ 'admin', 'manager' ].includes( req.session.header.decodetoken[ 'apps' + req.session.header.xworkon + 'profil' ] ) ) {
		try {
			const userslist = await Pagans.getUserlist( req.session.header, req.params.filter, req.params.field );
			logger.info( 'userslist', userslist );
			if( userslist.status == 200 ) {
				return res.status( userslist.status )
					.send( userslist.data );
			}
		} catch ( err ) {
			logger.info( err );
			return res.status( 400 )
				.send( { info: 'erreur' } );
		}
	} else {
		res.status( 403 )
			.send( {
				info: [ 'forbiddenAccess' ],
				model: 'Pagans'
			} );
	}
} );
router.get( '/uuid/:id', checkHeaders, isAuthenticated, hasAccessrighton( 'users', 'R' ), async ( req, res ) => {
	logger.info( `GET /users/uuid/${req.params.id}` );
	//logger.info('req.app.locals:  ', req.app.locals);
	//logger.info('req.session', req.session);
	const result = await Pagans.getUser( req.params.id, req.session.header.xworkon, req.session.header.accessrights );
	res.status( result.status )
		.send( result.data );
} );
router.put( '/chgpsw/:id', checkHeaders, isAuthenticated, async ( req, res ) => {
	logger.info( `PUT update /users/chgpsw/${req.params.id}` );
	try {
		const majpsw = await Pagans.updateUserpassword( req.params.id, req.session.header, req.body );
		res.status( majpsw.status )
			.send( majpsw.data );
	} catch ( {
		status,
		data
	} ) {
		res.status( status )
			.send( data );
	}
} );
router.post( '/uuid', checkHeaders, isAuthenticated, hasAccessrighton( 'users', 'C' ), async ( req, res ) => {
	logger.info( 'POST /users create for ' + req.session.header.xworkon, req.body );
	const usercreate = await Pagans.createUser( req.session.header, req.body );
	return res.status( usercreate.status )
		.send( usercreate.data );
} );
router.put( '/uuid/:id', checkHeaders, isAuthenticated, hasAccessrighton( 'users', 'U' ), async ( req, res ) => {
	logger.info( `PUT update /users/${req.params.id}` );
	// logger.info('req.app.locals:  ', req.app.locals);
	// logger.info('req.session', req.session);
	try {
		const majUser = await Pagans.updateUser( req.params.id, req.session.header, req.body );
		res.status( majUser.status )
			.send( majUser.data );
	} catch ( {
		status,
		data
	} ) {
		res.status( status )
			.send( data );
	}
} );
router.delete( '/uuid/:id', checkHeaders, isAuthenticated, hasAccessrighton( 'users', 'D' ), ( req, res ) => {
	logger.info( `DELETE /users/uuid/${req.params.id}` );
	const result = Pagans.deleteUser( req.params.id, req.session.header );
	res.status( result.status )
		.send( result.data );
} );
module.exports = router;
