const { Router } = require('express')
const mongoose = require('mongoose')

const { getAnswer } = require('../../utils/common')
const { CigaretteModel } = require('./model/cigarette')
const { authMiddleware } = require('./middleware/auth')

const router = Router()

// Все эндпоинты статистики требуют авторизации
router.use(authMiddleware)

// Агрегация по дням: количество сигарет в день для построения графика
router.get('/daily', async (req, res, next) => {
  try {
    const user = req.user
    const { from, to } = req.query

    const now = new Date()
    const defaultFrom = new Date(now)
    defaultFrom.setDate(defaultFrom.getDate() - 30)

    const fromDate = from ? new Date(from) : defaultFrom
    const toDate = to ? new Date(to) : now

    const match = {
      userId: new mongoose.Types.ObjectId(user.id),
      smokedAt: {
        $gte: fromDate,
        $lte: toDate,
      },
    }

    // Отладка: проверяем, сколько записей попадает в фильтр
    const totalCount = await CigaretteModel.countDocuments(match)
    console.log('[STATS] Match filter:', JSON.stringify(match, null, 2))
    console.log('[STATS] Total cigarettes in range:', totalCount)

    const data = await CigaretteModel.aggregate([
      { $match: match },
      {
        $group: {
          _id: {
            $dateToString: { format: '%Y-%m-%d', date: '$smokedAt', timezone: 'UTC' },
          },
          count: { $sum: 1 },
        },
      },
      { $sort: { _id: 1 } },
    ])

    console.log('[STATS] Aggregation result:', data)

    const result = data.map((item) => ({
      date: item._id,
      count: item.count,
    }))

    res.json(getAnswer(null, result))
  } catch (err) {
    next(err)
  }
})

