/**
 * School-wide Settings Controller
 *
 * Lightweight key/value surface for school-admin-editable toggles
 * (school_settings table) PLUS a structured list of education-level
 * configurations (education_level_configs table). The configs table
 * is the new source of truth for "which levels does this school run
 * and which grading scale goes with each" — see feature/shapeshift.
 *
 * Exposed today:
 *   Key/value surface (school_settings table):
 *     GET  /api/school-settings                       — all key/value pairs (auth)
 *     GET  /api/school-settings/scales               — list of valid grading scales
 *     GET  /api/school-settings/default-grading-scale — DERIVED: scale of the
 *                                                   active "secondary" config
 *                                                   (or the first active config).
 *                                                   Kept for backwards compat.
 *     PUT  /api/school-settings/default-grading-scale — DERIVED: updates the
 *                                                   active "secondary" config's
 *                                                   scale (school_admin / systems_admin).
 *
 *   Education-level configs (education_level_configs table):
 *     GET  /api/school-settings/education-levels     — canonical enum list
 *                                                   (kept for backwards compat
 *                                                   with the shapeshift client).
 *     GET  /api/school-settings/education-level      — DERIVED: level of the
 *                                                   active "secondary" config.
 *                                                   Kept for backwards compat.
 *     PUT  /api/school-settings/education-level      — DERIVED: update level
 *                                                   metadata of the active
 *                                                   "secondary" config
 *                                                   (school_admin / systems_admin).
 *     GET  /api/school-settings/education-level-configs   — list (active + all)
 *     GET  /api/school-settings/education-level-configs/:uid — one row
 *     POST /api/school-settings/education-level-configs   — create
 *                                                   (school_admin / systems_admin)
 *     PUT  /api/school-settings/education-level-configs/:uid — update
 *                                                   (school_admin / systems_admin)
 *     DELETE /api/school-settings/education-level-configs/:uid — soft delete
 *                                                   (school_admin / systems_admin)
 *
 * Mounted at /api/school-settings in server/src/index.js.
 */

const express = require('express');
const router = express.Router();
const { v4: uuidv4 } = require('uuid');

const dbPath = process.env.DB_PATH || require('path').join(__dirname, '../../data/school.db');
const Database = require('better-sqlite3');
let db;
const getDb = () => {
  if (!db) {
    db = new Database(dbPath);
    db.pragma('foreign_keys = ON');
  }
  return db;
};

// Auth + RBAC middleware (inline to match the codebase convention; see
// .harness/docs/conventions.md §Controller template).
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) {
    res.status(401).json({ error: 'Invalid token' });
  }
};

const adminOnly = (req, res, next) => {
  if (!['school_admin', 'systems_admin'].includes(req.user.role)) {
    return res.status(403).json({ error: 'Admin access required' });
  }
  next();
};

// Lazy require to avoid a circular dep with utils/gradeScales.js
const loadGradeScales = () => require('../utils/gradeScales');

/**
 * @openapi
 * /api/school-settings:
 *   get:
 *     summary: List school-wide settings
 *     description: |
 *       Returns all rows in `school_settings` as a key/value map.
 *       Non-admin users see only the public keys (today that's
 *       `default_grading_scale` — anything that should be hidden from
 *       students / parents stays out of this map).
 *     tags:
 *       - School Settings
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: Key/value map
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               additionalProperties: { type: string }
 *       401: { description: Unauthorized }
 */
