/**
 * Finance — Fee Engine Controller (§10b)
 *
 * Plan-apply and discount-apply are the load-bearing engine endpoints:
 * they turn the CRUD rows from §10a into the actual `student_fees` and
 * `student_fee_discounts` rows that show up on a parent's bill. Two
 * routes: apply (generate / link) and revoke (undo).
 *
 * Student groups CRUD + membership also live here; the group is the
 * unit that both endpoints walk when scope='group'.
 */

const express = require('express');
const { v4: uuidv4 } = require('uuid');
const Database = require('better-sqlite3');
const path = require('path');
const AuditService = require('../services/AuditService');

const db = new Database(process.env.DB_PATH || path.join(__dirname, '../../data/school.db'));
db.pragma('foreign_keys = ON');

const router = express.Router();

const auth = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ error: 'No token provided' });
  try {
    const jwt = require('jsonwebtoken');
    const { jwtSecret: JWT_SECRET } = require('../config');
    req.user = jwt.verify(token, JWT_SECRET);
    next();
  } catch (err) {
    return res.status(401).json({ error: 'Invalid token' });
  }
};

// financeAccess: same as Phase 1 / §10a.
const financeAccess = (req, res, next) => {
  if (!['school_admin', 'systems_admin', 'principal', 'bursar', 'accountant', 'hr'].includes(req.user.role)) {
    return res.status(403).json({ error: 'Finance / accounting role required' });
  }
  next();
};

// ============================================================
// Student groups CRUD
// ============================================================

