// src/controllers/usage.controller.js
// 사용량 컨트롤러

const { UsageLog, User } = require('../models');
const { Op } = require('sequelize');

/**
 * 사용량 요약 조회
 */
exports.getSummary = async (req, res, next) => {
  try {
    const userId = req.user.userId;

    // 사용자 정보 조회
    const user = await User.findByPk(userId);
    if (!user) {
      return res.status(404).json({
        success: false,
        error: {
          code: 'USER_NOT_FOUND',
          message: '사용자를 찾을 수 없습니다.',
        },
      });
    }

    // 이번 달 사용량
    const now = new Date();
    const monthlyUsage = await UsageLog.getMonthlyTotalByUser(
      userId,
      now.getFullYear(),
      now.getMonth() + 1
    );

    // 오늘 사용량
    const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    const todayEnd = new Date(todayStart);
    todayEnd.setDate(todayEnd.getDate() + 1);

    const todayUsage = await UsageLog.findOne({
      where: {
        userId,
        createdAt: {
          [Op.between]: [todayStart, todayEnd],
        },
      },
      attributes: [
        [UsageLog.sequelize.fn('SUM', UsageLog.sequelize.col('total_tokens')), 'totalTokens'],
        [UsageLog.sequelize.fn('SUM', UsageLog.sequelize.col('cost_usd')), 'totalCost'],
        [UsageLog.sequelize.fn('COUNT', UsageLog.sequelize.col('id')), 'requestCount'],
      ],
      raw: true,
    });

    return res.json({
      success: true,
      data: {
        plan: user.plan,
        limit: {
          monthly: user.monthlyTokenLimit,
          remaining: Math.max(0, user.monthlyTokenLimit - monthlyUsage.totalTokens),
        },
        usage: {
          today: {
            tokens: parseInt(todayUsage?.totalTokens, 10) || 0,
            cost: parseFloat(todayUsage?.totalCost) || 0,
            requests: parseInt(todayUsage?.requestCount, 10) || 0,
          },
          monthly: monthlyUsage,
        },
      },
    });
  } catch (error) {
    return next(error);
  }
};

/**
 * 일별 사용량 조회
 */
exports.getDailyUsage = async (req, res, next) => {
  try {
    const userId = req.user.userId;
    const { startDate, endDate } = req.query;

    // 기본값: 최근 30일
    const end = endDate ? new Date(endDate) : new Date();
    const start = startDate ? new Date(startDate) : new Date(end);
    if (!startDate) {
      start.setDate(start.getDate() - 30);
    }

    const dailyUsage = await UsageLog.getDailyUsageByUser(userId, start, end);

    return res.json({
      success: true,
      data: {
        startDate: start.toISOString().split('T')[0],
        endDate: end.toISOString().split('T')[0],
        usage: dailyUsage,
      },
    });
  } catch (error) {
    return next(error);
  }
};

/**
 * 월별 사용량 조회
 */
exports.getMonthlyUsage = async (req, res, next) => {
  try {
    const userId = req.user.userId;
    const now = new Date();
    const year = parseInt(req.query.year, 10) || now.getFullYear();
    const month = parseInt(req.query.month, 10) || (now.getMonth() + 1);

    const monthlyUsage = await UsageLog.getMonthlyTotalByUser(userId, year, month);

    return res.json({
      success: true,
      data: {
        year,
        month,
        usage: monthlyUsage,
      },
    });
  } catch (error) {
    return next(error);
  }
};

/**
 * 사용량 로그 목록 조회
 */
exports.getLogs = async (req, res, next) => {
  try {
    const userId = req.user.userId;
    const page = parseInt(req.query.page, 10) || 1;
    const limit = parseInt(req.query.limit, 10) || 20;
    const offset = (page - 1) * limit;

    const { count, rows: logs } = await UsageLog.findAndCountAll({
      where: { userId },
      attributes: [
        'id',
        'providerName',
        'modelName',
        'promptTokens',
        'completionTokens',
        'totalTokens',
        'costUsd',
        'responseTimeMs',
        'success',
        'errorMessage',
        'createdAt',
      ],
      order: [['createdAt', 'DESC']],
      limit,
      offset,
    });

    return res.json({
      success: true,
      data: {
        logs,
        pagination: {
          total: count,
          page,
          limit,
          totalPages: Math.ceil(count / limit),
        },
      },
    });
  } catch (error) {
    return next(error);
  }
};
