const express = require('express');
const router = express.Router();
const { authenticateUser } = require('../middleware/auth');
const gameforgeAuth = require('../middleware/gameforgeAuth');
const gameforgeService = require('../services/gameforgeIntegration');
const db = require('../database/db');

/**
 * POST /api/gameforge/projects
 * Provision new GameForge project with communication channels
 * Requires GameForge API key authentication
 */
router.post('/projects', gameforgeAuth, async (req, res) => {
  try {
    const integration = await gameforgeService.provisionProject(req.body);
    
    res.json({
      success: true,
      integration
    });
  } catch (error) {
    console.error('Failed to provision project:', error);
    res.status(500).json({
      success: false,
      error: error.message
    });
  }
});

/**
 * PATCH /api/gameforge/projects/:projectId/team
 * Update team members (add/remove/update roles)
 * Requires GameForge API key authentication
 */
router.patch('/projects/:projectId/team', gameforgeAuth, async (req, res) => {
  try {
    const { projectId } = req.params;
    const { action, members } = req.body;

    const updated = await gameforgeService.updateTeamMembers(
      projectId,
      action,
      members
    );

    res.json({
      success: true,
      updated
    });
  } catch (error) {
    console.error('Failed to update team:', error);
    res.status(500).json({
      success: false,
      error: error.message
    });
  }
});

/**
 * DELETE /api/gameforge/projects/:projectId
 * Archive project channels when project is deleted
 * Requires GameForge API key authentication
 */
router.delete('/projects/:projectId', gameforgeAuth, async (req, res) => {
  try {
    const { projectId } = req.params;

    const result = await gameforgeService.archiveProject(projectId);

    res.json({
      success: true,
      ...result
    });
  } catch (error) {
    console.error('Failed to archive project:', error);
    res.status(500).json({
      success: false,
      error: error.message
    });
  }
});

/**
 * GET /api/gameforge/projects/:projectId/channels
 * Get all channels for a project
 * Requires user authentication
 */
router.get('/projects/:projectId/channels', authenticateUser, async (req, res) => {
  try {
    const { projectId } = req.params;

    const result = await db.query(
      `SELECT c.*, 
         (SELECT COUNT(*) FROM conversation_participants WHERE conversation_id = c.id) as participant_count,
         (SELECT COUNT(*) FROM messages m 
          WHERE m.conversation_id = c.id 
          AND m.created_at > COALESCE(
            (SELECT last_read_at FROM conversation_participants 
             WHERE conversation_id = c.id AND user_id = $2),
            '1970-01-01'
          )) as unread_count
       FROM conversations c
       WHERE c.gameforge_project_id = $1
       AND c.is_archived = false
       ORDER BY 
         CASE c.metadata->>'channelName'
           WHEN 'general' THEN 1
           WHEN 'announcements' THEN 2
           ELSE 3
         END,
         c.created_at ASC`,
      [projectId, req.user.id]
    );

    const channels = [];

    for (const row of result.rows) {
      // Get last message
      const lastMessageResult = await db.query(
        `SELECT m.*, u.username
         FROM messages m
         LEFT JOIN users u ON m.sender_id = u.id
         WHERE m.conversation_id = $1
         AND m.deleted_at IS NULL
         ORDER BY m.created_at DESC
         LIMIT 1`,
        [row.id]
      );

      const metadata = row.metadata || {};

      channels.push({
        id: row.id,
        name: metadata.channelName || 'unknown',
        identifier: metadata.identifier || `channel@forge.aethex.dev`,
        description: row.description,
        permissions: metadata.permissions || ['all'],
        participantCount: parseInt(row.participant_count),
        unreadCount: parseInt(row.unread_count),
        lastMessage: lastMessageResult.rows.length > 0 ? {
          id: lastMessageResult.rows[0].id,
          content: lastMessageResult.rows[0].content_encrypted,
          senderId: lastMessageResult.rows[0].sender_id,
          senderName: lastMessageResult.rows[0].username,
          createdAt: lastMessageResult.rows[0].created_at
        } : null
      });
    }

    res.json({
      success: true,
      channels
    });

  } catch (error) {
    console.error('Failed to get channels:', error);
    res.status(500).json({
      success: false,
      error: error.message
    });
  }
});

/**
 * POST /api/gameforge/projects/:projectId/channels
 * Create custom channel for project
 * Requires user authentication
 */
