const MatrixService = require('../../services/matrix/MatrixService');

async function create(req, res) {
  try {
    const { name, email, force, depth } = req.query; // email of the top node account
    const parsedDepth = depth !== undefined ? Number(depth) : undefined;
    const result = await MatrixService.create({
      name,
      topNodeEmail: email,
      force: String(force || '').toLowerCase() === 'true',
      depth: parsedDepth,
      actorUser: req.user
    });
    return res.json({ success: true, data: result });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Matrix creation failed' });
  }
}

async function stats(req, res) {
  try {
    const data = await MatrixService.getStats({ actorUser: req.user });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not load matrix stats' });
  }
}

// NEW: admin-only list of matrix users under a root
async function getMatrixUserforAdmin(req, res) {
  try {
    const { rootUserId, depth, limit, offset, includeRoot, rogueOnly } = req.query;
    const matrixInstanceId = req.query.matrixInstanceId || req.query.matrixId || req.query.id;
    const topNodeEmail = req.query.topNodeEmail || req.query.email;

    const data = await MatrixService.getUsers({
      rootUserId,
      maxDepth: depth,
      limit,
      offset,
      includeRoot,
      rogueOnly: String(rogueOnly || '').toLowerCase() === 'true',
      actorUser: req.user,
      matrixInstanceId,
      matrixId: matrixInstanceId, // backward alias
      topNodeEmail
    });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not load matrix users' });
  }
}

// NEW: admin-only search of user candidates to add into a matrix
async function searchCandidates(req, res) {
  try {
    const { q, type, limit, offset, rootUserId } = req.query;
    const matrixInstanceId = req.query.matrixInstanceId || req.query.matrixId || req.query.id;
    const topNodeEmail = req.query.topNodeEmail || req.query.email;
    const data = await MatrixService.getUserCandidates({
      q,
      type,
      limit,
      offset,
      rootUserId,
      matrixInstanceId,
      matrixId: matrixInstanceId,
      topNodeEmail,
      actorUser: req.user
    });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not search user candidates' });
  }
}

async function addUser(req, res) {
  try {
    const {
      rootUserId,
      matrixInstanceId,
      matrixId,
      topNodeEmail,
      childUserId,
      forceParentFallback,
      parentUserId
    } = req.body;
    const resolvedMatrixId = matrixInstanceId || matrixId;
    const data = await MatrixService.addUserToMatrix({
      rootUserId,
      matrixInstanceId: resolvedMatrixId,
      matrixId: resolvedMatrixId,
      topNodeEmail,
      childUserId,
      forceParentFallback,
      parentUserId,
      actorUser: req.user
    });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not add user to matrix' });
  }
}

// NEW: user-facing matrix overview anchored at requester
async function getMyOverview(req, res) {
  try {
    const userId = req.user?.id ?? req.user?.userId;
    const data = await MatrixService.getMyOverview({ userId, actorUser: req.user });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not load matrix overview' });
  }
}

// NEW: admin-only deactivate a matrix instance
async function deactivate(req, res) {
  try {
    const matrixInstanceId =
      req.params.id ||
      req.body?.matrixInstanceId ||
      req.body?.matrixId ||
      req.query?.matrixInstanceId ||
      req.query?.matrixId;

    const data = await MatrixService.deactivate({
      matrixInstanceId,
      actorUser: req.user
    });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not deactivate matrix' });
  }
}

// NEW: admin-only activate a matrix instance
async function activate(req, res) {
  try {
    const matrixInstanceId =
      req.params.id ||
      req.body?.matrixInstanceId ||
      req.body?.matrixId ||
      req.query?.matrixInstanceId ||
      req.query?.matrixId;

    const data = await MatrixService.activate({
      matrixInstanceId,
      actorUser: req.user
    });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not activate matrix' });
  }
}

// NEW: list all matrices current user belongs to
async function listMyMatrices(req, res) {
  try {
    const userId = req.user?.id ?? req.user?.userId;
    const data = await MatrixService.listMyMatrices({ userId, actorUser: req.user });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not load matrices' });
  }
}

// NEW: personal overview for a specific matrix instance
async function getMyOverviewByInstance(req, res) {
  try {
    const userId = req.user?.id ?? req.user?.userId;
    const matrixInstanceId = req.params.id || req.query?.matrixInstanceId || req.query?.matrixId;
    const data = await MatrixService.getMyOverviewByInstance({ userId, matrixInstanceId, actorUser: req.user });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not load matrix overview' });
  }
}

// NEW: personal matrix summary (totals and fill) for a specific instance
async function getMyMatrixSummary(req, res) {
  try {
    const userId = req.user?.id ?? req.user?.userId;
    const matrixInstanceId = req.params.id || req.query?.matrixInstanceId || req.query?.matrixId;
    const data = await MatrixService.getMyMatrixSummary({ userId, matrixInstanceId, actorUser: req.user });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not load matrix summary' });
  }
}

async function removeUser(req, res) {
  try {
    const { matrixInstanceId, userId } = req.body;
    const data = await MatrixService.removeUser({ matrixInstanceId, userId, actorUser: req.user });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not remove user' });
  }
}

async function assignVacancy(req, res) {
  try {
    const { matrixInstanceId, parentUserId, position, userId } = req.body;
    const data = await MatrixService.assignVacancy({ matrixInstanceId, parentUserId, position, userId, actorUser: req.user });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not assign vacancy' });
  }
}

async function listVacancies(req, res) {
  try {
    const matrixInstanceId = req.query.matrixInstanceId || req.query.matrixId || req.query.id;
    const data = await MatrixService.listVacancies({ matrixInstanceId, actorUser: req.user });
    return res.json({ success: true, data });
  } catch (err) {
    const status = err.status || 500;
    return res.status(status).json({ success: false, message: err.message || 'Could not list vacancies' });
  }
}

module.exports = {
  create,
  stats,
  getMatrixUserforAdmin,
  searchCandidates,
  addUser, // NEW
  getMyOverview, // NEW
  deactivate, // NEW
  activate, // NEW
  listMyMatrices, // NEW
  getMyOverviewByInstance, // NEW
  getMyMatrixSummary, // NEW
  removeUser, // NEW
  assignVacancy, // NEW
  listVacancies // NEW
};
