const express = require('express');
const { BetaAnalyticsDataClient } = require('@google-analytics/data');
const router = express.Router();
const logger = require('../utils/logger');

// Initialize GA4 client
const analyticsClient = new BetaAnalyticsDataClient({
  credentials: JSON.parse(process.env.GOOGLE_APPLICATION_CREDENTIALS_JSON)
});

const propertyId = process.env.GA_PROPERTY_ID;

// Cache durations
const CACHE_DURATIONS = {
  REALTIME_BASIC: 60, // 1 minute
  REALTIME_DETAILED: 300, // 5 minutes
  BASIC_METRICS: 3600, // 1 hour
  USER_BEHAVIOR: 3600 // 1 hour
};

// Basic metrics endpoint
router.get('/metrics', async (req, res) => {
  try {
    const { startDate = '7daysAgo' } = req.query;
    const cacheKey = `analytics:basic_metrics:${startDate}`;

    // Check Redis cache
    const cachedData = await req.redisClient.get(cacheKey);
    if (cachedData) {
      logger.info('Returning cached basic metrics data');
      return res.json({ success: true, data: JSON.parse(cachedData) });
    }

    // Fetch from GA4
    const [response] = await analyticsClient.runReport({
      property: `properties/${propertyId}`,
      dateRanges: [{ startDate, endDate: 'today' }],
      dimensions: [{ name: 'date' }],
      metrics: [
        { name: 'activeUsers' },
        { name: 'newUsers' },
        { name: 'averageSessionDuration' },
        { name: 'screenPageViews' },
        { name: 'bounceRate' },
        { name: 'conversions' }
      ],
      returnPropertyQuota: true
    });

    // Cache the response
    await req.redisClient.set(cacheKey, JSON.stringify(response), {
      EX: CACHE_DURATIONS.BASIC_METRICS
    });

    res.json({ success: true, data: response });
  } catch (error) {
    logger.error('Error fetching basic metrics:', error);
    res.status(500).json({ success: false, error: error.message });
  }
});

// Realtime basic data endpoint
router.get('/realtime/basic', async (req, res) => {
  try {
    const cacheKey = 'analytics:realtime:basic';
    
    // Check Redis cache
    const cachedData = await req.redisClient.get(cacheKey);
    if (cachedData) {
      logger.info('Returning cached realtime basic data');
      return res.json({ success: true, data: JSON.parse(cachedData) });
    }

    // Fetch active users
    const [userResponse] = await analyticsClient.runRealtimeReport({
      property: `properties/${propertyId}`,
      metrics: [{ name: 'activeUsers' }],
      returnPropertyQuota: true
    });

    // Fetch last 5 minutes
    const [fiveMinResponse] = await analyticsClient.runRealtimeReport({
      property: `properties/${propertyId}`,
      metrics: [{ name: 'activeUsers' }],
      minuteRanges: [{ startMinutesAgo: 5, endMinutesAgo: 0 }]
    });

    // Fetch time series data
    const [timeSeriesResponse] = await analyticsClient.runRealtimeReport({
      property: `properties/${propertyId}`,
      dimensions: [{ name: 'minutesAgo' }],
      metrics: [{ name: 'activeUsers' }]
    });

    const response = {
      userResponse,
      fiveMinResponse,
      timeSeriesResponse,
      quotaInfo: {
        projectHourly: userResponse.propertyQuota.tokensPerProjectPerHour,
        daily: userResponse.propertyQuota.tokensPerDay,
        serverErrors: userResponse.propertyQuota.serverErrorsPerProjectPerHour,
        thresholdedRequests: userResponse.propertyQuota.potentiallyThresholdedRequestsPerHour
      }
    };

    // Cache the response
    await req.redisClient.set(cacheKey, JSON.stringify(response), {
      EX: CACHE_DURATIONS.REALTIME_BASIC
    });

    res.json({ success: true, data: response });
  } catch (error) {
    logger.error('Error fetching realtime basic data:', error);
    res.status(500).json({ success: false, error: error.message });
  }
});

