const express = require('express');
const router = express.Router();

const UserController = require('../controllers/UserController');
const { authenticate, authenticate_noerror, authenticate_withUser } = require('../middleware/authenticate');
const { checkBlocked } = require('../middleware/securityMiddleware');

// Initialize controller
const userController = new UserController();

// ===== PUBLIC ROUTES =====

/**
 * Register new user
 * POST /users
 */
router.post('/', (req, res) => userController.register(req, res));

/**
 * Check if username exists
 * GET /users/:idapp/:username
 */
router.get('/:idapp/:username', (req, res) => userController.checkUsername(req, res));

/**
 * User login
 * POST /users/login
 */
router.post('/login', checkBlocked, (req, res) => userController.login(req, res));

/**
 * Refresh authentication token
 * POST /users/newtok
 */
router.post('/newtok', (req, res) => userController.refreshToken(req, res));

/**
 * Get user activities (public profile)
 * POST /users/activities
 */
router.post('/activities', authenticate_noerror, (req, res) => 
  userController.getProfile(req, res)
);

// ===== AUTHENTICATED ROUTES =====

/**
 * Get user profile
 * POST /users/profile
 */
router.post('/profile', authenticate, (req, res) => 
  userController.getProfile(req, res)
);

/**
 * Get user panel info (admin/manager only)
 * POST /users/panel
 */
router.post('/panel', authenticate, (req, res) => {
  const { User } = require('../models/user');
  const server_constants = require('../tools/server_constants');
  
  if (!req.user || (!User.isAdmin(req.user.perm) && 
      !User.isManager(req.user.perm) && 
      !User.isFacilitatore(req.user.perm))) {
    return res.status(server_constants.RIS_CODE_ERR_UNAUTHORIZED).send({ 
      code: server_constants.RIS_CODE_ERR_UNAUTHORIZED, 
      msg: '' 
    });
  }
  
  userController.getProfile(req, res);
});

/**
 * Update user balance
 * POST /users/updatesaldo
 */
router.post('/updatesaldo', authenticate, (req, res) => 
  userController.updateSaldo(req, res)
);

/**
 * Get user's friends
 * POST /users/friends
 */
router.post('/friends', authenticate, (req, res) => 
  userController.getFriends(req, res)
);

/**
 * Execute friend command
 * POST /users/friends/cmd
 */
router.post('/friends/cmd', authenticate, (req, res) => 
  userController.executeFriendCommand(req, res)
);

/**
 * Send command to user
 * POST /users/sendcmd
 */
router.post('/sendcmd', authenticate, (req, res) => {
  const usernameLogged = req.user.username;
  const { idapp, usernameOrig, usernameDest, cmd, value } = req.body;
  
  userController.userService.sendCommand(
    req, idapp, usernameOrig, usernameDest, cmd, value
  ).then(result => res.send(result))
    .catch(error => res.status(400).send({ error: error.message }));
});

/**
 * Get user's groups
 * POST /users/groups
 */
router.post('/groups', authenticate, (req, res) => 
  userController.getGroups(req, res)
);

/**
 * Execute group command
 * POST /users/groups/cmd
 */
router.post('/groups/cmd', authenticate, (req, res) => {
  const usernameLogged = req.user.username;
  const { idapp, usernameOrig, groupnameDest, cmd, value } = req.body;
  
  userController.userService.executeGroupCommand(
    idapp, usernameOrig, groupnameDest, cmd, value, usernameLogged
  ).then(result => res.send(result))
    .catch(error => res.status(400).send({ error: error.message }));
});

/**
 * Get user's circuits
 * POST /users/circuits
 */
router.post('/circuits', authenticate_withUser, (req, res) => 
  userController.getCircuits(req, res)
);

/**
 * Execute circuit command
 * POST /users/circuits/cmd
 */
router.post('/circuits/cmd', authenticate, async (req, res) => {
  const usernameLogged = req.user.username;
  const { idapp, usernameOrig, circuitname, cmd, value, extrarec } = req.body;
  
  try {
    const result = await userController.userService.executeCircuitCommand(
      idapp, usernameOrig, circuitname, cmd, value, usernameLogged, extrarec
    );
    res.send(result);
  } catch (error) {
    res.status(400).send({ error: error.message });
  }
});

/**
 * Logout user
 * DELETE /users/me/token
 */
router.delete('/me/token', authenticate_withUser, (req, res) => 
  userController.logout(req, res)
);

/**
 * Set user permissions
 * POST /users/setperm
 */
router.post('/setperm', authenticate, (req, res) => 
  userController.setPermissions(req, res)
);

/**
 * Get last movements/transactions
 * POST /users/lastmovs
 */
router.post('/lastmovs', authenticate, async (req, res) => {
  const { nummov, nummov_uscita, idapp } = req.body;
  const server_constants = require('../tools/server_constants');
  const tools = require('../tools/general');
  
  try {
    const { Movement } = require('../models/movement');
    
    let last_transactions = [];
    if (nummov) {
      last_transactions = await Movement.getLastN_Transactions(idapp, nummov, nummov_uscita);
    }
    
    res.send({ code: server_constants.RIS_CODE_OK, last_transactions });
  } catch (e) {
    tools.mylogserr('Error lastmovs: ', e);
    res.status(400).send();
  }
});

