/**
 * Settings Controller
 * System configuration and preferences
 */

const express = require('express');
const router = express.Router();

// Database path
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 middleware
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 JWT_SECRET = process.env.JWT_SECRET || 'africa-alert-secret-key-2024';
    req.user = jwt.verify(token, JWT_SECRET);
    next();
  } catch (err) {
    res.status(401).json({ error: 'Invalid token' });
  }
};

// Admin-only middleware
const adminOnly = (req, res, next) => {
  if (req.user.role !== 'admin') {
    return res.status(403).json({ error: 'Admin access required' });
  }
  next();
};

// ============ SYSTEM SETTINGS ============

// Get all settings (for admin) or public settings (for all users)
router.get('/', auth, (req, res) => {
  try {
    const { category } = req.query;
    
    let query = 'SELECT key, value, description, category FROM system_settings WHERE is_deleted = 0';
    const params = [];
    
    // Non-admins only see general settings
    if (req.user.role !== 'admin') {
      query += " AND category IN ('general', 'academic')";
    }
    
    if (category) {
      query += ' AND category = ?';
      params.push(category);
    }
    
    const settings = getDb().prepare(query).all(...params);
    
    // Convert to key-value object
    const result = settings.reduce((acc, s) => {
      acc[s.key] = s.value;
      return acc;
    }, {});
    
    res.json(result);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Get single setting
router.get('/:key', auth, (req, res) => {
  try {
    const setting = getDb().prepare(`
      SELECT key, value, description, category
      FROM system_settings
      WHERE key = ? AND is_deleted = 0
    `).get(req.params.key);
    
    if (!setting) {
      return res.status(404).json({ error: 'Setting not found' });
    }
    
    // Non-admins can't see sensitive settings
    if (req.user.role !== 'admin' && ['payment', 'sync', 'security'].includes(setting.category)) {
      return res.status(403).json({ error: 'Access denied' });
    }
    
    res.json(setting);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Update/create setting (admin only)
router.put('/:key', auth, adminOnly, (req, res) => {
  try {
    const { value, description, category } = req.body;
    
    if (value === undefined) {
      return res.status(400).json({ error: 'Value is required' });
    }
    
    // Check if setting exists
    const existing = getDb().prepare('SELECT id FROM system_settings WHERE key = ?').get(req.params.key);
    
    if (existing) {
      getDb().prepare(`
        UPDATE system_settings SET
          value = ?,
          description = COALESCE(?, description),
          category = COALESCE(?, category),
          updated_at = CURRENT_TIMESTAMP,
          sync_status = 'pending'
        WHERE key = ?
      `).run(value, description, category, req.params.key);
    } else {
      getDb().prepare(`
        INSERT INTO system_settings (key, value, description, category)
        VALUES (?, ?, ?, ?)
      `).run(req.params.key, value, description || '', category || 'general');
    }
    
    const setting = getDb().prepare('SELECT * FROM system_settings WHERE key = ?').get(req.params.key);
    res.json(setting);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Delete setting (admin only)
router.delete('/:key', auth, adminOnly, (req, res) => {
  try {
    // Soft delete
    getDb().prepare(`
      UPDATE system_settings SET is_deleted = 1, updated_at = CURRENT_TIMESTAMP, sync_status = 'pending'
      WHERE key = ?
    `).run(req.params.key);
    
    res.json({ success: true, message: 'Setting deleted' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ BULK OPERATIONS ============

// Bulk update settings
router.put('/', auth, adminOnly, (req, res) => {
  try {
    const { settings } = req.body;
    
    if (!settings || typeof settings !== 'object') {
      return res.status(400).json({ error: 'Settings object required' });
    }
    
    const updateMany = getDb().transaction((settings) => {
      const results = [];
      for (const [key, value] of Object.entries(settings)) {
        try {
          const existing = getDb().prepare('SELECT id FROM system_settings WHERE key = ?').get(key);
          
          if (existing) {
            getDb().prepare(`
              UPDATE system_settings SET value = ?, updated_at = CURRENT_TIMESTAMP, sync_status = 'pending'
              WHERE key = ?
            `).run(String(value), key);
          } else {
            getDb().prepare(`
              INSERT INTO system_settings (key, value, category)
              VALUES (?, ?, 'general')
            `).run(key, String(value));
          }
          
          results.push({ key, success: true });
        } catch (e) {
          results.push({ key, success: false, error: e.message });
        }
      }
      return results;
    });
    
    const results = updateMany(settings);
    res.json({ updated: results.filter(r => r.success).length, results });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ PREDEFINED SETTINGS ============

// Get academic settings
router.get('/academic', auth, (req, res) => {
  try {
    const settings = getDb().prepare(`
      SELECT key, value FROM system_settings
      WHERE category = 'academic' AND is_deleted = 0
    `).all();
    
    res.json(settings.reduce((acc, s) => { acc[s.key] = s.value; return acc; }, {}));
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Get payment settings
router.get('/payment', auth, adminOnly, (req, res) => {
  try {
    const settings = getDb().prepare(`
      SELECT key, value FROM system_settings
      WHERE category = 'payment' AND is_deleted = 0
    `).all();
    
    // Mask sensitive values
    const masked = settings.reduce((acc, s) => {
      if (s.key.includes('key') || s.key.includes('secret') || s.key.includes('password')) {
        acc[s.key] = s.value ? '***' : '';
      } else {
        acc[s.key] = s.value;
      }
      return acc;
    }, {});
    
    res.json(masked);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Update payment settings
router.put('/payment', auth, adminOnly, (req, res) => {
  try {
    const { paynow_integration_id, paynow_integration_key, paynow_callback_url } = req.body;
    
    const upsert = (key, value) => {
      const existing = getDb().prepare('SELECT id FROM system_settings WHERE key = ?').get(key);
      if (existing) {
        getDb().prepare('UPDATE system_settings SET value = ?, updated_at = CURRENT_TIMESTAMP WHERE key = ?').run(value, key);
      } else {
        getDb().prepare('INSERT INTO system_settings (key, value, category) VALUES (?, ?, ?)').run(key, value, 'payment');
      }
    };
    
    if (paynow_integration_id !== undefined) upsert('paynow_integration_id', paynow_integration_id);
    if (paynow_integration_key !== undefined) upsert('paynow_integration_key', paynow_integration_key);
    if (paynow_callback_url !== undefined) upsert('paynow_callback_url', paynow_callback_url);
    
    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Get sync settings
router.get('/sync', auth, adminOnly, (req, res) => {
  try {
    const settings = getDb().prepare(`
      SELECT key, value FROM system_settings
      WHERE category = 'sync' AND is_deleted = 0
    `).all();
    
    // Mask sensitive values
    const masked = settings.reduce((acc, s) => {
      if (s.key.includes('key') || s.key.includes('secret') || s.key.includes('password')) {
        acc[s.key] = s.value ? '***' : '';
      } else {
        acc[s.key] = s.value;
      }
      return acc;
    }, {});
    
    res.json(masked);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Update sync settings
router.put('/sync', auth, adminOnly, (req, res) => {
  try {
    const { supabase_url, supabase_key, sync_interval_seconds } = req.body;
    
    const upsert = (key, value) => {
      const existing = getDb().prepare('SELECT id FROM system_settings WHERE key = ?').get(key);
      if (existing) {
        getDb().prepare('UPDATE system_settings SET value = ?, updated_at = CURRENT_TIMESTAMP WHERE key = ?').run(value, key);
      } else {
        getDb().prepare('INSERT INTO system_settings (key, value, category) VALUES (?, ?, ?)').run(key, value, 'sync');
      }
    };
    
    if (supabase_url !== undefined) upsert('supabase_url', supabase_url);
    if (supabase_key !== undefined) upsert('supabase_key', supabase_key);
    if (sync_interval_seconds !== undefined) upsert('sync_interval_seconds', sync_interval_seconds);
    
    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============ DEFAULT SETTINGS ============

// Reset to defaults
router.post('/reset', auth, adminOnly, (req, res) => {
  try {
    const defaults = {
      school_name: 'Africa Alert School',
      academic_year: new Date().getFullYear().toString(),
      currency: 'USD',
      sync_interval_seconds: '30'
    };
    
    const updateMany = getDb().transaction((defaults) => {
      for (const [key, value] of Object.entries(defaults)) {
        const existing = getDb().prepare('SELECT id FROM system_settings WHERE key = ?').get(key);
        if (existing) {
          getDb().prepare('UPDATE system_settings SET value = ?, updated_at = CURRENT_TIMESTAMP WHERE key = ?').run(value, key);
        } else {
          getDb().prepare('INSERT INTO system_settings (key, value, category) VALUES (?, ?, ?)').run(key, value, 'general');
        }
      }
    });
    
    updateMany(defaults);
    res.json({ success: true, message: 'Settings reset to defaults' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

module.exports = router;