// Realtime detailed data endpoint
router.get('/realtime/detailed', async (req, res) => {
  try {
    const cacheKey = 'analytics:realtime:detailed';
    
    // Check Redis cache
    const cachedData = await req.redisClient.get(cacheKey);
    if (cachedData) {
      logger.info('Returning cached realtime detailed data');
      return res.json({ success: true, data: JSON.parse(cachedData) });
    }

    // Fetch current pages
    const [pageResponse] = await analyticsClient.runRealtimeReport({
      property: `properties/${propertyId}`,
      dimensions: [{ name: 'unifiedScreenName' }],
      metrics: [{ name: 'screenPageViews' }],
      orderBy: [{ metric: { metricName: 'screenPageViews' }, desc: true }],
      limit: 25
    });

    // Fetch events
    const [eventResponse] = await analyticsClient.runRealtimeReport({
      property: `properties/${propertyId}`,
      dimensions: [{ name: 'eventName' }],
      metrics: [{ name: 'eventCount' }],
      orderBy: [{ metric: { metricName: 'eventCount' }, desc: true }],
      limit: 25
    });

    // Fetch device categories
    const [deviceResponse] = await analyticsClient.runRealtimeReport({
      property: `properties/${propertyId}`,
      dimensions: [{ name: 'deviceCategory' }],
      metrics: [{ name: 'activeUsers' }],
      orderBy: [{ metric: { metricName: 'activeUsers' }, desc: true }],
      limit: 10,
      returnPropertyQuota: true
    });

    const response = {
      pageResponse,
      eventResponse,
      sourceResponse: deviceResponse
    };

    // Cache the response
    await req.redisClient.set(cacheKey, JSON.stringify(response), {
      EX: CACHE_DURATIONS.REALTIME_DETAILED
    });

    res.json({ success: true, data: response });
  } catch (error) {
    logger.error('Error fetching realtime detailed data:', error);
    res.status(500).json({ success: false, error: error.message });
  }
});

// User behavior endpoint
router.get('/user-behavior', async (req, res) => {
  try {
    const { timeRange = '30' } = req.query;
    const cacheKey = `analytics:user_behavior:${timeRange}`;
    
    // Check Redis cache
    const cachedData = await req.redisClient.get(cacheKey);
    if (cachedData) {
      logger.info('Returning cached user behavior data');
      return res.json({ success: true, data: JSON.parse(cachedData) });
    }

    // Fetch page data
    const [pageResponse] = await analyticsClient.runReport({
      property: `properties/${propertyId}`,
      dateRanges: [{ startDate: `${timeRange}daysAgo`, endDate: 'today' }],
      dimensions: [{ name: 'pagePath' }],
      metrics: [
        { name: 'screenPageViews' },
        { name: 'averageSessionDuration' },
        { name: 'bounceRate' },
        { name: 'sessions' }
      ],
      orderBy: [{
        metric: { metricName: 'screenPageViews' },
        desc: true
      }],
      limit: 25
    });

    // Fetch device data
    const [deviceResponse] = await analyticsClient.runReport({
      property: `properties/${propertyId}`,
      dateRanges: [{ startDate: `${timeRange}daysAgo`, endDate: 'today' }],
      dimensions: [{ name: 'deviceCategory' }],
      metrics: [
        { name: 'screenPageViews' },
        { name: 'sessions' }
      ]
    });

    // Fetch source data
    const [sourceResponse] = await analyticsClient.runReport({
      property: `properties/${propertyId}`,
      dateRanges: [{ startDate: `${timeRange}daysAgo`, endDate: 'today' }],
      dimensions: [{ name: 'sessionSource' }],
      metrics: [
        { name: 'sessions' },
        { name: 'conversions' }
      ],
      orderBy: [{
        metric: { metricName: 'sessions' },
        desc: true
      }],
      limit: 25,
      returnPropertyQuota: true
    });

    const response = {
      pageResponse,
      deviceResponse,
      sourceResponse
    };

    // Cache the response
    await req.redisClient.set(cacheKey, JSON.stringify(response), {
      EX: CACHE_DURATIONS.USER_BEHAVIOR
    });

    res.json({ success: true, data: response });
  } catch (error) {
    logger.error('Error fetching user behavior data:', error);
    res.status(500).json({ success: false, error: error.message });
  }
});

module.exports = router; 