import express from 'express';
import { requireAdmin } from '../../shared/auth/middleware.js';

const router = express.Router();

// Phase 6.2: global settings are admin-only on write. Reads pass through to any
// authenticated user (the server-level authenticate() already gates that).
router.use((req, res, next) => {
  if (req.method === 'GET' || req.method === 'HEAD' || req.method === 'OPTIONS') return next();
  return requireAdmin(req, res, next);
});

// ===== GLOBAL SETTINGS =====

// Get all global settings
router.get('/global', async (req, res) => {
  const pool = req.app.locals.pool;
  try {
    console.log('[Config Route] Fetching global settings...');
    
    const { rows } = await pool.query('SELECT * FROM settings_global ORDER BY setting_key');
    
    console.log('[Config Route] Sending global settings:', rows);
    res.json(rows);
  } catch (error) {
    console.error('[Config Route] Error fetching global settings:', error);
    res.status(500).json({ error: 'Failed to fetch global settings', details: error.message });
  }
});

// Update global settings
router.put('/global', async (req, res) => {
  const pool = req.app.locals.pool;
  try {
    console.log('[Config Route] Updating global settings:', req.body);
    
    // Validate request
    if (!Array.isArray(req.body)) {
      return res.status(400).json({ error: 'Request body must be an array of settings' });
    }
    
    // Begin transaction
    const client = await pool.connect();
    try {
      await client.query('BEGIN');
      
      for (const setting of req.body) {
        if (!setting.setting_key || !setting.setting_value) {
          throw new Error('Each setting must have a key and value');
        }
        
        await client.query(
          `UPDATE settings_global 
           SET setting_value = $1, 
               updated_at = CURRENT_TIMESTAMP
           WHERE setting_key = $2`,
          [setting.setting_value, setting.setting_key]
        );
      }
      
      await client.query('COMMIT');
      res.json({ success: true });
    } catch (error) {
      await client.query('ROLLBACK');
      throw error;
    } finally {
      client.release();
    }
  } catch (error) {
    console.error('[Config Route] Error updating global settings:', error);
    res.status(500).json({ error: 'Failed to update global settings', details: error.message });
  }
});

// ===== PRODUCT SETTINGS =====

// Get product settings with pagination and search
router.get('/products', async (req, res) => {
  const pool = req.app.locals.pool;
  try {
    console.log('[Config Route] Fetching product settings...');
    
    const page = parseInt(req.query.page) || 1;
    const pageSize = parseInt(req.query.pageSize) || 10;
    const offset = (page - 1) * pageSize;
    const search = req.query.search || '';
    
    // Get total count for pagination
    const countQuery = search
      ? `SELECT COUNT(*) FROM settings_product sp
         JOIN products p ON sp.pid::text = p.pid::text
         WHERE sp.pid::text ILIKE $1 OR p.title ILIKE $1`
      : 'SELECT COUNT(*) FROM settings_product';
    
    const countParams = search ? [`%${search}%`] : [];
    const { rows: countResult } = await pool.query(countQuery, countParams);
    const total = parseInt(countResult[0].count);
    
    // Get paginated settings
    const query = search
      ? `SELECT sp.*, p.title as product_name 
         FROM settings_product sp
         JOIN products p ON sp.pid::text = p.pid::text
         WHERE sp.pid::text ILIKE $1 OR p.title ILIKE $1
         ORDER BY sp.pid
         LIMIT $2 OFFSET $3`
      : `SELECT sp.*, p.title as product_name 
         FROM settings_product sp
         JOIN products p ON sp.pid::text = p.pid::text
         ORDER BY sp.pid
         LIMIT $1 OFFSET $2`;
    
    const queryParams = search 
      ? [`%${search}%`, pageSize, offset]
      : [pageSize, offset];
    
    const { rows } = await pool.query(query, queryParams);
    
    const response = {
      items: rows,
      total,
      page,
      pageSize
    };
    
    console.log(`[Config Route] Sending ${rows.length} product settings`);
    res.json(response);
  } catch (error) {
    console.error('[Config Route] Error fetching product settings:', error);
    res.status(500).json({ error: 'Failed to fetch product settings', details: error.message });
  }
});

// Update product settings
router.put('/products/:pid', async (req, res) => {
  const pool = req.app.locals.pool;
  try {
    const { pid } = req.params;
    const { lead_time_days, days_of_stock, safety_stock, forecast_method, exclude_from_forecast } = req.body;
    
    console.log(`[Config Route] Updating product settings for ${pid}:`, req.body);
    
    // Check if product exists
    const { rows: checkProduct } = await pool.query(
      'SELECT 1 FROM settings_product WHERE pid::text = $1',
      [pid]
    );
    
    if (checkProduct.length === 0) {
      // Insert if it doesn't exist
      await pool.query(
        `INSERT INTO settings_product 
         (pid, lead_time_days, days_of_stock, safety_stock, forecast_method, exclude_from_forecast)
         VALUES ($1, $2, $3, $4, $5, $6)`,
        [pid, lead_time_days, days_of_stock, safety_stock, forecast_method, exclude_from_forecast]
      );
    } else {
      // Update if it exists
      await pool.query(
        `UPDATE settings_product
         SET lead_time_days = $2,
             days_of_stock = $3,
             safety_stock = $4,
             forecast_method = $5,
             exclude_from_forecast = $6,
             updated_at = CURRENT_TIMESTAMP
         WHERE pid::text = $1`,
        [pid, lead_time_days, days_of_stock, safety_stock, forecast_method, exclude_from_forecast]
      );
    }
    
    res.json({ success: true });
  } catch (error) {
    console.error(`[Config Route] Error updating product settings for ${req.params.pid}:`, error);
    res.status(500).json({ error: 'Failed to update product settings', details: error.message });
  }
});

