/**
 * Admin Controller
 * Moderation queue and system statistics
 */

const ModerationQueue = require('../models/ModerationQueue.model');
const Document = require('../models/Document.model');
const BlogPost = require('../models/BlogPost.model');
const User = require('../models/User.model');
const logger = require('../utils/logger.util');

/**
 * Get moderation queue dashboard
 * GET /api/admin/moderation
 */
async function getModerationQueue(req, res) {
  try {
    const { limit = 20, skip = 0, priority, quadrant, item_type, type } = req.query;

    let items;
    let total;

    // Support both new 'type' and legacy 'item_type' fields
    // Treat 'all' as no filter (same as not providing a type)
    const filterType = (type && type !== 'all') ? type : (item_type && item_type !== 'all' ? item_type : null);

    if (quadrant) {
      items = await ModerationQueue.findByQuadrant(quadrant, {
        limit: parseInt(limit),
        skip: parseInt(skip)
      });
      total = await ModerationQueue.countPending({ quadrant });
    } else if (filterType) {
      // Filter by new 'type' field (preferred) or legacy 'item_type' field
      const collection = await require('../utils/db.util').getCollection('moderation_queue');
      items = await collection
        .find({
          status: 'pending',
          $or: [
            { type: filterType },
            { item_type: filterType }
          ]
        })
        .sort({ priority: -1, created_at: 1 })
        .skip(parseInt(skip))
        .limit(parseInt(limit))
        .toArray();

      total = await collection.countDocuments({
        status: 'pending',
        $or: [
          { type: filterType },
          { item_type: filterType }
        ]
      });
    } else {
      items = await ModerationQueue.findPending({
        limit: parseInt(limit),
        skip: parseInt(skip),
        priority
      });
      total = await ModerationQueue.countPending(priority ? { priority } : {});
    }

    // Get stats by quadrant
    const stats = await ModerationQueue.getStatsByQuadrant();

    res.json({
      success: true,
      items,
      queue: items, // Alias for backward compatibility
      stats: stats.reduce((acc, stat) => {
        acc[stat._id] = {
          total: stat.count,
          high_priority: stat.high_priority
        };
        return acc;
      }, {}),
      pagination: {
        total,
        limit: parseInt(limit),
        skip: parseInt(skip)
      }
    });

  } catch (error) {
    logger.error('Get moderation queue error:', error);
    res.status(500).json({
      error: 'Internal Server Error',
      message: 'An error occurred'
    });
  }
}

/**
 * Get single moderation item
 * GET /api/admin/moderation/:id
 */
async function getModerationItem(req, res) {
  try {
    const { id } = req.params;

    const item = await ModerationQueue.findById(id);

    if (!item) {
      return res.status(404).json({
        error: 'Not Found',
        message: 'Moderation item not found'
      });
    }

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

  } catch (error) {
    logger.error('Get moderation item error:', error);
    res.status(500).json({
      error: 'Internal Server Error',
      message: 'An error occurred'
    });
  }
}

/**
 * Review moderation item (approve/reject/escalate)
 * POST /api/admin/moderation/:id/review
 */
async function reviewModerationItem(req, res) {
  try {
    const { id } = req.params;
    const { action, notes } = req.body;

    const item = await ModerationQueue.findById(id);

    if (!item) {
      return res.status(404).json({
        error: 'Not Found',
        message: 'Moderation item not found'
      });
    }

    let success;

    switch (action) {
      case 'approve':
        success = await ModerationQueue.approve(id, req.userId, notes);
        break;
      case 'reject':
        success = await ModerationQueue.reject(id, req.userId, notes);
        break;
      case 'escalate':
        success = await ModerationQueue.escalate(id, req.userId, notes);
        break;
      default:
        return res.status(400).json({
          error: 'Bad Request',
          message: 'Invalid action. Must be: approve, reject, or escalate'
        });
    }

    if (!success) {
      return res.status(500).json({
        error: 'Internal Server Error',
        message: 'Failed to update moderation item'
      });
    }

    const updatedItem = await ModerationQueue.findById(id);

    logger.info(`Moderation item ${action}: ${id} by ${req.user.email}`);

    res.json({
      success: true,
      item: updatedItem,
      message: `Item ${action}d successfully`
    });

  } catch (error) {
    logger.error('Review moderation item error:', error);
    res.status(500).json({
      error: 'Internal Server Error',
      message: 'An error occurred'
    });
  }
}

/**
 * Get system statistics
 * GET /api/admin/stats
 */
async function getSystemStats(req, res) {
  try {
    // Document stats
    const totalDocuments = await Document.count();
    const documentsByQuadrant = await Promise.all([
      Document.count({ quadrant: 'STRATEGIC' }),
      Document.count({ quadrant: 'OPERATIONAL' }),
      Document.count({ quadrant: 'TACTICAL' }),
      Document.count({ quadrant: 'SYSTEM' }),
      Document.count({ quadrant: 'STOCHASTIC' })
    ]);

    // Blog stats
    const blogStats = await Promise.all([
      BlogPost.countByStatus('published'),
      BlogPost.countByStatus('draft'),
      BlogPost.countByStatus('pending')
    ]);

    // Moderation queue stats
    const moderationStats = await ModerationQueue.getStatsByQuadrant();
    const totalPending = await ModerationQueue.countPending();

    // User stats
    const totalUsers = await User.count();
    const activeUsers = await User.count({ active: true });

    res.json({
      success: true,
      stats: {
        documents: {
          total: totalDocuments,
          by_quadrant: {
            STRATEGIC: documentsByQuadrant[0],
            OPERATIONAL: documentsByQuadrant[1],
            TACTICAL: documentsByQuadrant[2],
            SYSTEM: documentsByQuadrant[3],
            STOCHASTIC: documentsByQuadrant[4]
          }
        },
        blog: {
          published: blogStats[0],
          draft: blogStats[1],
          pending: blogStats[2],
          total: blogStats[0] + blogStats[1] + blogStats[2]
        },
        moderation: {
          total_pending: totalPending,
          by_quadrant: moderationStats.reduce((acc, stat) => {
            acc[stat._id] = {
              total: stat.count,
              high_priority: stat.high_priority
            };
            return acc;
          }, {})
        },
        users: {
          total: totalUsers,
          active: activeUsers,
          inactive: totalUsers - activeUsers
        }
      }
    });

  } catch (error) {
    logger.error('Get system stats error:', error);
    res.status(500).json({
      error: 'Internal Server Error',
      message: 'An error occurred'
    });
  }
}

/**
 * Get recent activity log
 * GET /api/admin/activity
 */
async function getActivityLog(req, res) {
  try {
    // This would typically read from a dedicated activity log
    // For now, return recent moderation reviews as example
    const { limit = 50 } = req.query;

    const collection = await require('../utils/db.util').getCollection('moderation_queue');

    const recentActivity = await collection
      .find({ status: 'reviewed' })
      .sort({ reviewed_at: -1 })
      .limit(parseInt(limit))
      .toArray();

    res.json({
      success: true,
      activity: recentActivity.map(item => ({
        timestamp: item.reviewed_at,
        action: item.review_decision?.action,
        item_type: item.item_type,
        item_id: item.item_id,
        reviewer: item.review_decision?.reviewer,
        notes: item.review_decision?.notes
      }))
    });

  } catch (error) {
    logger.error('Get activity log error:', error);
    res.status(500).json({
      error: 'Internal Server Error',
      message: 'An error occurred'
    });
  }
}

module.exports = {
  getModerationQueue,
  getModerationItem,
  reviewModerationItem,
  getSystemStats,
  getActivityLog
};
