const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const { authenticate } = require('../middleware/auth');
const { modifyLimiter, readLimiter } = require('../middleware/rateLimiter');
const { db } = require('../database/db');
const logger = require('../utils/logger');
const {
  validateIdParam,
  validateChannelUpdate,
  validatePagination,
  validateSearch
} = require('../middleware/inputValidation');

// Configure multer for logo uploads
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const uploadDir = path.join(__dirname, '../uploads/logos');
    if (!fs.existsSync(uploadDir)) {
      fs.mkdirSync(uploadDir, { recursive: true });
    }
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    cb(null, 'channel-' + uniqueSuffix + path.extname(file.originalname));
  }
});

const upload = multer({
  storage: storage,
  limits: { fileSize: 5 * 1024 * 1024 }, // 5MB limit
  fileFilter: (req, file, cb) => {
    const allowedTypes = /jpeg|jpg|png|gif|svg|webp/;
    const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
    const mimetype = allowedTypes.test(file.mimetype);
    if (mimetype && extname) {
      return cb(null, true);
    }
    cb(new Error('Only image files are allowed'));
  }
});

// Get channels with filters
router.get('/', authenticate, readLimiter, validatePagination, validateSearch, (req, res) => {
  const { playlistId, isRadio, groupName, search } = req.query;
  const limit = req.sanitizedQuery?.limit || 100;
  const offset = req.sanitizedQuery?.offset || 0;
  
  let query = `
    SELECT c.*, p.name as playlist_name,
    COALESCE(c.custom_logo, c.logo) as logo
    FROM channels c 
    JOIN playlists p ON c.playlist_id = p.id 
    WHERE p.user_id = ? AND c.is_active = 1
  `;
  const params = [req.user.userId];

  if (playlistId) {
    query += ' AND c.playlist_id = ?';
    params.push(playlistId);
  }

  if (isRadio !== undefined) {
    query += ' AND c.is_radio = ?';
    params.push(isRadio === 'true' ? 1 : 0);
  }

  if (groupName) {
    query += ' AND c.group_name = ?';
    params.push(groupName);
  }

  if (search) {
    query += ' AND (c.name LIKE ? OR c.group_name LIKE ?)';
    params.push(`%${search}%`, `%${search}%`);
  }

  query += ' ORDER BY c.name LIMIT ? OFFSET ?';
  params.push(parseInt(limit), parseInt(offset));

  db.all(query, params, (err, channels) => {
    if (err) {
      return res.status(500).json({ error: 'Failed to fetch channels' });
    }
    res.json(channels);
  });
});

// Get channel groups
router.get('/groups', authenticate, readLimiter, (req, res) => {
  const { playlistId, isRadio } = req.query;
  
  // Validate playlist ID if provided
  if (playlistId && (isNaN(parseInt(playlistId)) || parseInt(playlistId) < 1)) {
    return res.status(400).json({ error: 'Invalid playlist ID' });
  }
  
  let query = `
    SELECT DISTINCT c.group_name, COUNT(*) as count 
    FROM channels c 
    JOIN playlists p ON c.playlist_id = p.id 
    WHERE p.user_id = ? AND c.is_active = 1
  `;
  const params = [req.user.userId];

  if (playlistId) {
    query += ' AND c.playlist_id = ?';
    params.push(playlistId);
  }

  if (isRadio !== undefined) {
    query += ' AND c.is_radio = ?';
    params.push(isRadio === 'true' ? 1 : 0);
  }

  query += ' GROUP BY c.group_name ORDER BY c.group_name';

  db.all(query, params, (err, groups) => {
    if (err) {
      return res.status(500).json({ error: 'Failed to fetch groups' });
    }
    res.json(groups);
  });
});

// Upload custom logo for channel
router.post('/:id/logo', authenticate, modifyLimiter, validateIdParam, upload.single('logo'), (req, res) => {
  const channelId = req.params.id;
  const userId = req.user.userId;

  if (!req.file) {
    return res.status(400).json({ error: 'No file uploaded' });
  }

  // Verify channel belongs to user
  db.get(
    `SELECT c.*, c.custom_logo as old_logo 
     FROM channels c 
     JOIN playlists p ON c.playlist_id = p.id 
     WHERE c.id = ? AND p.user_id = ?`,
    [channelId, userId],
    (err, channel) => {
      if (err) {
        return res.status(500).json({ error: 'Database error' });
      }
      if (!channel) {
        // Delete uploaded file if channel not found
        fs.unlinkSync(req.file.path);
        return res.status(404).json({ error: 'Channel not found' });
      }

      // Delete old custom logo if exists
      if (channel.old_logo) {
        const oldLogoPath = path.join(__dirname, '..', channel.old_logo);
        if (fs.existsSync(oldLogoPath)) {
          fs.unlinkSync(oldLogoPath);
        }
      }

      // Save new logo path
      const logoPath = `/uploads/logos/${req.file.filename}`;
      db.run(
        'UPDATE channels SET custom_logo = ? WHERE id = ?',
        [logoPath, channelId],
        (err) => {
          if (err) {
            return res.status(500).json({ error: 'Failed to update logo' });
          }
          res.json({ 
            message: 'Logo uploaded successfully',
            logoUrl: logoPath
          });
        }
      );
    }
  );
});

