/**
 * Setting Controller — Mengelola pengaturan aplikasi yang tersimpan di database.
 */
const { logger } = require('nodejs-log-agent');
const db = require('../models');
const { testSmtpConnection } = require('../services/emailService');

/**
 * Mendapatkan semua pengaturan, opsional difilter berdasarkan group.
 * Password tidak dikembalikan valuenya untuk keamanan.
 */
const getSettings = async (req, res) => {
  try {
    const { group } = req.query;
    const where = group ? { group } : {};

    const settings = await db.setting.findAll({
      where,
      order: [['group', 'ASC'], ['key', 'ASC']]
    });

    // Sembunyikan nilai password
    const sanitized = settings.map(s => ({
      id: s.id,
      key: s.key,
      value: s.type === 'password' ? (s.value ? '••••••••' : '') : s.value,
      label: s.label,
      description: s.description,
      type: s.type,
      group: s.group,
      updatedAt: s.updatedAt
    }));

    return res.json({ status: true, data: sanitized });
  } catch (error) {
    logger.error('[Settings] Gagal mengambil pengaturan', { message: error.message, stack: error.stack });
    return res.status(500).json({ status: false, message: error.message });
  }
};

/**
 * Update satu pengaturan berdasarkan key.
 */
const updateSetting = async (req, res) => {
  const { key } = req.params;
  const { value } = req.body;

  if (!key) {
    return res.status(400).json({ status: false, message: 'Setting key is required.' });
  }

  try {
    const setting = await db.setting.findOne({ where: { key } });

    if (!setting) {
      return res.status(404).json({ status: false, message: `Setting '${key}' not found.` });
    }

    await db.setting.update({ value: String(value) }, { where: { key } });

    logger.info(`[Settings] Pengaturan '${key}' diperbarui.`);
    return res.json({ status: true, message: `Pengaturan '${setting.label || key}' berhasil diperbarui.` });
  } catch (error) {
    logger.error(`[Settings] Gagal memperbarui pengaturan '${key}'`, { message: error.message, stack: error.stack });
    return res.status(500).json({ status: false, message: error.message });
  }
};

/**
 * Update banyak pengaturan sekaligus (bulk update).
 * Body: { settings: [ { key: 'xxx', value: 'yyy' }, ... ] }
 */
const updateSettingsBulk = async (req, res) => {
  const { settings } = req.body;

  if (!settings || !Array.isArray(settings) || settings.length === 0) {
    return res.status(400).json({ status: false, message: 'Array settings tidak boleh kosong.' });
  }

  try {
    const updatePromises = settings.map(s =>
      db.setting.update({ value: String(s.value ?? '') }, { where: { key: s.key } })
    );

    await Promise.all(updatePromises);

    logger.info(`[Settings] Bulk update ${settings.length} pengaturan berhasil.`);
    return res.json({ status: true, message: `${settings.length} pengaturan berhasil diperbarui.` });
  } catch (error) {
    logger.error('[Settings] Gagal bulk update pengaturan', { message: error.message, stack: error.stack });
    return res.status(500).json({ status: false, message: error.message });
  }
};

/**
 * Test koneksi SMTP dengan konfigurasi yang diberikan di body request.
 */
const testEmailConnection = async (req, res) => {
  const { host, port, user, pass, secure } = req.body;

  if (!host || !user || !pass) {
    return res.status(400).json({ status: false, message: 'Host, user, dan pass SMTP diperlukan untuk test koneksi.' });
  }

  try {
    await testSmtpConnection({ host, port, user, pass, secure });
    logger.info(`[Settings] Test koneksi SMTP ke ${host}:${port} berhasil.`);
    return res.json({ status: true, message: `Koneksi ke ${host}:${port} berhasil! SMTP siap digunakan.` });
  } catch (error) {
    logger.error(`[Settings] Test koneksi SMTP gagal: ${error.message}`);
    return res.status(400).json({ status: false, message: `Koneksi SMTP gagal: ${error.message}` });
  }
};

module.exports = {
  getSettings,
  updateSetting,
  updateSettingsBulk,
  testEmailConnection
};