router.get('/', auth, (req, res) => {
  try {
    const rows = getDb().prepare(
      'SELECT key, value FROM school_settings WHERE is_deleted = 0'
    ).all();
    const isAdmin = ['school_admin', 'systems_admin'].includes(req.user.role);

    // Restrict the surface for non-admin callers. Today only these keys
    // exist and none are sensitive; the gate is here so future private
    // keys (e.g. payment rail toggle) can be added without another code
    // change. `education_level` is public so the client can shape-shift
    // its terminology for students / parents too.
    const PUBLIC_KEYS = new Set(['default_grading_scale', 'education_level']);
    const out = {};
    for (const r of rows) {
      if (isAdmin || PUBLIC_KEYS.has(r.key)) {
        out[r.key] = r.value;
      }
    }
    res.json(out);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/school-settings/scales:
 *   get:
 *     summary: List available grading scales
 *     description: |
 *       Returns the canonical set of grading scales (ZIMSEC Primary/O/A
 *       + Cambridge IGCSE/AS-A) with their human-readable labels. Use
 *       this to populate the scale dropdown in the admin Settings page
 *       and the per-exam / per-mark override fields.
 *     tags:
 *       - School Settings
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: Array of { value, label, description }
 *         content:
 *           application/json:
 *             schema:
 *               type: array
 *               items:
 *                 type: object
 *                 properties:
 *                   value: { type: string }
 *                   label: { type: string }
 *                   description: { type: string }
 *       401: { description: Unauthorized }
 */
router.get('/scales', auth, (req, res) => {
  try {
    res.json(loadGradeScales().scaleOptions());
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/school-settings/default-grading-scale:
 *   get:
 *     summary: Current default grading scale (derived from active configs)
 *     description: |
 *       Backwards-compatible view. Resolves the grading scale bound to
 *       the active "secondary" config row. If none exists, falls back to
 *       the lowest-sort_order active row, then the resolver's default
 *       (`zimsec_olevel`).
 *     tags:
 *       - School Settings
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: Resolved default
 *       401: { description: Unauthorized }
 */
router.get('/default-grading-scale', auth, (req, res) => {
  try {
    // The "default" is whichever active row has is_default = 1. Falls
    // back to the first active row, then to the resolver's default.
    const row = getDb().prepare(`
      SELECT grading_scale FROM education_level_configs
      WHERE is_default = 1 AND is_active = 1 AND is_deleted = 0
      LIMIT 1
    `).get() || getDb().prepare(`
      SELECT grading_scale FROM education_level_configs
      WHERE is_active = 1 AND is_deleted = 0
      ORDER BY sort_order ASC LIMIT 1
    `).get();
    const { isValidScaleKey, SCALES, DEFAULT_SCALE_KEY } = loadGradeScales();
    const key = isValidScaleKey(row?.grading_scale) ? row.grading_scale : DEFAULT_SCALE_KEY;
    res.json({ value: key, label: SCALES[key].label });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/school-settings/default-grading-scale:
 *   put:
 *     summary: Set the school default grading scale (derived write)
 *     description: |
 *       Backwards-compatible view. Updates the grading scale on the
 *       row currently flagged is_default = 1. If no row is default
 *       yet, sets Secondary as default and updates it. Accepts the
 *       same body as the legacy endpoint. Restricted to school_admin
 *       / systems_admin.
 *     tags:
 *       - School Settings
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               value: { type: string }
 *               default_grading_scale: { type: string, deprecated: true }
 *     responses:
 *       200: { description: New default }
 *       400: { description: Invalid scale key }
 *       403: { description: Admin only }
 */
router.put('/default-grading-scale', auth, adminOnly, (req, res) => {
  try {
    const { isValidScaleKey, SCALES } = loadGradeScales();
    const value = req.body.value ?? req.body.default_grading_scale;
    if (!isValidScaleKey(value)) {
      return res.status(400).json({
        error: `Invalid grading scale: ${value}. Must be one of: ${Object.keys(SCALES).join(', ')}`,
      });
    }

    const database = getDb();
    const existing = database.prepare(`
      SELECT id, uid FROM education_level_configs
      WHERE is_default = 1 AND is_deleted = 0
      LIMIT 1
    `).get();

    if (existing) {
      database.prepare(`
        UPDATE education_level_configs
        SET grading_scale = ?, updated_at = datetime('now', 'localtime'),
            sync_status = 'pending'
        WHERE id = ?
      `).run(value, existing.id);
    } else {
      // Bootstrap: promote Secondary to default + set its scale.
      const secondary = database.prepare(`
        SELECT id FROM education_level_configs
        WHERE level = 'secondary' AND is_deleted = 0
        LIMIT 1
      `).get();
      if (secondary) {
        database.prepare(`
          UPDATE education_level_configs
          SET grading_scale = ?, is_default = 1,
              updated_at = datetime('now', 'localtime'),
              sync_status = 'pending'
          WHERE id = ?
        `).run(value, secondary.id);
      } else {
        // No Secondary row — create one and mark default.
        database.prepare(`
          INSERT INTO education_level_configs
            (uid, level, grading_scale, display_name, sort_order, is_active, is_default)
          VALUES (?, 'secondary', ?, 'Secondary (O-Level)', 20, 1, 1)
        `).run(uuidv4(), value);
      }
    }

    res.json({ value, label: SCALES[value].label });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============================================================
// Education Level — drives the shapeshift terminology switch
// (Primary / Secondary / Tertiary). See shapeshift initiative.
// ============================================================

// Canonical list of education levels. Keep this in sync with the
// client-side terminology resolver (`client/src/lib/terminology.ts` —
// to be added by the next step of the shapeshift work).
const EDUCATION_LEVELS = {
  primary: { label: 'Primary', description: 'Primary school (Grades 1–7). Uses "Subject" and "Grade".' },
  secondary: { label: 'Secondary (O Levels)', description: 'Secondary school O-Level (Forms 1–4 / Grades 8–11). Uses "Subject" and "Form / Class".' },
  high_school: { label: 'High School (A Levels)', description: 'High school A-Level (Forms 5–6 / Lower & Upper Sixth). Uses "Subject" and "Form / Class".' },
  tertiary: { label: 'Tertiary', description: 'Tertiary institution. Uses "Course", "Programme" and "Year/Semester".' },
};
const DEFAULT_EDUCATION_LEVEL = 'secondary';

const isValidEducationLevel = (v) => Object.prototype.hasOwnProperty.call(EDUCATION_LEVELS, v);

/**
 * @openapi
 * /api/school-settings/education-levels:
 *   get:
 *     summary: List valid education levels
 *     description: |
 *       Returns the canonical set of education levels the shapeshift
 *       feature understands. Use this to populate the dropdown in the
 *       admin Settings page.
 *     tags:
 *       - School Settings
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: Array of { value, label, description }
 *         content:
 *           application/json:
 *             schema:
 *               type: array
 *               items:
 *                 type: object
 *                 properties:
 *                   value: { type: string, example: "secondary" }
 *                   label: { type: string, example: "Secondary" }
 *                   description: { type: string }
 *       401: { description: Unauthorized }
 */
router.get('/education-levels', auth, (req, res) => {
  try {
    const out = Object.entries(EDUCATION_LEVELS).map(([value, v]) => ({
      value,
      label: v.label,
      description: v.description,
    }));
    res.json(out);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/school-settings/education-level:
 *   get:
 *     summary: Current school education level (derived)
 *     description: |
 *       Backwards-compatible view. Resolves the level of the active
 *       "secondary" config row. Falls back to "secondary" if no config
 *       exists. Public — students/parents need this for terminology.
 *     tags:
 *       - School Settings
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200: { description: Resolved level }
 *       401: { description: Unauthorized }
 */
router.get('/education-level', auth, (req, res) => {
  try {
    // Resolve the level of the active default row. Falls back to the
    // first active row, then to "secondary" if nothing is configured.
    const row = getDb().prepare(`
      SELECT level FROM education_level_configs
      WHERE is_default = 1 AND is_active = 1 AND is_deleted = 0
      LIMIT 1
    `).get() || getDb().prepare(`
      SELECT level FROM education_level_configs
      WHERE is_active = 1 AND is_deleted = 0
      ORDER BY sort_order ASC LIMIT 1
    `).get();
    const key = isValidEducationLevel(row?.level) ? row.level : DEFAULT_EDUCATION_LEVEL;
    res.json({ value: key, label: EDUCATION_LEVELS[key].label });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/school-settings/education-level:
 *   put:
 *     summary: Set the school education level (derived write)
 *     description: |
 *       Backwards-compatible view. NOTE: this endpoint pre-dates the
 *       multi-config + default-level model. For now, if no row is
 *       flagged default, it bootstraps by promoting the requested
 *       level to default. Use the per-row `is_default` flag on
 *       `/education-level-configs/:uid` to choose the default cleanly.
 *       Restricted to school_admin / systems_admin.
 *     tags:
 *       - School Settings
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               value: { type: string, enum: [primary, secondary, high_school, tertiary] }
 *               education_level: { type: string, deprecated: true }
 *     responses:
 *       200: { description: New level (or default-promoted bootstrap) }
 *       400: { description: Invalid education level }
 *       403: { description: Admin only }
 */
router.put('/education-level', auth, adminOnly, (req, res) => {
  try {
    const value = req.body.value ?? req.body.education_level;
    if (!isValidEducationLevel(value)) {
      return res.status(400).json({
        error: `Invalid education level: ${value}. Must be one of: ${Object.keys(EDUCATION_LEVELS).join(', ')}`,
      });
    }
    // Bootstrap path: ensure the requested level has a row. If no row
    // is currently default, promote this one. (New default selection
    // happens via the per-row is_default toggle on the configs API.)
    const database = getDb();
    const haveDefault = database.prepare(
      'SELECT id FROM education_level_configs WHERE is_default = 1 AND is_deleted = 0 LIMIT 1'
    ).get();
    const existing = database.prepare(`
      SELECT id FROM education_level_configs
      WHERE level = ? AND is_deleted = 0
      LIMIT 1
    `).get(value);
    if (!existing) {
      const defaults = {
        primary: { name: 'Primary',                sort: 10 },
        secondary: { name: 'Secondary (O-Level)',   sort: 20 },
        high_school: { name: 'High School (A-Level)', sort: 30 },
        tertiary: { name: 'Tertiary',              sort: 40 },
      }[value];
      const defaultScale = {
        primary: 'zimsec_primary',
        secondary: 'zimsec_olevel',
        high_school: 'zimsec_alevel',
        tertiary: 'cambridge_alevel',
      }[value];
      database.prepare(`
        INSERT INTO education_level_configs
          (uid, level, grading_scale, display_name, sort_order, is_active)
        VALUES (?, ?, ?, ?, ?, 1)
      `).run(uuidv4(), value, defaultScale, defaults.name, defaults.sort);
    }
    if (!haveDefault) {
      database.prepare(`
        UPDATE education_level_configs
        SET is_default = 1, updated_at = datetime('now', 'localtime'),
            sync_status = 'pending'
        WHERE level = ? AND is_deleted = 0
      `).run(value);
    }
    res.json({ value, label: EDUCATION_LEVELS[value].label });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============================================================
// Education Level Configs — multi-row CRUD (feature/shapeshift)
// ============================================================
//
// One row per education level this school operates. The legacy
// `default-grading-scale` and `education-level` endpoints above are
// kept as derived views off this table for backwards compatibility.

const VALID_LEVELS = Object.keys(EDUCATION_LEVELS);

const configRowToJson = (row, SCALES) => ({
  uid: row.uid,
  level: row.level,
  level_label: EDUCATION_LEVELS[row.level]?.label || row.level,
  grading_scale: row.grading_scale,
  grading_scale_label: SCALES?.[row.grading_scale]?.label || row.grading_scale,
  display_name: row.display_name,
  sort_order: row.sort_order,
  is_active: !!row.is_active,
  is_default: !!row.is_default,
  created_at: row.created_at,
  updated_at: row.updated_at,
});

/**
 * @openapi
 * /api/school-settings/education-level-configs:
 *   get:
 *     summary: List education level configurations
 *     description: |
 *       Returns all active rows ordered by `sort_order` then `level`.
 *       Use `?include_inactive=1` to also fetch soft-disabled rows.
 *     tags:
 *       - School Settings
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: include_inactive
 *         schema: { type: boolean }
 *     responses:
 *       200:
 *         description: Array of config rows
 *       401: { description: Unauthorized }
 */
router.get('/education-level-configs', auth, (req, res) => {
  try {
    const includeInactive = req.query.include_inactive === '1' || req.query.include_inactive === 'true';
    const where = includeInactive ? 'is_deleted = 0' : 'is_active = 1 AND is_deleted = 0';
    const rows = getDb().prepare(`
      SELECT uid, level, grading_scale, display_name, sort_order, is_active,
             is_default, created_at, updated_at
      FROM education_level_configs
      WHERE ${where}
      ORDER BY is_default DESC, sort_order ASC, level ASC
    `).all();
    const { SCALES } = loadGradeScales();
    res.json(rows.map((r) => configRowToJson(r, SCALES)));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/school-settings/education-level-configs/{uid}:
 *   get:
 *     summary: Fetch one config row by uid
 *     tags:
 *       - School Settings
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: uid
 *         required: true
 *         schema: { type: string }
 *     responses:
 *       200: { description: Config row }
 *       404: { description: Not found }
 *       401: { description: Unauthorized }
 */
router.get('/education-level-configs/:uid', auth, (req, res) => {
  try {
    const row = getDb().prepare(`
      SELECT uid, level, grading_scale, display_name, sort_order, is_active,
             is_default, created_at, updated_at
      FROM education_level_configs
      WHERE uid = ? AND is_deleted = 0
      LIMIT 1
    `).get(req.params.uid);
    if (!row) return res.status(404).json({ error: 'Config not found' });
    const { SCALES } = loadGradeScales();
    res.json(configRowToJson(row, SCALES));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/school-settings/education-level-configs:
 *   post:
 *     summary: Create an education level config
 *     description: |
 *       Creates a new row. Body: `{ level, grading_scale, display_name?,
 *       sort_order?, is_active? }`. Rejects duplicate `level` (one
 *       active row per level). Restricted to school_admin / systems_admin.
 *     tags:
 *       - School Settings
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [level, grading_scale]
 *             properties:
 *               level: { type: string, enum: [primary, secondary, high_school, tertiary] }
 *               grading_scale: { type: string }
 *               display_name: { type: string }
 *               sort_order: { type: integer }
 *               is_active: { type: boolean }
 *     responses:
 *       201: { description: Created }
 *       400: { description: Invalid level / scale / duplicate }
 *       403: { description: Admin only }
 */
router.post('/education-level-configs', auth, adminOnly, (req, res) => {
  try {
    const { level, grading_scale, display_name, sort_order, is_active, is_default } = req.body || {};
    if (!isValidEducationLevel(level)) {
      return res.status(400).json({
        error: `Invalid education level: ${level}. Must be one of: ${VALID_LEVELS.join(', ')}`,
      });
    }
    const { isValidScaleKey, SCALES } = loadGradeScales();
    if (!isValidScaleKey(grading_scale)) {
      return res.status(400).json({
        error: `Invalid grading scale: ${grading_scale}. Must be one of: ${Object.keys(SCALES).join(', ')}`,
      });
    }

    const database = getDb();
    const dup = database.prepare(
      'SELECT id FROM education_level_configs WHERE level = ? AND is_deleted = 0 LIMIT 1'
    ).get(level);
    if (dup) {
      return res.status(400).json({
        error: `An education level config already exists for "${level}". Edit the existing row instead.`,
      });
    }

    const uid = uuidv4();
    const sort = Number.isFinite(Number(sort_order)) ? Number(sort_order) : 50;
    const active = is_active === false ? 0 : 1;
    const name = (display_name && String(display_name).trim()) || EDUCATION_LEVELS[level].label;

    const wantsDefault = is_default === true;
    const setDefaultTxn = database.transaction(() => {
      if (wantsDefault) {
        database.prepare('UPDATE education_level_configs SET is_default = 0 WHERE is_default = 1').run();
      }
      database.prepare(`
        INSERT INTO education_level_configs
          (uid, level, grading_scale, display_name, sort_order, is_active, is_default)
        VALUES (?, ?, ?, ?, ?, ?, ?)
      `).run(uid, level, grading_scale, name, sort, active, wantsDefault ? 1 : 0);
    });
    setDefaultTxn();

    const row = database.prepare(
      'SELECT uid, level, grading_scale, display_name, sort_order, is_active, is_default, created_at, updated_at FROM education_level_configs WHERE uid = ?'
    ).get(uid);
    res.status(201).json(configRowToJson(row, SCALES));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/school-settings/education-level-configs/{uid}:
 *   put:
 *     summary: Update an education level config
 *     description: |
 *       Partial update. Body may include any of `grading_scale`,
 *       `display_name`, `sort_order`, `is_active`. `level` itself
 *       cannot be changed — delete + recreate to move a row between
 *       levels. Restricted to school_admin / systems_admin.
 *     tags:
 *       - School Settings
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: uid
 *         required: true
 *         schema: { type: string }
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               grading_scale: { type: string }
 *               display_name: { type: string }
 *               sort_order: { type: integer }
 *               is_active: { type: boolean }
 *     responses:
 *       200: { description: Updated row }
 *       400: { description: Invalid scale }
 *       404: { description: Not found }
 *       403: { description: Admin only }
 */
router.put('/education-level-configs/:uid', auth, adminOnly, (req, res) => {
  try {
    const { SCALES, isValidScaleKey } = loadGradeScales();
    const database = getDb();
    const existing = database.prepare(
      'SELECT id FROM education_level_configs WHERE uid = ? AND is_deleted = 0 LIMIT 1'
    ).get(req.params.uid);
    if (!existing) return res.status(404).json({ error: 'Config not found' });

    const fields = [];
    const values = [];
    if (req.body.grading_scale !== undefined) {
      if (!isValidScaleKey(req.body.grading_scale)) {
        return res.status(400).json({
          error: `Invalid grading scale: ${req.body.grading_scale}. Must be one of: ${Object.keys(SCALES).join(', ')}`,
        });
      }
      fields.push('grading_scale = ?'); values.push(req.body.grading_scale);
    }
    if (req.body.display_name !== undefined) {
      fields.push('display_name = ?'); values.push(String(req.body.display_name).trim() || null);
    }
    if (req.body.sort_order !== undefined) {
      const s = Number(req.body.sort_order);
      if (!Number.isFinite(s)) {
        return res.status(400).json({ error: 'sort_order must be a number' });
      }
      fields.push('sort_order = ?'); values.push(s);
    }
    if (req.body.is_active !== undefined) {
      fields.push('is_active = ?'); values.push(req.body.is_active ? 1 : 0);
    }
    const wantsDefault = req.body.is_default === true;
    const unsetDefault = req.body.is_default === false;

    if (fields.length === 0 && !wantsDefault && !unsetDefault) {
      return res.status(400).json({ error: 'No updatable fields supplied' });
    }

    // Run the toggle + update in a single transaction so the "at most
    // one default" invariant holds across concurrent admins.
    const txn = database.transaction(() => {
      if (wantsDefault) {
        database.prepare('UPDATE education_level_configs SET is_default = 0 WHERE is_default = 1').run();
        fields.push('is_default = ?'); values.push(1);
      } else if (unsetDefault) {
        fields.push('is_default = ?'); values.push(0);
      }
      fields.push("updated_at = datetime('now', 'localtime')");
      fields.push("sync_status = 'pending'");
      database.prepare(`
        UPDATE education_level_configs SET ${fields.join(', ')} WHERE id = ?
      `).run(...values, existing.id);
    });
    txn();

    const row = database.prepare(
      'SELECT uid, level, grading_scale, display_name, sort_order, is_active, is_default, created_at, updated_at FROM education_level_configs WHERE id = ?'
    ).get(existing.id);
    res.json(configRowToJson(row, SCALES));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

/**
 * @openapi
 * /api/school-settings/education-level-configs/{uid}:
 *   delete:
 *     summary: Soft-delete an education level config
 *     tags:
 *       - School Settings
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: uid
 *         required: true
 *         schema: { type: string }
 *     responses:
 *       200: { description: Deleted }
 *       404: { description: Not found }
 *       403: { description: Admin only }
 */
router.delete('/education-level-configs/:uid', auth, adminOnly, (req, res) => {
  try {
    const database = getDb();
    const existing = database.prepare(
      'SELECT id FROM education_level_configs WHERE uid = ? AND is_deleted = 0 LIMIT 1'
    ).get(req.params.uid);
    if (!existing) return res.status(404).json({ error: 'Config not found' });
    database.prepare(`
      UPDATE education_level_configs
      SET is_deleted = 1, is_active = 0, is_default = 0,
          updated_at = datetime('now', 'localtime'),
          sync_status = 'pending'
      WHERE id = ?
    `).run(existing.id);
    res.json({ ok: true, uid: req.params.uid });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

module.exports = router;
