/**
 * Admin Sync Routes
 * Handles syncing services from Owlet API with smart filtering
 */

const express = require('express');
const owletService = require('../services/OwletService');

const router = express.Router();

/**
 * Middleware: Authenticate token
 */
const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];

  if (!token) {
    return res.status(401).json({ error: 'Access token required' });
  }

  const jwt = require('jsonwebtoken');
  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
    if (err) {
      return res.status(403).json({ error: 'Invalid or expired token' });
    }
    req.user = user;
    next();
  });
};

/**
 * Middleware: Check admin role
 */
const authenticateAdmin = (req, res, next) => {
  if (req.user.role !== 'admin') {
    return res.status(403).json({ error: 'Admin access required' });
  }
  next();
};

/**
 * GET /api/admin/owlet/test-connection
 * Test connection to Owlet API
 */
router.get('/owlet/test-connection', authenticateToken, authenticateAdmin, async (req, res) => {
  try {
    console.log('[Admin] Testing Owlet API connection...');
    const result = await owletService.testConnection();

    if (result.success) {
      res.json({
        success: true,
        message: 'Connected successfully!',
        balance: result.balance,
        currency: result.currency
      });
    } else {
      res.status(400).json({
        success: false,
        error: result.error,
        message: 'Connection failed'
      });
    }
  } catch (error) {
    console.error('[Admin] Connection test error:', error);
    res.status(500).json({ error: 'Failed to test connection' });
  }
});

/**
 * GET /api/admin/owlet/services/preview
 * Preview filtered services (test mode - no database changes)
 */
router.get('/owlet/services/preview', authenticateToken, authenticateAdmin, async (req, res) => {
  try {
    console.log('[Admin] Previewing filtered services...');

    const filtered = await owletService.getFilteredServices();
    const categorized = await owletService.getServicesByCategory();

    const totalServices = filtered.length;
    const totalCategories = Object.keys(categorized).length;

    // Show sample services
    const sampleServices = filtered.slice(0, 10).map(service => ({
      id: service.service || service.id,
      name: service.name,
      category: service.category,
      rate: service.rate,
      min: service.min,
      max: service.max,
    }));

    // Category breakdown
    const categoryBreakdown = Object.keys(categorized).map(key => ({
      name: categorized[key].name,
      icon: categorized[key].icon,
      count: categorized[key].count
    }));

    res.json({
      message: '✅ Preview Mode - No changes made',
      stats: {
        totalServices,
        totalCategories,
        sampleSize: Math.min(10, totalServices)
      },
      sample: sampleServices,
      categories: categoryBreakdown
    });
  } catch (error) {
    console.error('[Admin] Preview error:', error);
    res.status(500).json({ error: 'Failed to preview services' });
  }
});

/**
 * POST /api/admin/owlet/sync-services
 * Sync filtered services from Owlet API to database
 */
