const express = require('express');
const { authenticateToken } = require('../middleware/auth');
const db = require('../database');
const { triggerWebhook } = require('../utils/webhooks');

const router = express.Router();

// Get all webhooks (admin only)
router.get('/', authenticateToken, (req, res) => {
  try {
    const webhooks = db.prepare(`
      SELECT id, name, url, events, enabled, created_at
      FROM webhooks
      ORDER BY created_at DESC
    `).all();

    // Parse events JSON for each webhook
    const webhooksWithParsedEvents = webhooks.map(webhook => ({
      ...webhook,
      events: JSON.parse(webhook.events),
      enabled: webhook.enabled === 1
    }));

    res.json(webhooksWithParsedEvents);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Get single webhook by ID (admin only)
router.get('/:id', authenticateToken, (req, res) => {
  try {
    const webhook = db.prepare(`
      SELECT id, name, url, events, enabled, created_at
      FROM webhooks
      WHERE id = ?
    `).get(req.params.id);

    if (!webhook) {
      return res.status(404).json({ error: 'Webhook not found' });
    }

    res.json({
      ...webhook,
      events: JSON.parse(webhook.events),
      enabled: webhook.enabled === 1
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Create new webhook (admin only)
router.post('/', authenticateToken, (req, res) => {
  try {
    const { name, url, secret, events } = req.body;

    // Validate required fields
    if (!name || !url || !secret || !events) {
      return res.status(400).json({ 
        error: 'Missing required fields: name, url, secret, events' 
      });
    }

    // Validate events is an array
    if (!Array.isArray(events)) {
      return res.status(400).json({ 
        error: 'events must be an array' 
      });
    }

    // Validate URL format
    try {
      new URL(url);
    } catch (err) {
      return res.status(400).json({ error: 'Invalid URL format' });
    }

    // Insert webhook
    const stmt = db.prepare(`
      INSERT INTO webhooks (name, url, secret, events, enabled)
      VALUES (?, ?, ?, ?, 1)
    `);

    const result = stmt.run(name, url, secret, JSON.stringify(events));

    const newWebhook = db.prepare(`
      SELECT id, name, url, events, enabled, created_at
      FROM webhooks
      WHERE id = ?
    `).get(result.lastInsertRowid);

    res.status(201).json({
      ...newWebhook,
      events: JSON.parse(newWebhook.events),
      enabled: newWebhook.enabled === 1,
      message: 'Webhook created successfully'
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Update webhook (admin only)
router.patch('/:id', authenticateToken, (req, res) => {
  try {
    const { name, url, secret, events, enabled } = req.body;
    const webhookId = req.params.id;

    // Check if webhook exists
    const webhook = db.prepare('SELECT * FROM webhooks WHERE id = ?').get(webhookId);
    
    if (!webhook) {
      return res.status(404).json({ error: 'Webhook not found' });
    }

    // Build update query dynamically based on provided fields
    const updates = [];
    const params = [];

    if (name !== undefined) {
      updates.push('name = ?');
      params.push(name);
    }

    if (url !== undefined) {
      // Validate URL format
      try {
        new URL(url);
      } catch (err) {
        return res.status(400).json({ error: 'Invalid URL format' });
      }
      updates.push('url = ?');
      params.push(url);
    }

    if (secret !== undefined) {
      updates.push('secret = ?');
      params.push(secret);
    }

    if (events !== undefined) {
      if (!Array.isArray(events)) {
        return res.status(400).json({ error: 'events must be an array' });
      }
      updates.push('events = ?');
      params.push(JSON.stringify(events));
    }

    if (enabled !== undefined) {
      updates.push('enabled = ?');
      params.push(enabled ? 1 : 0);
    }

    if (updates.length === 0) {
      return res.status(400).json({ error: 'No fields to update' });
    }

    params.push(webhookId);

    const stmt = db.prepare(`
      UPDATE webhooks
      SET ${updates.join(', ')}
      WHERE id = ?
    `);

    stmt.run(...params);

    const updatedWebhook = db.prepare(`
      SELECT id, name, url, events, enabled, created_at
      FROM webhooks
      WHERE id = ?
    `).get(webhookId);

    res.json({
      ...updatedWebhook,
      events: JSON.parse(updatedWebhook.events),
      enabled: updatedWebhook.enabled === 1,
      message: 'Webhook updated successfully'
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Delete webhook (admin only)
router.delete('/:id', authenticateToken, (req, res) => {
  try {
    const webhook = db.prepare('SELECT * FROM webhooks WHERE id = ?').get(req.params.id);
    
    if (!webhook) {
      return res.status(404).json({ error: 'Webhook not found' });
    }

    // Delete webhook (logs will be cascade deleted)
    db.prepare('DELETE FROM webhooks WHERE id = ?').run(req.params.id);

    res.json({ 
      message: 'Webhook deleted successfully',
      webhookId: parseInt(req.params.id)
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Test webhook (admin only)
router.post('/test/:id', authenticateToken, async (req, res) => {
  try {
    const webhook = db.prepare('SELECT * FROM webhooks WHERE id = ?').get(req.params.id);
    
    if (!webhook) {
      return res.status(404).json({ error: 'Webhook not found' });
    }

    // Send a test payload
    const testData = {
      session: {
        id: 0,
        is_active: true,
        games_played: 0
      },
      game: {
        id: 0,
        title: 'Test Game',
        pack_name: 'Test Pack',
        min_players: 2,
        max_players: 8,
        manually_added: false
      }
    };

    // Trigger the webhook asynchronously
    triggerWebhook('game.added', testData);

    res.json({ 
      message: 'Test webhook sent',
      note: 'Check webhook_logs table for delivery status'
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Get webhook logs (admin only)
router.get('/:id/logs', authenticateToken, (req, res) => {
  try {
    const { limit = 50 } = req.query;

    const logs = db.prepare(`
      SELECT *
      FROM webhook_logs
      WHERE webhook_id = ?
      ORDER BY created_at DESC
      LIMIT ?
    `).all(req.params.id, parseInt(limit));

    // Parse payload JSON for each log
    const logsWithParsedPayload = logs.map(log => ({
      ...log,
      payload: JSON.parse(log.payload)
    }));

    res.json(logsWithParsedPayload);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

module.exports = router;