/**
 * Set receive RIS flag
 * POST /users/receiveris
 */
router.post('/receiveris', authenticate, async (req, res) => {
  const username = req.user?.username || '';
  const { groupname, idapp } = req.body;
  const { User } = require('../models/user');
  const { MyGroup } = require('../models/mygroup');
  const server_constants = require('../tools/server_constants');
  const tools = require('../tools/general');
  
  try {
    if (!username) {
      return res.send({ code: server_constants.RIS_CODE_ERR });
    }
    
    if (groupname) {
      await MyGroup.setReceiveRisGroup(idapp, groupname);
    } else {
      await User.setReceiveRis(idapp, username);
    }
    
    res.send({ code: server_constants.RIS_CODE_OK });
  } catch (err) {
    tools.mylog('ERRORE IN receiveris: ' + err.message);
    res.status(400).send();
  }
});

/**
 * List registration links
 * POST /users/listlinkreg
 */
router.post('/listlinkreg', authenticate, async (req, res) => {
  const username = req.user?.username || '';
  const { idapp } = req.body;
  const { User } = require('../models/user');
  const server_constants = require('../tools/server_constants');
  const tools = require('../tools/general');
  
  try {
    if (!username) {
      return res.send({ code: server_constants.RIS_CODE_ERR });
    }
    
    await User.setLinkReg(idapp, username);
    res.send({ code: server_constants.RIS_CODE_OK });
  } catch (err) {
    tools.mylog('ERRORE IN listlinkreg: ' + err.message);
    res.status(400).send();
  }
});

// ===== ADMIN ROUTES =====

/**
 * Update user (admin only)
 * PATCH /users/:id
 */
router.patch('/:id', authenticate, (req, res) => {
  const { User } = require('../models/user');
  const _ = require('lodash');
  const shared_consts = require('../tools/shared_nodejs');
  const server_constants = require('../tools/server_constants');
  const tools = require('../tools/general');
  
  const id = req.params.id;
  const body = _.pick(req.body.user, shared_consts.fieldsUserToChange());
  
  tools.mylogshow('PATCH USER: ', id);
  
  if (!User.isAdmin(req.user.perm)) {
    return res.status(server_constants.RIS_CODE_ERR_UNAUTHORIZED).send({ 
      code: server_constants.RIS_CODE_ERR_UNAUTHORIZED, 
      msg: '' 
    });
  }
  
  User.findByIdAndUpdate(id, { $set: body })
    .then((user) => {
      tools.mylogshow(' USER TO MODIFY: ', user);
      if (!user) {
        return res.status(404).send();
      }
      res.send({ code: server_constants.RIS_CODE_OK, msg: '' });
    })
    .catch((e) => {
      tools.mylogserr('Error patch USER: ', e);
      res.status(400).send();
    });
});

/**
 * Execute database operation (admin only)
 * POST /users/dbop
 */
router.post('/dbop', authenticate, (req, res) => 
  userController.executeDbOperation(req, res)
);

/**
 * Execute user database operation
 * POST /users/dbopuser
 */
router.post('/dbopuser', authenticate, async (req, res) => {
  const { mydata, idapp } = req.body;
  const server_constants = require('../tools/server_constants');
  
  try {
    const result = await userController.userService.executeUserDbOperation(
      idapp, 
      mydata, 
      req.user.username
    );
    
    res.send({ code: server_constants.RIS_CODE_OK, ris: result });
  } catch (e) {
    res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: e.message });
  }
});

/**
 * Get map information
 * POST /users/infomap
 */
router.post('/infomap', authenticate, (req, res) => 
  userController.getMapInfo(req, res)
);

/**
 * Management telegram operations
 * POST /users/mgt
 */
router.post('/mgt', authenticate_withUser, async (req, res) => {
  const { mydata, idapp } = req.body;
  const telegrambot = require('../telegram/telegrambot');
  
  try {
    const { nummsgsent, numrec, textsent, text } = 
      await telegrambot.sendMsgFromSiteToBotTelegram(idapp, req.user, mydata);
    
    res.send({ numrec, nummsgsent, textsent, text });
  } catch (e) {
    res.status(400).send({ error: e.message });
  }
});

// ===== TEST ROUTES (Development only) =====

if (process.env.NODE_ENV === 'development' || process.env.LOCALE === '1') {
  router.post('/test1', async (req, res) => {
    const { User } = require('../models/user');
    const sendemail = require('../sendemail');
    
    const user = await User.findOne({
      idapp: 1,
      username: 'paoloar77'
    });
    
    if (user) {
      await sendemail.sendEmail_Registration(
        user.lang, 
        user.email, 
        user, 
        user.idapp, 
        user.linkreg
      );
    }
    
    res.send({ success: true });
  });
}

module.exports = router;