import express from 'express';
import { authenticateToken } from '../middleware/auth.js';
import Discovery from '../models/Discovery.js';
import Project from '../models/Project.js';
import { startWorker } from '../workers/DiscoveryWorker.js';

const router = express.Router();

// Initialize the discovery worker on module load
startWorker();

/**
 * PHASE 4: Discovery & Analysis Endpoints
 * 4 endpoints for project discovery, analysis tracking, and statistics
 */

// 1. POST /api/discovery/scan - Start discovery scan
router.post('/scan', authenticateToken, async (req, res, next) => {
  try {
    const { projectId, type = 'project-analysis' } = req.body;

    if (!projectId) {
      return res.status(400).json({
        status: 'error',
        code: 'VALIDATION_ERROR',
        message: 'projectId is required',
        data: null
      });
    }

    const project = await Project.findOne({
      where: { id: projectId, userId: req.user.id }
    });

    if (!project) {
      return res.status(404).json({
        status: 'error',
        code: 'PROJECT_NOT_FOUND',
        message: 'Project not found',
        data: null
      });
    }

    const discovery = await Discovery.create({
      projectId,
      userId: req.user.id,
      type,
      status: 'queued'
    });

    // Queue for background processing
    console.log(`[Discovery] Scan queued: ${discovery.id} (${type})`);

    res.status(202).json({
      status: 'success',
      code: 'DISCOVERY_SCAN_STARTED',
      message: 'Discovery scan started',
      data: {
        discoveryId: discovery.id,
        status: 'queued',
        estimatedTime: type === 'component-audit' ? '1-3 minutes' : '2-5 minutes'
      }
    });
  } catch (error) {
    next(error);
  }
});

// 2. GET /api/discovery/activity - Get discovery activity
router.get('/activity', authenticateToken, async (req, res, next) => {
  try {
    const { projectId, limit = 50, offset = 0 } = req.query;
    const where = { userId: req.user.id };

    if (projectId) {
      where.projectId = projectId;
    }

    const { count, rows } = await Discovery.findAndCountAll({
      where,
      order: [['createdAt', 'DESC']],
      limit: Math.min(parseInt(limit), 100),
      offset: parseInt(offset)
    });

    res.status(200).json({
      status: 'success',
      code: 'DISCOVERY_ACTIVITY_RETRIEVED',
      message: 'Discovery activity retrieved',
      data: {
        total: count,
        limit: Math.min(parseInt(limit), 100),
        offset: parseInt(offset),
        activities: rows
      }
    });
  } catch (error) {
    next(error);
  }
});

// 3. GET /api/discovery/stats - Get discovery statistics
router.get('/stats', authenticateToken, async (req, res, next) => {
  try {
    const where = { userId: req.user.id };

    // Use SQL aggregation instead of loading all records
    const [totalCount, byTypeGroups, byStatusGroups, recentCompleted] = await Promise.all([
      Discovery.count({ where }),
      Discovery.findAll({
        where,
        attributes: [
          'type',
          [Discovery.sequelize.fn('COUNT', 'type'), 'count']
        ],
        group: ['type'],
        raw: true
      }),
      Discovery.findAll({
        where,
        attributes: [
          'status',
          [Discovery.sequelize.fn('COUNT', 'status'), 'count']
        ],
        group: ['status'],
        raw: true
      }),
      Discovery.findOne({
        where: { ...where, status: 'completed' },
        order: [['completedAt', 'DESC']],
        limit: 1
      })
    ]);

    // Transform aggregated results
    const stats = {
      total: totalCount,
      byType: {},
      byStatus: {},
      recentCompleted: recentCompleted,
      totalTime: 0 // Note: Computing totalTime would require loading all records
    };

    byTypeGroups.forEach(group => {
      stats.byType[group.type] = parseInt(group.count);
    });

    byStatusGroups.forEach(group => {
      stats.byStatus[group.status] = parseInt(group.count);
    });

    res.status(200).json({
      status: 'success',
      code: 'DISCOVERY_STATS_RETRIEVED',
      message: 'Discovery statistics retrieved',
      data: { stats }
    });
  } catch (error) {
    next(error);
  }
});

// 4. GET /api/discovery/:id - Get status of a specific discovery job
router.get('/:id', authenticateToken, async (req, res, next) => {
  try {
    const discovery = await Discovery.findOne({
      where: {
        id: req.params.id,
        userId: req.user.id
      }
    });

    if (!discovery) {
      return res.status(404).json({
        status: 'error',
        code: 'DISCOVERY_NOT_FOUND',
        message: 'Discovery job not found',
        data: null
      });
    }

    res.status(200).json({
      status: 'success',
      code: 'DISCOVERY_JOB_RETRIEVED',
      message: 'Discovery job retrieved',
      data: {
        id: discovery.id,
        projectId: discovery.projectId,
        type: discovery.type,
        status: discovery.status,
        progress: discovery.progress,
        results: discovery.results,
        error: discovery.error,
        startedAt: discovery.startedAt,
        completedAt: discovery.completedAt,
        createdAt: discovery.createdAt,
        updatedAt: discovery.updatedAt
      }
    });
  } catch (error) {
    next(error);
  }
});

export default router;
