/**
 * Employee Controller
 * Handles employee management operations
 */

const Employee = require("../models/Employee");
const User = require("../models/User");
const ActivityLog = require("../models/ActivityLog");
const Notification = require("../models/Notification");
const { query, transaction } = require("../config/database");

/**
 * Get all employees
 * GET /api/employees
 */
const getAllEmployees = async (req, res, next) => {
  try {
    const { page, limit, search, departmentId, status, sortBy, sortOrder } =
      req.query;

    const result = await Employee.findAll({
      page: parseInt(page) || 1,
      limit: parseInt(limit) || 10,
      search,
      departmentId,
      status,
      sortBy,
      sortOrder,
    });

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

/**
 * Get employee by ID
 * GET /api/employees/:id
 */
const getEmployeeById = async (req, res, next) => {
  try {
    const employee = await Employee.findById(req.params.id);

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

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

/**
 * Create new employee
 * POST /api/employees
 */
const createEmployee = async (req, res, next) => {
  try {
    const {
      firstName,
      lastName,
      nic,
      email,
      mobile,
      address,
      jobTitle,
      departmentId,
      joinDate,
      status,
      createUserAccount,
      username,
      password,
      role,
    } = req.body;

    // Create employee
    const employee = await Employee.create({
      firstName,
      lastName,
      nic,
      email,
      mobile,
      address,
      jobTitle,
      departmentId,
      joinDate,
      status,
    });

    // Create user account if requested
    if (createUserAccount && username && password) {
      await User.create({
        employeeId: employee.id,
        username,
        email,
        password,
        role: role || "Employee",
      });
    }

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

    // Get complete employee data
    const createdEmployee = await Employee.findById(employee.id);

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

/**
 * Update employee
 * PUT /api/employees/:id
 */
const updateEmployee = async (req, res, next) => {
  try {
    const { id } = req.params;

    // Get existing employee
    const existingEmployee = await Employee.findById(id);

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

    // Update employee
    const updatedEmployee = await Employee.update(id, req.body);

    // Log activity
    await ActivityLog.create({
      userId: req.user.id,
      actionType: "UPDATE",
      entityType: "Employee",
      entityId: id,
      description: `Updated employee: ${updatedEmployee.first_name} ${updatedEmployee.last_name}`,
      oldValues: existingEmployee,
      newValues: updatedEmployee,
      ipAddress: req.ip,
      userAgent: req.headers["user-agent"],
    });

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

/**
 * Delete employee (soft delete)
 * DELETE /api/employees/:id
 */
const deleteEmployee = async (req, res, next) => {
  try {
    const { id } = req.params;

    const employee = await Employee.findById(id);

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

    await Employee.softDelete(id);

    // Deactivate user account if exists
    if (employee.user_id) {
      await User.update(employee.user_id, { isActive: false });
    }

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

    res.json({
      success: true,
      message: "Employee deleted successfully",
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Get employees by department
 * GET /api/employees/department/:departmentId
 */
const getEmployeesByDepartment = async (req, res, next) => {
  try {
    const employees = await Employee.findByDepartment(req.params.departmentId);

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

/**
 * Get employee statistics
 * GET /api/employees/statistics
 */
const getEmployeeStatistics = async (req, res, next) => {
  try {
    const stats = await Employee.getStatistics();

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

module.exports = {
  getAllEmployees,
  getEmployeeById,
  createEmployee,
  updateEmployee,
  deleteEmployee,
  getEmployeesByDepartment,
  getEmployeeStatistics,
};
