import { decideChangeRequest, getChangeRequest, listChangeRequests } from '../models/changeRequestModel.js';
import { getConnectionGovernance, intuneReportingOverview, listGraphAudit } from '../models/graphModel.js';
import { loadIntuneDeployment } from '../models/psadtModel.js';
import { canApprove } from '../services/graphRbac.js';

export function changeRequests(req, res) {
  res.json(listChangeRequests(req.user.id, { status: req.query.status, isAdmin: req.user.role === 'admin' }));
}

// Admins can always decide; otherwise the user must be a named approver on the
// request's Graph connection.
function authorizedApprover(req, request) {
  if (req.user.role === 'admin') return true;
  const governance = request.connectionId ? getConnectionGovernance(request.connectionId) : null;
  return canApprove({ approverIds: governance?.approverIds || [] }, req.user);
}

function decide(req, res, status) {
  const request = getChangeRequest(req.params.id);
  if (!request || request.status !== 'pending') return res.status(404).json({ error: 'Pending change request not found' });
  if (!authorizedApprover(req, request)) return res.status(403).json({ error: 'You are not an authorized approver for this connection.' });
  const decided = decideChangeRequest(req.params.id, {
    status,
    approverUserId: req.user.id,
    approverEmail: req.user.email,
    reason: req.body?.reason || ''
  });
  if (!decided) return res.status(404).json({ error: 'Pending change request not found' });
  res.json(decided);
}

export function approveChangeRequest(req, res) {
  decide(req, res, 'approved');
}

export function rejectChangeRequest(req, res) {
  decide(req, res, 'rejected');
}

export function reportingOverview(req, res) {
  res.json(intuneReportingOverview(req.user.id, req.user.role === 'admin'));
}

function toCsv(rows) {
  const headers = ['createdAt', 'action', 'status', 'actorEmail', 'targetGraphId', 'message'];
  const escape = (value) => `"${String(value ?? '').replace(/"/g, '""')}"`;
  const lines = [headers.join(',')];
  for (const row of rows) lines.push(headers.map((h) => escape(row[h])).join(','));
  return lines.join('\n');
}

// CSV export of the tenant write-back audit trail for one deployment.
export function auditExport(req, res) {
  const deployment = loadIntuneDeployment(req.params.id, req.user.id);
  if (!deployment) return res.status(404).json({ error: 'Intune deployment not found' });
  const rows = listGraphAudit({ deploymentId: deployment.id, limit: 1000 });
  res.setHeader('Content-Type', 'text/csv; charset=utf-8');
  res.setHeader('Content-Disposition', `attachment; filename="audit-${deployment.id}.csv"`);
  res.send(toCsv(rows));
}
