const Expense = require("../../models/accounts/expenseModel");
const { errorResponse } = require("../../utils/errorResponseHandler");
const { logUserAction } = require("../../utils/userActionLogger");

/* =====================================================
   CREATE EXPENSE (ADMIN)
   POST /expenses
===================================================== */
const createExpense = async (req, res) => {
  try {
    const userId = req.user._id;
    const orgId = req.user.orgId;

    const {
      expenseNumber,
      category,
      // reimbursementType,
      expenseName,
      amount,
      expenseDate,
      notes,
      attachments = [],
    } = req.body;

    if (!expenseNumber || !category || !amount || !expenseDate) {
      return errorResponse(res, "Missing required fields", 400);
    }

    const expense = await Expense.create({
      orgId,
      expenseNumber,
      category,
      expenseName,
      amount,
      expenseDate,
      notes,
      attachments,
      createdBy: userId,
      updatedBy: userId,
    });
    const populatedExpense = await Expense.findById(expense._id)
      .populate("createdBy", "firstName lastName");

    await logUserAction({
      userId,
      orgId,
      action: "CREATE_EXPENSE",
      model: "Expense",
      modelId: expense._id,
      req,
    });

    return res.status(201).json({
      success: true,
      message: "Expense created successfully",
      data: populatedExpense,
    });
  } catch (err) {
    if (err.code === 11000) {
      return errorResponse(res, "Expense number already exists", 400);
    }
    return errorResponse(res, "Failed to create expense", 500, err);
  }
};

/* =====================================================
   GET ALL EXPENSES (ADMIN)
   GET /expenses
   Filters + Pagination
===================================================== */
const getAllExpenses = async (req, res) => {
  try {
    const orgId = req.user.orgId;
    const { status, category, search, page = 1, limit = 10 } = req.query;

    const filter = {
      orgId,
      isDeleted: false,
    };

    if (status) filter.status = status;
    if (category) filter.category = category;

    if (search) {
      filter.$or = [
        { expenseNumber: { $regex: search, $options: "i" } },
        { category: { $regex: search, $options: "i" } },
      ];
    }

    const skip = (page - 1) * limit;

    const [expenses, total] = await Promise.all([
      Expense.find(filter)
        .sort({ createdAt: -1 })
        .populate("createdBy", "firstName lastName")
        .skip(skip)
        .limit(Number(limit)),
      Expense.countDocuments(filter),
    ]);

    return res.json({
      success: true,
      data: expenses,
      pagination: {
        total,
        page: Number(page),
        limit: Number(limit),
        pages: Math.ceil(total / limit),
      },
    });
  } catch (err) {
    return errorResponse(res, "Failed to fetch expenses", 500, err);
  }
};

/* =====================================================
   GET EXPENSE BY ID
   GET /expenses/:id
===================================================== */
const getExpenseById = async (req, res) => {
  try {
    const expense = await Expense.findOne({
      _id: req.params.id,
      orgId: req.user.orgId,
      isDeleted: false,
    });

    if (!expense) {
      return errorResponse(res, "Expense not found", 404);
    }

    return res.json({ success: true, data: expense });
  } catch (err) {
    return errorResponse(res, "Failed to fetch expense", 500, err);
  }
};

/* =====================================================
   UPDATE EXPENSE
   PUT /expenses/:id
===================================================== */
const updateExpense = async (req, res) => {
  try {
    const expense = await Expense.findOne({
      _id: req.params.id,
      orgId: req.user.orgId,
      isDeleted: false,
    });

    if (!expense) {
      return errorResponse(res, "Expense not found", 404);
    }

    Object.assign(expense, req.body, {
      updatedBy: req.user._id,
    });

    await expense.save();

    await logUserAction({
      userId: req.user._id,
      orgId: req.user.orgId,
      action: "UPDATE_EXPENSE",
      model: "Expense",
      modelId: expense._id,
      req,
    });

    return res.json({
      success: true,
      message: "Expense updated successfully",
      data: expense,
    });
  } catch (err) {
    return errorResponse(res, "Failed to update expense", 500, err);
  }
};

/* =====================================================
   UPDATE STATUS (PAID / REJECTED)
   PATCH /expenses/:id/status
===================================================== */
const updateExpenseStatus = async (req, res) => {
  try {
    const { amount,expenseName, notes } = req.body;

    // if (!["PENDING", "PAID", "REJECTED"].includes(status)) {
    //   return errorResponse(res, "Invalid status", 400);
    // }

    const expense = await Expense.findOne({
      _id: req.params.id,
      orgId: req.user.orgId,
      isDeleted: false,
    })
      .populate("createdBy", "firstName lastName")
      .populate("updatedBy", "firstName lastName");
    ;

    if (!expense) {
      return errorResponse(res, "Expense not found", 404);
    }

    // expense.status = status;
    expense.amount = amount;
    expense.expenseName = expenseName;
    expense.notes = notes;
    expense.updatedBy = req.user._id;

    await expense.save();

    return res.json({
      success: true,
      message: "Expense status updated",
      data: expense
    });
  } catch (err) {
    return errorResponse(res, "Failed to update expense status", 500, err);
  }
};

/* =====================================================
   DELETE EXPENSE (SOFT DELETE)
   DELETE /expenses/:id
===================================================== */
const deleteExpense = async (req, res) => {
  try {
    const expense = await Expense.findOne({
      _id: req.params.id,
      orgId: req.user.orgId,
      isDeleted: false,
    });

    if (!expense) {
      return errorResponse(res, "Expense not found", 404);
    }

    expense.isDeleted = true;
    expense.updatedBy = req.user._id;

    await expense.save();

    await logUserAction({
      userId: req.user._id,
      orgId: req.user.orgId,
      action: "DELETE_EXPENSE",
      model: "Expense",
      modelId: expense._id,
      req,
    });

    return res.json({
      success: true,
      message: "Expense deleted successfully",
    });
  } catch (err) {
    return errorResponse(res, "Failed to delete expense", 500, err);
  }
};

module.exports = {
  createExpense,
  getAllExpenses,
  getExpenseById,
  updateExpense,
  updateExpenseStatus,
  deleteExpense,
};