// Сводная статистика: среднее в день, по дням недели, общее по всем пользователям
router.get('/summary', async (req, res, next) => {
  try {
    const user = req.user
    const { from, to } = req.query

    const now = new Date()
    const defaultFrom = new Date(now)
    defaultFrom.setDate(defaultFrom.getDate() - 30)

    const fromDate = from ? new Date(from) : defaultFrom
    const toDate = to ? new Date(to) : now

    // Фильтр для текущего пользователя
    const userMatch = {
      userId: new mongoose.Types.ObjectId(user.id),
      smokedAt: {
        $gte: fromDate,
        $lte: toDate,
      },
    }

    // Фильтр для всех пользователей (общая статистика)
    const globalMatch = {
      smokedAt: {
        $gte: fromDate,
        $lte: toDate,
      },
    }

    // 1. Статистика по дням (для текущего пользователя)
    const dailyStats = await CigaretteModel.aggregate([
      { $match: userMatch },
      {
        $group: {
          _id: {
            $dateToString: { format: '%Y-%m-%d', date: '$smokedAt', timezone: 'UTC' },
          },
          count: { $sum: 1 },
        },
      },
      { $sort: { _id: 1 } },
    ])

    const dailyData = dailyStats.map((item) => ({
      date: item._id,
      count: item.count,
    }))

    // 2. Среднее количество в день (для текущего пользователя)
    const totalCigarettes = dailyStats.reduce((sum, item) => sum + item.count, 0)
    const daysWithData = dailyStats.length
    const averagePerDay = daysWithData > 0 ? (totalCigarettes / daysWithData).toFixed(2) : 0

    // 3. Статистика по дням недели (для текущего пользователя)
    const weekdayStats = await CigaretteModel.aggregate([
      { $match: userMatch },
      {
        $group: {
          _id: { $dayOfWeek: '$smokedAt' }, // 1 = воскресенье, 2 = понедельник, ..., 7 = суббота
          count: { $sum: 1 },
        },
      },
      { $sort: { _id: 1 } },
    ])

    const weekdayNames = ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота']
    const weekdayData = weekdayStats.map((item) => {
      const dayIndex = item._id - 1 // MongoDB возвращает 1-7, приводим к 0-6
      return {
        dayOfWeek: item._id,
        dayName: weekdayNames[dayIndex],
        count: item.count,
      }
    })

    // Вычисляем среднее для каждого дня недели
    const weekdayAverages = weekdayData.map((day) => {
      // Считаем, сколько раз встречается этот день недели в периоде
      const occurrences = Math.floor(
        (toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24 * 7)
      ) + 1
      return {
        ...day,
        average: occurrences > 0 ? (day.count / occurrences).toFixed(2) : day.count,
      }
    })

    // 4. Определяем активных пользователей (от 2 до 40 сигарет в день в среднем)
    const MIN_CIGARETTES_PER_DAY = 2
    const MAX_CIGARETTES_PER_DAY = 40
    const periodDays = Math.ceil((toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24))
    
    // Получаем статистику по каждому пользователю
    const userStats = await CigaretteModel.aggregate([
      { $match: globalMatch },
      {
        $group: {
          _id: '$userId',
          total: { $sum: 1 },
        },
      },
    ])

    // Фильтруем активных пользователей (исключаем слишком низкие и слишком высокие значения)
    const activeUserIds = userStats
      .filter((stat) => {
        const avgPerDay = stat.total / periodDays
        return avgPerDay > MIN_CIGARETTES_PER_DAY && avgPerDay <= MAX_CIGARETTES_PER_DAY
      })
      .map((stat) => stat._id)

    const filteredLow = userStats.filter((stat) => stat.total / periodDays <= MIN_CIGARETTES_PER_DAY).length
    const filteredHigh = userStats.filter((stat) => stat.total / periodDays > MAX_CIGARETTES_PER_DAY).length

    console.log('[STATS] Total users:', userStats.length)
    console.log('[STATS] Active users (2-40 cigs/day):', activeUserIds.length)
    console.log('[STATS] Filtered out (too low):', filteredLow)
    console.log('[STATS] Filtered out (too high):', filteredHigh)

    // Фильтр только для активных пользователей
    const activeGlobalMatch = {
      ...globalMatch,
      userId: { $in: activeUserIds },
    }

    // Общая статистика по активным пользователям
    const globalDailyStats = await CigaretteModel.aggregate([
      { $match: activeGlobalMatch },
      {
        $group: {
          _id: {
            $dateToString: { format: '%Y-%m-%d', date: '$smokedAt', timezone: 'UTC' },
          },
          count: { $sum: 1 },
        },
      },
      { $sort: { _id: 1 } },
    ])

    const globalDailyData = globalDailyStats.map((item) => ({
      date: item._id,
      count: item.count,
    }))

    const globalTotalCigarettes = globalDailyStats.reduce((sum, item) => sum + item.count, 0)
    const globalDaysWithData = globalDailyStats.length
    const globalAveragePerDay =
      globalDaysWithData > 0 ? (globalTotalCigarettes / globalDaysWithData).toFixed(2) : 0

    // Общая статистика по дням недели (активные пользователи)
    const globalWeekdayStats = await CigaretteModel.aggregate([
      { $match: activeGlobalMatch },
      {
        $group: {
          _id: { $dayOfWeek: '$smokedAt' },
          count: { $sum: 1 },
        },
      },
      { $sort: { _id: 1 } },
    ])

    const globalWeekdayData = globalWeekdayStats.map((item) => {
      const dayIndex = item._id - 1
      return {
        dayOfWeek: item._id,
        dayName: weekdayNames[dayIndex],
        count: item.count,
      }
    })

    const globalWeekdayAverages = globalWeekdayData.map((day) => {
      const occurrences = Math.floor(
        (toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24 * 7)
      ) + 1
      return {
        ...day,
        average: occurrences > 0 ? (day.count / occurrences).toFixed(2) : day.count,
      }
    })

    // Количество активных пользователей
    const activeUsers = activeUserIds

    const result = {
      user: {
        daily: dailyData,
        averagePerDay: parseFloat(averagePerDay),
        weekday: weekdayAverages,
        total: totalCigarettes,
        daysWithData,
      },
      global: {
        daily: globalDailyData,
        averagePerDay: parseFloat(globalAveragePerDay),
        weekday: globalWeekdayAverages,
        total: globalTotalCigarettes,
        daysWithData: globalDaysWithData,
        activeUsers: activeUsers.length,
      },
      period: {
        from: fromDate.toISOString(),
        to: toDate.toISOString(),
      },
    }

    res.json(getAnswer(null, result))
  } catch (err) {
    next(err)
  }
})

module.exports = router


