const db = require('../config/db');
const { logAuditFromReq } = require('../middlewares/audit');

/**
 * Get all settings as key-value pairs.
 */
exports.getAll = async (req, res, next) => {
  try {
    const [rows] = await db.query('SELECT `key`, `value` FROM settings ORDER BY `key`');
    const map = {};
    for (const row of rows) {
      map[row.key] = row.value;
    }
    res.json(map);
  } catch (err) {
    next(err);
  }
};

/**
 * Get a single setting by key.
 */
exports.getByKey = async (req, res, next) => {
  try {
    const [rows] = await db.query('SELECT `value` FROM settings WHERE `key` = ?', [req.params.key]);
    if (rows.length === 0) return res.status(404).json({ error: 'Setting not found' });
    res.json({ key: req.params.key, value: rows[0].value });
  } catch (err) {
    next(err);
  }
};

/**
 * Upsert a single setting (create or update).
 * Body: { key, value }
 */
exports.upsert = async (req, res, next) => {
  try {
    const { key, value } = req.body;
    if (!key) return res.status(400).json({ error: 'key is required' });

    await db.query(
      `INSERT INTO settings (\`key\`, \`value\`) VALUES (?, ?)
       ON DUPLICATE KEY UPDATE \`value\` = VALUES(\`value\`), updated_at = NOW()`,
      [key, value != null ? String(value) : null]
    );

    logAuditFromReq(req, 'upsert', 'setting', null, { key, value });

    res.json({ key, value });
  } catch (err) {
    next(err);
  }
};

/**
 * Bulk upsert multiple settings.
 * Body: { settings: { key1: value1, key2: value2, ... } }
 */
exports.bulkUpsert = async (req, res, next) => {
  try {
    const { settings } = req.body;
    if (!settings || typeof settings !== 'object') {
      return res.status(400).json({ error: 'settings object is required' });
    }

    const entries = Object.entries(settings);
    if (entries.length === 0) return res.json({});

    const conn = await db.pool.getConnection();
    try {
      await conn.beginTransaction();
      for (const [key, value] of entries) {
        await conn.query(
          `INSERT INTO settings (\`key\`, \`value\`) VALUES (?, ?)
           ON DUPLICATE KEY UPDATE \`value\` = VALUES(\`value\`), updated_at = NOW()`,
          [key, value != null ? String(value) : null]
        );
      }
      await conn.commit();

      logAuditFromReq(req, 'bulk_upsert', 'setting', null, {
        keys: entries.map(([k]) => k),
      });

      res.json(settings);
    } catch (e) {
      await conn.rollback();
      throw e;
    } finally {
      conn.release();
    }
  } catch (err) {
    next(err);
  }
};
