const db = require('../models');
const { sendResponse, sendError } = require('../utils/response');
const asyncHandler = require('../middlewares/asyncHandler');
const { getPagination, getPagingData } = require('../utils/pagination');
const { Op } = require('sequelize');

// Get notifications for current user
exports.getNotifications = asyncHandler(async (req, res) => {
  const userId = req.user?.userId;
  const companyId = req.user?.companyId;
  const { page = 1, limit = 20, is_read, type } = req.query;

  if (!userId) {
    return sendError(res, 'User ID is required', 400);
  }

  const where = {
    user_id: userId,
    company_id: companyId
  };

  if (is_read !== undefined) {
    where.is_read = is_read === 'true' || is_read === true;
  }

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

  const { limit: pageSize, offset } = getPagination(page, limit);

  const { count, rows } = await db.Notification.findAndCountAll({
    where,
    order: [['created_at', 'DESC']],
    limit: pageSize,
    offset: offset
  });

  const response = getPagingData({ count, rows }, page, pageSize);
  sendResponse(res, 200, true, 'Notifications retrieved successfully', response);
});

// Get unread notification count
exports.getUnreadCount = asyncHandler(async (req, res) => {
  const userId = req.user?.userId;
  const companyId = req.user?.companyId;

  if (!userId) {
    return sendError(res, 'User ID is required', 400);
  }

  const count = await db.Notification.count({
    where: {
      user_id: userId,
      company_id: companyId,
      is_read: false
    }
  });

  sendResponse(res, 200, true, 'Unread count retrieved successfully', { count });
});

// Mark notification as read
exports.markAsRead = asyncHandler(async (req, res) => {
  const { id } = req.params;
  const userId = req.user?.userId;
  const companyId = req.user?.companyId;

  if (!userId) {
    return sendError(res, 'User ID is required', 400);
  }

  const notification = await db.Notification.findOne({
    where: {
      id,
      user_id: userId,
      company_id: companyId
    }
  });

  if (!notification) {
    return sendError(res, 'Notification not found', 404);
  }

  await notification.update({
    is_read: true,
    read_at: new Date(),
    updated_by: userId
  });

  sendResponse(res, 200, true, 'Notification marked as read', notification);
});

// Mark all notifications as read
exports.markAllAsRead = asyncHandler(async (req, res) => {
  const userId = req.user?.userId;
  const companyId = req.user?.companyId;

  if (!userId) {
    return sendError(res, 'User ID is required', 400);
  }

  await db.Notification.update(
    {
      is_read: true,
      read_at: new Date(),
      updated_by: userId
    },
    {
      where: {
        user_id: userId,
        company_id: companyId,
        is_read: false
      }
    }
  );

  sendResponse(res, 200, true, 'All notifications marked as read', null);
});

// Delete notification
exports.deleteNotification = asyncHandler(async (req, res) => {
  const { id } = req.params;
  const userId = req.user?.userId;
  const companyId = req.user?.companyId;

  if (!userId) {
    return sendError(res, 'User ID is required', 400);
  }

  const notification = await db.Notification.findOne({
    where: {
      id,
      user_id: userId,
      company_id: companyId
    }
  });

  if (!notification) {
    return sendError(res, 'Notification not found', 404);
  }

  await notification.destroy();

  sendResponse(res, 200, true, 'Notification deleted successfully', null);
});

