/**
 * Department Controller
 * Handles department management operations
 */

const Department = require("../models/Department");
const ActivityLog = require("../models/ActivityLog");

/**
 * Get all departments
 * GET /api/departments
 */
const getAllDepartments = async (req, res, next) => {
  try {
    const { includeInactive, search } = req.query;

    const departments = await Department.findAll({
      includeInactive: includeInactive === "true",
      search,
    });

    res.json({
      success: true,
      data: departments,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Get department by ID
 * GET /api/departments/:id
 */
const getDepartmentById = async (req, res, next) => {
  try {
    const department = await Department.findById(req.params.id);

    if (!department) {
      return res.status(404).json({
        success: false,
        message: "Department not found",
      });
    }

    res.json({
      success: true,
      data: department,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Get department with employees
 * GET /api/departments/:id/employees
 */
const getDepartmentWithEmployees = async (req, res, next) => {
  try {
    const department = await Department.findWithEmployees(req.params.id);

    if (!department) {
      return res.status(404).json({
        success: false,
        message: "Department not found",
      });
    }

    res.json({
      success: true,
      data: department,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Create department
 * POST /api/departments
 */
const createDepartment = async (req, res, next) => {
  try {
    const { name, description, managerId, isActive } = req.body;

    // Check if department name exists
    const existing = await Department.findByName(name);

    if (existing) {
      return res.status(409).json({
        success: false,
        message: "Department with this name already exists",
      });
    }

    const department = await Department.create({
      name,
      description,
      managerId,
      isActive,
    });

    // Log activity
    await ActivityLog.create({
      userId: req.user.id,
      actionType: "CREATE",
      entityType: "Department",
      entityId: department.id,
      description: `Created department: ${name}`,
      newValues: department,
      ipAddress: req.ip,
      userAgent: req.headers["user-agent"],
    });

    const createdDepartment = await Department.findById(department.id);

    res.status(201).json({
      success: true,
      message: "Department created successfully",
      data: createdDepartment,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Update department
 * PUT /api/departments/:id
 */
const updateDepartment = async (req, res, next) => {
  try {
    const { id } = req.params;

    const existingDepartment = await Department.findById(id);

    if (!existingDepartment) {
      return res.status(404).json({
        success: false,
        message: "Department not found",
      });
    }

    // Check for duplicate name if name is being changed
    if (req.body.name && req.body.name !== existingDepartment.name) {
      const duplicateName = await Department.findByName(req.body.name);
      if (duplicateName) {
        return res.status(409).json({
          success: false,
          message: "Department with this name already exists",
        });
      }
    }

    const updatedDepartment = await Department.update(id, req.body);

    // Log activity
    await ActivityLog.create({
      userId: req.user.id,
      actionType: "UPDATE",
      entityType: "Department",
      entityId: id,
      description: `Updated department: ${updatedDepartment.name}`,
      oldValues: existingDepartment,
      newValues: updatedDepartment,
      ipAddress: req.ip,
      userAgent: req.headers["user-agent"],
    });

    res.json({
      success: true,
      message: "Department updated successfully",
      data: updatedDepartment,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Delete department
 * DELETE /api/departments/:id
 */
const deleteDepartment = async (req, res, next) => {
  try {
    const { id } = req.params;

    const department = await Department.findById(id);

    if (!department) {
      return res.status(404).json({
        success: false,
        message: "Department not found",
      });
    }

    await Department.delete(id);

    // Log activity
    await ActivityLog.create({
      userId: req.user.id,
      actionType: "DELETE",
      entityType: "Department",
      entityId: id,
      description: `Deleted department: ${department.name}`,
      oldValues: department,
      ipAddress: req.ip,
      userAgent: req.headers["user-agent"],
    });

    res.json({
      success: true,
      message: "Department deleted successfully",
    });
  } catch (error) {
    if (error.message.includes("Cannot delete department")) {
      return res.status(400).json({
        success: false,
        message: error.message,
      });
    }
    next(error);
  }
};

module.exports = {
  getAllDepartments,
  getDepartmentById,
  getDepartmentWithEmployees,
  createDepartment,
  updateDepartment,
  deleteDepartment,
};