// Reset product settings to defaults
router.post('/products/:pid/reset', async (req, res) => {
  const pool = req.app.locals.pool;
  try {
    const { pid } = req.params;
    
    console.log(`[Config Route] Resetting product settings for ${pid}`);
    
    // Reset by setting everything to null/default
    await pool.query(
      `UPDATE settings_product
       SET lead_time_days = NULL,
           days_of_stock = NULL,
           safety_stock = 0,
           forecast_method = NULL,
           exclude_from_forecast = false,
           updated_at = CURRENT_TIMESTAMP
       WHERE pid::text = $1`,
      [pid]
    );
    
    res.json({ success: true });
  } catch (error) {
    console.error(`[Config Route] Error resetting product settings for ${req.params.pid}:`, error);
    res.status(500).json({ error: 'Failed to reset product settings', details: error.message });
  }
});

// ===== VENDOR SETTINGS =====

// Get vendor settings with pagination and search
router.get('/vendors', async (req, res) => {
  const pool = req.app.locals.pool;
  try {
    console.log('[Config Route] Fetching vendor settings...');
    
    const page = parseInt(req.query.page) || 1;
    const pageSize = parseInt(req.query.pageSize) || 10;
    const offset = (page - 1) * pageSize;
    const search = req.query.search || '';
    
    // Get total count for pagination
    const countQuery = search
      ? 'SELECT COUNT(*) FROM settings_vendor WHERE vendor ILIKE $1'
      : 'SELECT COUNT(*) FROM settings_vendor';
    
    const countParams = search ? [`%${search}%`] : [];
    const { rows: countResult } = await pool.query(countQuery, countParams);
    const total = parseInt(countResult[0].count);
    
    // Get paginated settings
    const query = search
      ? `SELECT * FROM settings_vendor
         WHERE vendor ILIKE $1
         ORDER BY vendor
         LIMIT $2 OFFSET $3`
      : `SELECT * FROM settings_vendor
         ORDER BY vendor
         LIMIT $1 OFFSET $2`;
    
    const queryParams = search 
      ? [`%${search}%`, pageSize, offset]
      : [pageSize, offset];
    
    const { rows } = await pool.query(query, queryParams);
    
    const response = {
      items: rows,
      total,
      page,
      pageSize
    };
    
    console.log(`[Config Route] Sending ${rows.length} vendor settings`);
    res.json(response);
  } catch (error) {
    console.error('[Config Route] Error fetching vendor settings:', error);
    res.status(500).json({ error: 'Failed to fetch vendor settings', details: error.message });
  }
});

// Update vendor settings
router.put('/vendors/:vendor', async (req, res) => {
  const pool = req.app.locals.pool;
  try {
    const vendor = req.params.vendor;
    const { default_lead_time_days, default_days_of_stock } = req.body;
    
    console.log(`[Config Route] Updating vendor settings for ${vendor}:`, req.body);
    
    // Check if vendor exists
    const { rows: checkVendor } = await pool.query(
      'SELECT 1 FROM settings_vendor WHERE vendor = $1',
      [vendor]
    );
    
    if (checkVendor.length === 0) {
      // Insert if it doesn't exist
      await pool.query(
        `INSERT INTO settings_vendor 
         (vendor, default_lead_time_days, default_days_of_stock)
         VALUES ($1, $2, $3)`,
        [vendor, default_lead_time_days, default_days_of_stock]
      );
    } else {
      // Update if it exists
      await pool.query(
        `UPDATE settings_vendor
         SET default_lead_time_days = $2,
             default_days_of_stock = $3,
             updated_at = CURRENT_TIMESTAMP
         WHERE vendor = $1`,
        [vendor, default_lead_time_days, default_days_of_stock]
      );
    }
    
    res.json({ success: true });
  } catch (error) {
    console.error(`[Config Route] Error updating vendor settings for ${req.params.vendor}:`, error);
    res.status(500).json({ error: 'Failed to update vendor settings', details: error.message });
  }
});

// Reset vendor settings to defaults
router.post('/vendors/:vendor/reset', async (req, res) => {
  const pool = req.app.locals.pool;
  try {
    const vendor = req.params.vendor;
    
    console.log(`[Config Route] Resetting vendor settings for ${vendor}`);
    
    // Reset by setting everything to null
    await pool.query(
      `UPDATE settings_vendor
       SET default_lead_time_days = NULL,
           default_days_of_stock = NULL,
           updated_at = CURRENT_TIMESTAMP
       WHERE vendor = $1`,
      [vendor]
    );
    
    res.json({ success: true });
  } catch (error) {
    console.error(`[Config Route] Error resetting vendor settings for ${req.params.vendor}:`, error);
    res.status(500).json({ error: 'Failed to reset vendor settings', details: error.message });
  }
});

// Export the router
export default router;