router.post('/projects/:projectId/channels', authenticateUser, async (req, res) => {
  try {
    const { projectId } = req.params;
    const { name, description, permissions } = req.body;

    // Verify user is project owner or admin
    // (In production, would call GameForge API to verify ownership)

    const integrationResult = await db.query(
      `SELECT * FROM gameforge_integrations WHERE project_id = $1`,
      [projectId]
    );

    if (integrationResult.rows.length === 0) {
      return res.status(404).json({
        success: false,
        error: 'Project not found'
      });
    }

    const integration = integrationResult.rows[0];
    const slug = integration.domain.split('@')[0];

    // Get project team members
    // (In production, would call GameForge API here)
    const teamMembers = []; // Placeholder

    const channel = await gameforgeService.createProjectChannel(
      integration.id,
      projectId,
      name,
      slug,
      req.user.id,
      teamMembers
    );

    res.json({
      success: true,
      channel
    });

  } catch (error) {
    console.error('Failed to create channel:', error);
    res.status(500).json({
      success: false,
      error: error.message
    });
  }
});

/**
 * PATCH /api/gameforge/channels/:channelId
 * Update channel settings (description, permissions)
 * Requires user authentication
 */
router.patch('/channels/:channelId', authenticateUser, async (req, res) => {
  try {
    const { channelId } = req.params;
    const { description, permissions } = req.body;

    // Verify user has admin access to channel
    const participantResult = await db.query(
      `SELECT role FROM conversation_participants 
       WHERE conversation_id = $1 AND user_id = $2`,
      [channelId, req.user.id]
    );

    if (participantResult.rows.length === 0 || participantResult.rows[0].role !== 'admin') {
      return res.status(403).json({
        success: false,
        error: 'Insufficient permissions'
      });
    }

    // Update conversation
    const updates = [];
    const values = [];
    let paramCount = 1;

    if (description !== undefined) {
      updates.push(`description = $${paramCount++}`);
      values.push(description);
    }

    if (permissions !== undefined) {
      // Update metadata with new permissions
      const metadataResult = await db.query(
        `SELECT metadata FROM conversations WHERE id = $1`,
        [channelId]
      );

      const metadata = metadataResult.rows[0]?.metadata || {};
      metadata.permissions = permissions;

      updates.push(`metadata = $${paramCount++}`);
      values.push(JSON.stringify(metadata));
    }

    if (updates.length > 0) {
      values.push(channelId);
      await db.query(
        `UPDATE conversations SET ${updates.join(', ')} WHERE id = $${paramCount}`,
        values
      );
    }

    // Get updated channel
    const channelResult = await db.query(
      `SELECT * FROM conversations WHERE id = $1`,
      [channelId]
    );

    res.json({
      success: true,
      channel: channelResult.rows[0]
    });

  } catch (error) {
    console.error('Failed to update channel:', error);
    res.status(500).json({
      success: false,
      error: error.message
    });
  }
});

/**
 * DELETE /api/gameforge/channels/:channelId
 * Delete/archive channel
 * Requires user authentication and admin role
 */
router.delete('/channels/:channelId', authenticateUser, async (req, res) => {
  try {
    const { channelId } = req.params;

    // Verify user has admin access
    const participantResult = await db.query(
      `SELECT role FROM conversation_participants 
       WHERE conversation_id = $1 AND user_id = $2`,
      [channelId, req.user.id]
    );

    if (participantResult.rows.length === 0 || participantResult.rows[0].role !== 'admin') {
      return res.status(403).json({
        success: false,
        error: 'Insufficient permissions'
      });
    }

    // Archive channel (soft delete)
    await db.query(
      `UPDATE conversations SET is_archived = true WHERE id = $1`,
      [channelId]
    );

    res.json({
      success: true
    });

  } catch (error) {
    console.error('Failed to delete channel:', error);
    res.status(500).json({
      success: false,
      error: error.message
    });
  }
});

/**
 * POST /api/gameforge/projects/:projectId/notify
 * Send system notification to project channel
 * Requires GameForge API key authentication
 */
router.post('/projects/:projectId/notify', gameforgeAuth, async (req, res) => {
  try {
    const { projectId } = req.params;
    const notification = req.body;

    const result = await gameforgeService.sendNotification(
      projectId,
      notification.channelName || 'general',
      notification
    );

    res.json({
      success: true,
      ...result
    });

  } catch (error) {
    console.error('Failed to send notification:', error);
    res.status(500).json({
      success: false,
      error: error.message
    });
  }
});

module.exports = router;