router.get('/groups', auth, financeAccess, (req, res) => {
  try {
    const { type, search } = req.query;
    let sql = `
      SELECT g.*, c.name AS class_name,
             (SELECT COUNT(*) FROM student_group_members m WHERE m.group_id = g.id AND m.is_deleted = 0) AS member_count
      FROM student_groups g
      LEFT JOIN classes c ON g.class_id = c.id
      WHERE g.is_deleted = 0
    `;
    const params = [];
    if (type) { sql += ' AND g.type = ?'; params.push(type); }
    if (search) {
      sql += ' AND (g.name LIKE ? OR g.description LIKE ?)';
      const like = `%${search}%`;
      params.push(like, like);
    }
    sql += ' ORDER BY g.created_at DESC';
    res.json(db.prepare(sql).all(...params));
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

router.get('/groups/:uid', auth, financeAccess, (req, res) => {
  try {
    const head = db.prepare(`
      SELECT g.*, c.name AS class_name
      FROM student_groups g LEFT JOIN classes c ON g.class_id = c.id
      WHERE g.uid = ? AND g.is_deleted = 0
    `).get(req.params.uid);
    if (!head) return res.status(404).json({ error: 'Group not found' });
    const members = db.prepare(`
      SELECT m.uid AS member_uid, m.joined_at,
             u.id AS student_id, u.uid AS student_uid,
             u.first_name, u.last_name, u.email
      FROM student_group_members m
      JOIN users u ON m.student_id = u.id
      WHERE m.group_id = ? AND m.is_deleted = 0 AND u.is_deleted = 0
      ORDER BY u.first_name, u.last_name
    `).all(head.id);
    res.json({ ...head, members });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

router.post('/groups', auth, financeAccess, async (req, res) => {
  try {
    const { name, description, type, color, class_id, capacity, auto_track_class } = req.body;
    if (!name) return res.status(400).json({ error: 'name is required' });
    let classId = null;
    if (class_id) {
      const c = db.prepare('SELECT id FROM classes WHERE id = ? AND is_deleted = 0').get(Number(class_id));
      if (!c) return res.status(400).json({ error: 'class_id not found' });
      classId = c.id;
    }

    const uid = uuidv4();
    db.prepare(`
      INSERT INTO student_groups (
        uid, name, description, type, color, class_id, capacity, auto_track_class, created_by
      ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    `).run(
      uid, name, description || null,
      ['class', 'trip', 'hostel', 'transport', 'club', 'fee', 'custom'].includes(type) ? type : 'custom',
      color || null,
      classId, capacity ? Number(capacity) : null,
      auto_track_class ? 1 : 0,
      req.user.id,
    );

    // Auto-fill members if class_id + auto_track_class.
    if (classId && auto_track_class) {
      const enrolls = db.prepare(`
        SELECT DISTINCT u.id FROM users u
        JOIN enrollments e ON e.student_id = u.id
        WHERE e.class_id = ? AND e.status = 'active' AND e.is_deleted = 0
          AND u.role = 'student' AND u.is_deleted = 0
      `).all(classId);
      const ins = db.prepare(`INSERT OR IGNORE INTO student_group_members (uid, group_id, student_id) VALUES (?, ?, ?)`);
      enrolls.forEach((r) => ins.run(uuidv4(), db.prepare('SELECT id FROM student_groups WHERE uid = ?').get(uid).id, r.id));
    }

    await AuditService.log(req, 'CREATE_STUDENT_GROUP', { entityType: 'student_group', entityId: uid, newData: { name, type, auto_track_class: !!auto_track_class } });
    const row = db.prepare('SELECT * FROM student_groups WHERE uid = ?').get(uid);
    res.status(201).json(row);
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

router.patch('/groups/:uid', auth, financeAccess, async (req, res) => {
  try {
    const existing = db.prepare('SELECT id FROM student_groups WHERE uid = ? AND is_deleted = 0').get(req.params.uid);
    if (!existing) return res.status(404).json({ error: 'Group not found' });
    const updates = [];
    const params = [];
    for (const f of ['name', 'description', 'type', 'color', 'capacity']) {
      if (req.body[f] !== undefined) { updates.push(`${f} = ?`); params.push(req.body[f]); }
    }
    if (req.body.class_id !== undefined) {
      if (req.body.class_id === null) {
        updates.push('class_id = NULL');
      } else {
        const c = db.prepare('SELECT id FROM classes WHERE id = ?').get(Number(req.body.class_id));
        if (!c) return res.status(400).json({ error: 'class_id not found' });
        updates.push('class_id = ?'); params.push(c.id);
      }
    }
    if (req.body.auto_track_class !== undefined) {
      updates.push('auto_track_class = ?'); params.push(req.body.auto_track_class ? 1 : 0);
    }
    if (updates.length === 0) return res.status(400).json({ error: 'No updatable fields supplied' });
    updates.push('updated_at = datetime(\'now\',\'localtime\')', 'sync_status = ?'); params.push('pending');
    params.push(req.params.uid);
    db.prepare(`UPDATE student_groups SET ${updates.join(', ')} WHERE uid = ?`).run(...params);
    await AuditService.log(req, 'UPDATE_STUDENT_GROUP', { entityType: 'student_group', entityId: req.params.uid });
    res.json(db.prepare('SELECT * FROM student_groups WHERE uid = ?').get(req.params.uid));
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

router.delete('/groups/:uid', auth, financeAccess, async (req, res) => {
  try {
    const existing = db.prepare('SELECT id FROM student_groups WHERE uid = ? AND is_deleted = 0').get(req.params.uid);
    if (!existing) return res.status(404).json({ error: 'Group not found' });
    db.prepare(`
      UPDATE student_groups
      SET is_deleted = 1, sync_status = 'pending', last_synced_at = NULL, updated_at = datetime('now','localtime')
      WHERE id = ?
    `).run(existing.id);
    db.prepare(`
      UPDATE student_group_members
      SET is_deleted = 1, sync_status = 'pending', last_synced_at = NULL
      WHERE group_id = ?
    `).run(existing.id);
    res.json({ success: true });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

// Group membership: bulk add (ids / class / all).
router.post('/groups/:uid/members', auth, financeAccess, async (req, res) => {
  try {
    const group = db.prepare('SELECT id FROM student_groups WHERE uid = ? AND is_deleted = 0').get(req.params.uid);
    if (!group) return res.status(404).json({ error: 'Group not found' });
    const { mode, student_uids, class_id } = req.body;
    let studentIds = [];
    if (mode === 'ids') {
      if (!Array.isArray(student_uids) || student_uids.length === 0) {
        return res.status(400).json({ error: 'student_uids[] is required for mode=ids' });
      }
      const placeholders = student_uids.map(() => '?').join(',');
      studentIds = db.prepare(`SELECT id FROM users WHERE uid IN (${placeholders}) AND role='student' AND is_deleted=0`)
        .all(...student_uids).map((r) => r.id);
    } else if (mode === 'class') {
      if (!class_id) return res.status(400).json({ error: 'class_id is required for mode=class' });
      studentIds = db.prepare(`
        SELECT DISTINCT u.id FROM users u
        JOIN enrollments e ON e.student_id = u.id
        WHERE e.class_id = ? AND e.status = 'active' AND e.is_deleted = 0
          AND u.role = 'student' AND u.is_deleted = 0
      `).all(Number(class_id)).map((r) => r.id);
    } else if (mode === 'all') {
      studentIds = db.prepare(`SELECT id FROM users WHERE role='student' AND is_deleted = 0`).all().map((r) => r.id);
    } else {
      return res.status(400).json({ error: "mode must be one of 'ids' | 'class' | 'all'" });
    }
    if (studentIds.length === 0) return res.json({ added: 0, skipped: 0 });

    let added = 0;
    let skipped = 0;
    const ins = db.prepare(`INSERT OR IGNORE INTO student_group_members (uid, group_id, student_id) VALUES (?, ?, ?)`);
    const tx = db.transaction((ids) => {
      for (const sid of ids) {
        try {
          ins.run(uuidv4(), group.id, sid);
          added++;
        } catch (e2) {
          if (String(e2.message).includes('UNIQUE')) skipped++;
          else throw e2;
        }
      }
    });
    tx(studentIds);

    const total = db.prepare('SELECT COUNT(*) AS n FROM student_group_members WHERE group_id = ? AND is_deleted = 0').get(group.id).n;
    await AuditService.log(req, 'ADD_GROUP_MEMBERS', {
      entityType: 'student_group', entityId: req.params.uid, newData: { mode, added, skipped },
    });
    res.json({ added, skipped, total });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

router.delete('/groups/:uid/members/:studentUid', auth, financeAccess, async (req, res) => {
  try {
    const group = db.prepare('SELECT id FROM student_groups WHERE uid = ? AND is_deleted = 0').get(req.params.uid);
    if (!group) return res.status(404).json({ error: 'Group not found' });
    const student = db.prepare('SELECT id FROM users WHERE uid = ?').get(req.params.studentUid);
    if (!student) return res.status(404).json({ error: 'Student not found' });
    const r = db.prepare(`
      UPDATE student_group_members
      SET is_deleted = 1, sync_status = 'pending', last_synced_at = NULL
      WHERE group_id = ? AND student_id = ?
    `).run(group.id, student.id);
    if (r.changes === 0) return res.status(404).json({ error: 'Membership not found' });
    res.json({ success: true });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

// ============================================================
// Plan apply + revoke — the load-bearing endpoints
// ============================================================
//
// Body: { scope: 'student'|'group'|'class', scope_uid_or_id, academic_year?,
//         due_date_offset_days?: 0, fee_group_id_override?: number }
//
// For each recipient, materialise N student_fees rows (one per
// installment) and one row per (student_fee, fee_group) on the student
// side. Wrapped in db.transaction() — partial commits are not desired.

router.post('/plans/:uid/apply', auth, financeAccess, async (req, res) => {
  try {
    const plan = db.prepare(`
      SELECT p.*, fg.id AS fee_group_id_real
      FROM fee_plans p JOIN fee_groups fg ON p.fee_group_id = fg.id
      WHERE p.uid = ? AND p.is_deleted = 0
    `).get(req.params.uid);
    if (!plan) return res.status(404).json({ error: 'Fee plan not found' });

    const installments = db.prepare(`
      SELECT * FROM fee_plan_installments
      WHERE fee_plan_id = ? AND is_deleted = 0 ORDER BY sequence ASC
    `).all(plan.id);
    if (installments.length === 0) return res.status(400).json({ error: 'Plan has no installments to apply' });

    const { scope, scope_uid, academic_year, due_date_offset_days } = req.body;
    if (!['student', 'group', 'class'].includes(scope)) {
      return res.status(400).json({ error: "scope must be 'student'|'group'|'class'" });
    }

    // Resolve recipient set.
    let studentIds = [];
    if (scope === 'student') {
      if (!scope_uid) return res.status(400).json({ error: 'scope_uid is required' });
      const s = db.prepare('SELECT id FROM users WHERE uid = ? AND role = ? AND is_deleted = 0').get(scope_uid, 'student');
      if (!s) return res.status(400).json({ error: 'student not found' });
      studentIds = [s.id];
    } else if (scope === 'group') {
      if (!scope_uid) return res.status(400).json({ error: 'scope_uid is required' });
      const g = db.prepare('SELECT id FROM student_groups WHERE uid = ? AND is_deleted = 0').get(scope_uid);
      if (!g) return res.status(400).json({ error: 'group not found' });
      studentIds = db.prepare(`
        SELECT student_id AS id FROM student_group_members
        WHERE group_id = ? AND is_deleted = 0
      `).all(g.id).map((r) => r.id);
    } else if (scope === 'class') {
      if (!scope_uid) return res.status(400).json({ error: 'scope_uid is required' });
      const c = db.prepare('SELECT id FROM classes WHERE id = ?').get(Number(scope_uid));
      if (!c) return res.status(400).json({ error: 'class not found' });
      studentIds = db.prepare(`
        SELECT DISTINCT u.id FROM users u
        JOIN enrollments e ON e.student_id = u.id
        WHERE e.class_id = ? AND e.status = 'active' AND e.is_deleted = 0
          AND u.role = 'student' AND u.is_deleted = 0
      `).all(c.id).map((r) => r.id);
    }
    if (studentIds.length === 0) return res.status(400).json({ error: 'No recipients resolved' });

    const offset = Number(due_date_offset_days) || 0;
    const ay = academic_year || plan.academic_year || null;
    const feeGroupId = req.body.fee_group_id_override || plan.fee_group_id;

    // Insert fee rows idempotently — UNIQUE doesn't help here (different
    // uids per row), so we check for existing installments with the same
    // (student, plan, installment sequence) and skip.
    let created = 0;
    let skipped = 0;
    const insFee = db.prepare(`
      INSERT INTO student_fees (
        uid, student_id, fee_group_id, plan_id,
        amount, due_date, status, sync_status
      ) VALUES (?, ?, ?, ?, ?, ?, 'pending', 'pending')
    `);
    const findExisting = db.prepare(`
      SELECT id FROM student_fees
      WHERE student_id = ? AND plan_id = ? AND due_date = ?
        AND is_deleted = 0 LIMIT 1
    `);
    const tx = db.transaction((ids) => {
      for (const sid of ids) {
        for (const ins of installments) {
          const shifted = shiftDate(ins.due_date, offset);
          const existing = findExisting.get(sid, plan.id, shifted || ins.due_date);
          if (existing) { skipped++; continue; }
          insFee.run(uuidv4(), sid, feeGroupId, plan.id, Number(ins.amount) || 0, shifted || ins.due_date);
          created++;
        }
      }
    });
    tx(studentIds);

    await AuditService.log(req, 'APPLY_FEE_PLAN', {
      entityType: 'fee_plan', entityId: req.params.uid,
      newData: { scope, recipients: studentIds.length, created, skipped },
    });

    res.json({ scope, recipients: studentIds.length, installments_count: installments.length, created, skipped });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

// Shift YYYY-MM-DD by N days. Returns null on null/parseable input.
function shiftDate(d, days) {
  if (!d) return null;
  const t = new Date(d);
  if (Number.isNaN(t.getTime())) return null;
  t.setDate(t.getDate() + days);
  return t.toISOString().slice(0, 10);
}

// Plan REVOKE — only unlinks student_fees rows whose plan_id matches.
// Refunds (if any) are out of scope; this is a manual op.
router.post('/plans/:uid/revoke', auth, financeAccess, async (req, res) => {
  try {
    const plan = db.prepare('SELECT id FROM fee_plans WHERE uid = ? AND is_deleted = 0').get(req.params.uid);
    if (!plan) return res.status(404).json({ error: 'Fee plan not found' });
    const r = db.prepare(`
      UPDATE student_fees
      SET is_deleted = 1, sync_status = 'pending', last_synced_at = NULL,
          updated_at = datetime('now','localtime')
      WHERE plan_id = ? AND is_deleted = 0 AND paid_amount = 0
    `).run(plan.id);
    const removed = r.changes;
    await AuditService.log(req, 'REVOKE_FEE_PLAN', { entityType: 'fee_plan', entityId: req.params.uid, newData: { removed } });
    res.json({ removed });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

// ============================================================
// Discount apply + revoke
// ============================================================
//
// Body: { scope: 'student'|'group'|'fee_group'|'all', scope_uid_or_id,
//         academic_year?: string, valid_from?: date, valid_to?: date }
// Walks recipients, computes per-fee discount amount, and inserts / updates
// rows on student_fee_discounts. Multiple discounts may stack on the same
// fee line — caller is responsible for ordering. Server enforces a hard
// cap of 90% on percent discounts.

router.post('/discounts/:uid/apply', auth, financeAccess, async (req, res) => {
  try {
    const discount = db.prepare('SELECT * FROM discounts WHERE uid = ? AND is_deleted = 0').get(req.params.uid);
    if (!discount) return res.status(404).json({ error: 'Discount not found' });

    const { scope, scope_uid, class_id, academic_year, valid_from, valid_to, cap_percent } = req.body;
    if (!['student', 'group', 'fee_group', 'all'].includes(discount.scope)) {
      return res.status(400).json({ error: 'discount.scope is invalid' });
    }
    if (!['student', 'group', 'fee_group', 'all'].includes(scope || discount.scope)) {
      return res.status(400).json({ error: "scope must match discount.scope or be 'all'" });
    }

    // Resolve student IDs.
    let studentIds = [];
    const effectiveScope = scope || discount.scope;
    const effectiveScopeId = scope_uid ? Number(scope_uid) : discount.scope_id;
    if (effectiveScope === 'all') {
      studentIds = db.prepare(`SELECT id FROM users WHERE role = 'student' AND is_deleted = 0`).all().map((r) => r.id);
    } else if (effectiveScope === 'student') {
      const s = db.prepare('SELECT id FROM users WHERE uid = ?').get(scope_uid || '');
      if (!s) return res.status(400).json({ error: 'student not found' });
      studentIds = [s.id];
    } else if (effectiveScope === 'group') {
      const g = db.prepare('SELECT id FROM student_groups WHERE uid = ? AND is_deleted = 0').get(scope_uid || '');
      if (!g) return res.status(400).json({ error: 'group not found' });
      studentIds = db.prepare(`
        SELECT student_id AS id FROM student_group_members
        WHERE group_id = ? AND is_deleted = 0
      `).all(g.id).map((r) => r.id);
    } else if (effectiveScope === 'fee_group') {
      const fg = db.prepare('SELECT id FROM fee_groups WHERE id = ?').get(Number(scope_uid || discount.scope_id));
      if (!fg) return res.status(400).json({ error: 'fee_group not found' });
      studentIds = db.prepare(`
        SELECT DISTINCT student_id AS id FROM student_fees
        WHERE fee_group_id = ? AND is_deleted = 0
      `).all(fg.id).map((r) => r.id);
    }
    if (studentIds.length === 0) return res.status(400).json({ error: 'No recipients resolved' });

    // For each recipient, find their fee lines matching the optional
    // fee_group scope_id. We use ALL fee lines per recipient unless the
    // discount is scoped to fee_group, in which case we only target that
    // fee_group.
    const targetFeeGroupId = effectiveScope === 'fee_group'
      ? Number(scope_uid || discount.scope_id)
      : null;

    let applied = 0;
    let skipped = 0;
    let totalAmount = 0;

    const findFees = db.prepare(`
      SELECT id, amount, paid_amount, discount_amount FROM student_fees
      WHERE student_id = ? AND is_deleted = 0
        ${targetFeeGroupId ? 'AND fee_group_id = ?' : ''}
    `);
    const existingApply = db.prepare(`
      SELECT id, amount_applied FROM student_fee_discounts
      WHERE student_fee_id = ? AND discount_id = ? AND is_deleted = 0 LIMIT 1
    `);
    const insLink = db.prepare(`
      INSERT INTO student_fee_discounts (
        uid, student_fee_id, discount_id, amount_applied, applied_by
      ) VALUES (?, ?, ?, ?, ?)
    `);
    const updLink = db.prepare(`
      UPDATE student_fee_discounts
      SET amount_applied = ?, applied_by = ?, applied_at = datetime('now','localtime'),
          sync_status = 'pending'
      WHERE id = ?
    `);
    const updFeeDisc = db.prepare(`
      UPDATE student_fees SET discount_amount = ?, sync_status = 'pending',
                              updated_at = datetime('now','localtime')
      WHERE id = ?
    `);

    const cap = (cap_percent === undefined ? 90 : Number(cap_percent)); // server-side percent cap
    const ay = academic_year || discount.academic_year || null;

    const tx = db.transaction((ids) => {
      for (const sid of ids) {
        const fees = targetFeeGroupId
          ? findFees.all(sid, targetFeeGroupId)
          : findFees.all(sid);
        for (const f of fees) {
          const feeAmount = Number(f.amount) || 0;
          const existingDisc = Number(f.discount_amount) || 0;
          const capAbsolute = (cap / 100) * feeAmount;
          const remainingCap = Math.max(0, capAbsolute - existingDisc);

          let thisApply = 0;
          if (discount.kind === 'percent') {
            const rawAmount = (Number(discount.value) / 100) * feeAmount;
            thisApply = Math.min(rawAmount, remainingCap);
          } else {
            // fixed
            thisApply = Math.min(Number(discount.value) || 0, remainingCap);
          }
          thisApply = Math.round(thisApply * 100) / 100;
          if (thisApply <= 0) { skipped++; continue; }

          const already = existingApply.get(f.id, discount.id);
          if (already) {
            updLink.run(thisApply, req.user.id, already.id);
          } else {
            insLink.run(uuidv4(), f.id, discount.id, thisApply, req.user.id);
          }
          // Re-aggregate total discount on the fee. Sum all live links.
          const sumRow = db.prepare(`
            SELECT COALESCE(SUM(amount_applied), 0) AS total
            FROM student_fee_discounts
            WHERE student_fee_id = ? AND is_deleted = 0
          `).get(f.id);
          updFeeDisc.run(Number(sumRow.total) || 0, f.id);
          applied++;
          totalAmount += thisApply;
        }
      }
    });
    tx(studentIds);

    await AuditService.log(req, 'APPLY_DISCOUNT', {
      entityType: 'discount', entityId: req.params.uid, newData: { scope, applied, skipped, totalAmount },
    });

    res.json({ applied, skipped, total_amount: Math.round(totalAmount * 100) / 100, recipients: studentIds.length });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

router.post('/discounts/:uid/revoke', auth, financeAccess, async (req, res) => {
  try {
    const discount = db.prepare('SELECT id FROM discounts WHERE uid = ? AND is_deleted = 0').get(req.params.uid);
    if (!discount) return res.status(404).json({ error: 'Discount not found' });

    let removed = 0;
    let reAggregated = 0;

    const links = db.prepare(`
      SELECT id, student_fee_id FROM student_fee_discounts
      WHERE discount_id = ? AND is_deleted = 0
    `).all(discount.id);

    const softDel = db.prepare(`
      UPDATE student_fee_discounts
      SET is_deleted = 1, sync_status = 'pending', last_synced_at = NULL
      WHERE id = ?
    `);
    const sumDisc = db.prepare(`
      SELECT COALESCE(SUM(amount_applied), 0) AS total
      FROM student_fee_discounts WHERE student_fee_id = ? AND is_deleted = 0
    `);
    const updFee = db.prepare(`
      UPDATE student_fees SET discount_amount = ?, sync_status = 'pending',
                              updated_at = datetime('now','localtime') WHERE id = ?
    `);
    const tx = db.transaction((rows) => {
      for (const r of rows) {
        softDel.run(r.id);
        const sum = sumDisc.get(r.student_fee_id);
        updFee.run(Number(sum.total) || 0, r.student_fee_id);
        removed++;
        reAggregated++;
      }
    });
    tx(links);

    await AuditService.log(req, 'REVOKE_DISCOUNT', {
      entityType: 'discount', entityId: req.params.uid, newData: { removed, reAggregated },
    });
    res.json({ removed, re_aggregated: reAggregated });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

module.exports = router;