// Delete custom logo for a channel
router.delete('/:id/logo', authenticate, modifyLimiter, (req, res) => {
  const channelId = req.params.id;
  const userId = req.user.userId;

  // Verify channel belongs to user and get current logo
  db.get(
    `SELECT c.*, c.custom_logo 
     FROM channels c 
     JOIN playlists p ON c.playlist_id = p.id 
     WHERE c.id = ? AND p.user_id = ?`,
    [channelId, userId],
    (err, channel) => {
      if (err) {
        return res.status(500).json({ error: 'Database error' });
      }
      if (!channel) {
        return res.status(404).json({ error: 'Channel not found' });
      }

      if (!channel.custom_logo) {
        return res.status(400).json({ error: 'No custom logo to delete' });
      }

      // Delete file from filesystem
      const logoPath = path.join(__dirname, '..', channel.custom_logo);
      if (fs.existsSync(logoPath)) {
        fs.unlinkSync(logoPath);
      }

      // Remove logo from database
      db.run(
        'UPDATE channels SET custom_logo = NULL WHERE id = ?',
        [channelId],
        (err) => {
          if (err) {
            return res.status(500).json({ error: 'Failed to delete logo' });
          }
          res.json({ message: 'Logo deleted successfully' });
        }
      );
    }
  );
});

// Get single channel by ID
router.get('/:id', authenticate, readLimiter, (req, res) => {
  const channelId = req.params.id;
  const userId = req.user.userId;

  db.get(
    `SELECT c.*, p.name as playlist_name,
     COALESCE(c.custom_logo, c.logo) as logo
     FROM channels c 
     JOIN playlists p ON c.playlist_id = p.id 
     WHERE c.id = ? AND p.user_id = ?`,
    [channelId, userId],
    (err, channel) => {
      if (err) {
        return res.status(500).json({ error: 'Database error' });
      }
      if (!channel) {
        return res.status(404).json({ error: 'Channel not found' });
      }
      res.json(channel);
    }
  );
});

// Delete channel from playlist
router.delete('/:id', authenticate, modifyLimiter, validateIdParam, (req, res) => {
  const channelId = req.params.id;
  const userId = req.user.userId;

  // Verify channel belongs to user
  db.get(
    `SELECT c.id, c.playlist_id, c.custom_logo 
     FROM channels c 
     JOIN playlists p ON c.playlist_id = p.id 
     WHERE c.id = ? AND p.user_id = ?`,
    [channelId, userId],
    (err, channel) => {
      if (err) {
        logger.error('Error fetching channel for deletion:', err);
        return res.status(500).json({ error: 'Database error' });
      }
      if (!channel) {
        return res.status(404).json({ error: 'Channel not found' });
      }

      // Delete custom logo file if exists
      if (channel.custom_logo) {
        const logoPath = path.join(__dirname, '..', channel.custom_logo);
        if (fs.existsSync(logoPath)) {
          try {
            fs.unlinkSync(logoPath);
          } catch (err) {
            logger.error('Error deleting custom logo file:', err);
          }
        }
      }

      // Delete channel from database
      db.run('DELETE FROM channels WHERE id = ?', [channelId], function(err) {
        if (err) {
          logger.error('Error deleting channel:', err);
          return res.status(500).json({ error: 'Failed to delete channel' });
        }

        // Update playlist channel count
        db.run(
          'UPDATE playlists SET channel_count = (SELECT COUNT(*) FROM channels WHERE playlist_id = ?) WHERE id = ?',
          [channel.playlist_id, channel.playlist_id],
          (updateErr) => {
            if (updateErr) {
              logger.error('Error updating playlist count:', updateErr);
            }
          }
        );

        logger.info(`Channel ${channelId} deleted by user ${userId}`);
        res.json({ 
          message: 'Channel deleted successfully',
          deletedId: channelId 
        });
      });
    }
  );
});

module.exports = router;
