const express = require('express');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const db = require('../config/database');
const { auth } = require('../middleware/auth');

// Get all blocked dates
router.get('/', auth, async (req, res) => {
  try {
    const blockedDates = await db.all(`
      SELECT id, blocked_date, reason, start_time, end_time, created_at
      FROM blocked_dates
      ORDER BY blocked_date ASC, start_time ASC
    `);
    
    res.json({ blockedDates });
  } catch (error) {
    console.error('Error fetching blocked dates:', error);
    res.status(500).json({ error: 'Failed to fetch blocked dates' });
  }
});

// Check if a date/time is blocked
router.get('/check/:date', async (req, res) => {
  try {
    const { date } = req.params;
    const { time } = req.query; // Optional time to check (HH:MM format)
    
    // Check for full day blocks
    const fullDayBlock = await db.get(`
      SELECT id, blocked_date, reason
      FROM blocked_dates
      WHERE blocked_date = ? AND start_time IS NULL AND end_time IS NULL
    `, [date]);
    
    if (fullDayBlock) {
      return res.json({ 
        isBlocked: true,
        reason: fullDayBlock.reason,
        blockType: 'full_day'
      });
    }
    
    // If time is provided, check for time slot blocks
    if (time) {
      const timeSlotBlocks = await db.all(`
        SELECT id, blocked_date, reason, start_time, end_time
        FROM blocked_dates
        WHERE blocked_date = ? 
          AND start_time IS NOT NULL 
          AND end_time IS NOT NULL
          AND ? >= start_time 
          AND ? < end_time
      `, [date, time, time]);
      
      if (timeSlotBlocks.length > 0) {
        return res.json({ 
          isBlocked: true,
          reason: timeSlotBlocks[0].reason,
          blockType: 'time_slot',
          timeSlot: `${timeSlotBlocks[0].start_time} - ${timeSlotBlocks[0].end_time}`
        });
      }
    }
    
    res.json({ 
      isBlocked: false,
      reason: null
    });
  } catch (error) {
    console.error('Error checking blocked date:', error);
    res.status(500).json({ error: 'Failed to check date' });
  }
});

// Add a blocked date
router.post('/', [
  auth,
  body('date').isISO8601().withMessage('Valid date is required'),
  body('reason').optional().isString(),
  body('startTime').optional().matches(/^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/).withMessage('Start time must be in HH:MM format'),
  body('endTime').optional().matches(/^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/).withMessage('End time must be in HH:MM format')
], async (req, res) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }
    
    const { date, reason, startTime, endTime } = req.body;
    const userId = req.user.id;
    
    // If time slots are provided, validate them
    if (startTime && endTime) {
      if (startTime >= endTime) {
        return res.status(400).json({ error: 'End time must be after start time' });
      }
      
      // Check for overlapping time slots
      const overlapping = await db.get(`
        SELECT id FROM blocked_dates 
        WHERE blocked_date = ?
        AND (
          (start_time IS NULL AND end_time IS NULL) OR
          (start_time <= ? AND end_time > ?) OR
          (start_time < ? AND end_time >= ?) OR
          (start_time >= ? AND end_time <= ?)
        )
      `, [date, startTime, startTime, endTime, endTime, startTime, endTime]);
      
      if (overlapping) {
        return res.status(400).json({ error: 'This time slot overlaps with an existing block' });
      }
    } else {
      // Check if full day is already blocked
      const existing = await db.get(`
        SELECT id FROM blocked_dates 
        WHERE blocked_date = ? 
        AND start_time IS NULL 
        AND end_time IS NULL
      `, [date]);
      
      if (existing) {
        return res.status(400).json({ error: 'This date is already fully blocked' });
      }
    }
    
    // Insert blocked date/time
    const result = await db.run(`
      INSERT INTO blocked_dates (blocked_date, reason, start_time, end_time, created_by)
      VALUES (?, ?, ?, ?, ?)
    `, [date, reason || 'Fully booked', startTime || null, endTime || null, userId]);
    
    const newBlockedDate = await db.get(`
      SELECT id, blocked_date, reason, start_time, end_time, created_at
      FROM blocked_dates
      WHERE id = ?
    `, [result.id]);
    
    res.status(201).json({ 
      message: startTime && endTime ? 'Time slot blocked successfully' : 'Date blocked successfully',
      blockedDate: newBlockedDate
    });
  } catch (error) {
    console.error('Error blocking date:', error);
    res.status(500).json({ error: 'Failed to block date' });
  }
});

// Remove a blocked date
router.delete('/:id', auth, async (req, res) => {
  try {
    const { id } = req.params;
    
    const result = await db.run(`
      DELETE FROM blocked_dates WHERE id = ?
    `, [id]);
    
    if (result.changes === 0) {
      return res.status(404).json({ error: 'Blocked date not found' });
    }
    
    res.json({ message: 'Blocked date removed successfully' });
  } catch (error) {
    console.error('Error removing blocked date:', error);
    res.status(500).json({ error: 'Failed to remove blocked date' });
  }
});

// Get booking configuration
router.get('/config', auth, async (req, res) => {
  try {
    const configs = await db.all(`
      SELECT config_key, config_value, description
      FROM booking_config
    `);
    
    const configObj = {};
    configs.forEach(config => {
      configObj[config.config_key] = {
        value: config.config_value,
        description: config.description
      };
    });
    
    res.json({ config: configObj });
  } catch (error) {
    console.error('Error fetching booking config:', error);
    res.status(500).json({ error: 'Failed to fetch configuration' });
  }
});

// Update booking configuration
router.put('/config/:key', [
  auth,
  body('value').notEmpty().withMessage('Value is required')
], async (req, res) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }
    
    const { key } = req.params;
    const { value } = req.body;
    
    await db.run(`
      UPDATE booking_config 
      SET config_value = ?, updated_at = CURRENT_TIMESTAMP
      WHERE config_key = ?
    `, [value, key]);
    
    res.json({ message: 'Configuration updated successfully' });
  } catch (error) {
    console.error('Error updating config:', error);
    res.status(500).json({ error: 'Failed to update configuration' });
  }
});

module.exports = router;