router.post('/owlet/sync-services', authenticateToken, authenticateAdmin, async (req, res) => {
  try {
    console.log('[Admin] Starting service sync from Owlet API...');
    console.log('═══════════════════════════════════════════');

    // Get database connection (passed from main server)
    const { pool } = req.app.locals;

    if (!pool) {
      return res.status(500).json({ error: 'Database connection not available' });
    }

    // Test connection first
    console.log('[Admin] Testing Owlet API connection...');
    const connectionTest = await owletService.testConnection();

    if (!connectionTest.success) {
      return res.status(400).json({
        success: false,
        error: '❌ Failed to connect to Owlet API',
        details: connectionTest.error
      });
    }

    console.log('[Admin] ✅ Connected successfully!');
    console.log(`[Admin] Balance: ${connectionTest.balance} ${connectionTest.currency}`);

    // Get filtered services
    console.log('[Admin] Fetching services from Owlet...');
    const filteredServices = await owletService.getFilteredServices();

    if (!filteredServices || filteredServices.length === 0) {
      return res.status(400).json({
        success: false,
        error: '❌ No services retrieved after filtering'
      });
    }

    console.log(`[Admin] ✅ Retrieved ${filteredServices.length} services (after filtering)`);

    // Group by category
    const categorizedServices = await owletService.getServicesByCategory();
    console.log(`[Admin] 📁 Categories found: ${Object.keys(categorizedServices).length}`);

    // Confirm sync (optional - can be overridden with force flag)
    const forceSync = req.body.force === true;
    if (!forceSync && !req.body.confirmed) {
      return res.json({
        confirmed: false,
        message: 'Please confirm sync',
        stats: {
          totalServices: filteredServices.length,
          totalCategories: Object.keys(categorizedServices).length
        },
        requiresConfirmation: true
      });
    }

    // Start sync
    console.log('[Admin] Starting sync process...');

    let synced = 0;
    let created = 0;
    let updated = 0;
    let failed = 0;
    const errors = [];

    const connection = await pool.getConnection();

    try {
      await connection.beginTransaction();

      // Get or create Owlet provider
      const [providers] = await connection.query(
        'SELECT id FROM api_providers WHERE name = ? LIMIT 1',
        ['Owlet SMM']
      );

      let providerId;
      if (providers.length > 0) {
        providerId = providers[0].id;
        console.log(`[Admin] Using existing Owlet provider (ID: ${providerId})`);
      } else {
        const result = await connection.query(
          `INSERT INTO api_providers (name, description, api_url, api_key, status, created_at, updated_at)
           VALUES (?, ?, ?, ?, 'active', NOW(), NOW())`,
          ['Owlet SMM', 'Owlet SMM Panel Provider', process.env.OWLET_API_URL, process.env.OWLET_API_KEY]
        );
        providerId = result[0].insertId;
        console.log(`[Admin] Created new Owlet provider (ID: ${providerId})`);
      }

      // Sync services by category
      for (const [categoryName, categoryData] of Object.entries(categorizedServices)) {
        try {
          // Create or get category
          const [existingCategory] = await connection.query(
            'SELECT id FROM categories WHERE name = ? LIMIT 1',
            [categoryName]
          );

          let categoryId;
          if (existingCategory.length > 0) {
            categoryId = existingCategory[0].id;
          } else {
            const categoryResult = await connection.query(
              `INSERT INTO categories (name, icon_class, status, display_order, created_at, updated_at)
               VALUES (?, ?, 'active', ?, NOW(), NOW())`,
              [categoryName, categoryData.icon, Object.keys(categorizedServices).indexOf(categoryName)]
            );
            categoryId = categoryResult[0].insertId;
            console.log(`[Admin] Created category: ${categoryName}`);
          }

          // Sync services in this category
          for (const service of categoryData.services) {
            try {
              const apiServiceId = service.service || service.id;
              const serviceName = service.name;
              const description = service.category || serviceName;
              const price = parseFloat(service.rate) || 0;
              const minQuantity = parseInt(service.min) || 10;
              const maxQuantity = parseInt(service.max) || 100000;

              // Check if service exists
              const [existingService] = await connection.query(
                `SELECT id FROM services
                 WHERE api_service_id = ? AND api_provider_id = ?
                 LIMIT 1`,
                [apiServiceId, providerId]
              );

              if (existingService.length > 0) {
                // Update existing service
                await connection.query(
                  `UPDATE services
                   SET name = ?, description = ?, price = ?,
                       min_quantity = ?, max_quantity = ?, status = 'active',
                       updated_at = NOW()
                   WHERE api_service_id = ? AND api_provider_id = ?`,
                  [serviceName, description, price, minQuantity, maxQuantity, apiServiceId, providerId]
                );
                updated++;
              } else {
                // Insert new service
                await connection.query(
                  `INSERT INTO services
                   (category_id, api_provider_id, api_service_id, name, description,
                    price, min_quantity, max_quantity, status, created_at, updated_at)
                   VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'active', NOW(), NOW())`,
                  [categoryId, providerId, apiServiceId, serviceName, description,
                   price, minQuantity, maxQuantity]
                );
                created++;
              }

              synced++;
            } catch (error) {
              failed++;
              errors.push({
                service: service.name || 'Unknown',
                error: error.message
              });
              console.error(`[Admin] Failed to sync service: ${error.message}`);
            }
          }
        } catch (error) {
          console.error(`[Admin] Category sync error for ${categoryName}: ${error.message}`);
          errors.push({
            category: categoryName,
            error: error.message
          });
        }
      }

      await connection.commit();
      console.log('[Admin] Transaction committed successfully');

    } catch (error) {
      await connection.rollback();
      throw error;
    } finally {
      connection.release();
    }

    console.log('═══════════════════════════════════════════');
    console.log('[Admin] ✅ Sync Complete!');
    console.log(`[Admin] Synced: ${synced} | Created: ${created} | Updated: ${updated} | Failed: ${failed}`);

    res.json({
      success: true,
      message: '✅ Sync Complete!',
      stats: {
        synced,
        created,
        updated,
        failed,
        categories: Object.keys(categorizedServices).length,
        totalServices: filteredServices.length
      },
      errors: errors.length > 0 ? errors : undefined
    });

  } catch (error) {
    console.error('[Admin] Sync error:', error);
    res.status(500).json({
      success: false,
      error: 'Failed to sync services',
      details: error.message
    });
  }
});

/**
 * GET /api/admin/owlet/cache/clear
 * Clear Owlet service cache
 */
router.get('/owlet/cache/clear', authenticateToken, authenticateAdmin, (req, res) => {
  try {
    owletService.clearCache();
    res.json({
      success: true,
      message: 'Owlet services cache cleared'
    });
  } catch (error) {
    console.error('[Admin] Cache clear error:', error);
    res.status(500).json({ error: 'Failed to clear cache' });
  }
});

module.exports = router;
