const Employee = require('../models/Employee');
const Department = require('../models/Department');
const Position = require('../models/Position');
const User = require('../models/User');

exports.addEmployee = async (req, res) => {
  try {
    const {
      userName,
      firstName,
      lastName,
      email,
      gender,
      dateOfBirth,
      telephone,
      address,
      hireDate,
      status,
      department,
      position,
    } = req.body;

    if (
      !firstName ||
      !lastName ||
      !email ||
      !gender ||
      !dateOfBirth ||
      !telephone ||
      !address ||
      !hireDate ||
      !status ||
      !department ||
      !position
    ) {
      return res.status(400).json({ message: 'All employee fields are required' });
    }

    const existing = await Employee.findOne({ email: email.toLowerCase() });
    if (existing) {
      return res.status(409).json({ message: 'Employee email already exists' });
    }

    const departmentExists = await Department.findById(department);
    if (!departmentExists) {
      return res.status(404).json({ message: 'Department not found' });
    }

    const positionExists = await Position.findById(position);
    if (!positionExists) {
      return res.status(404).json({ message: 'Position not found' });
    }

    const employee = await Employee.create({
      userName,
      firstName: firstName.trim(),
      lastName: lastName.trim(),
      email: email.toLowerCase(),
      gender,
      dateOfBirth,
      telephone: telephone.trim(),
      address: address.trim(),
      hireDate,
      status,
      department,
      position,
    });

    if (email) {
      const user = await User.findOne({ email: email.toLowerCase() });
      if (user) {
        user.employee = employee._id;
        await user.save();
      }
    }

    res.status(201).json(employee);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

exports.getEmployees = async (req, res) => {
  try {
    const employees = await Employee.find().populate('department position');
    res.json(employees);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

exports.getEmployee = async (req, res) => {
  try {
    const employee = await Employee.findById(req.params.id).populate('department position');
    if (!employee) {
      return res.status(404).json({ message: 'Employee not found' });
    }
    res.json(employee);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

exports.updateEmployee = async (req, res) => {
  try {
    const employee = await Employee.findById(req.params.id);
    if (!employee) {
      return res.status(404).json({ message: 'Employee not found' });
    }

    const {
      userName,
      firstName,
      lastName,
      email,
      gender,
      dateOfBirth,
      telephone,
      address,
      hireDate,
      status,
      department,
      position,
    } = req.body;

    if (
      !firstName ||
      !lastName ||
      !email ||
      !gender ||
      !dateOfBirth ||
      !telephone ||
      !address ||
      !hireDate ||
      !status ||
      !department ||
      !position
    ) {
      return res.status(400).json({ message: 'All employee fields are required' });
    }

    const existing = await Employee.findOne({
      email: email.toLowerCase(),
      _id: { $ne: req.params.id },
    });
    if (existing) {
      return res.status(409).json({ message: 'Employee email already exists' });
    }

    const departmentExists = await Department.findById(department);
    if (!departmentExists) {
      return res.status(404).json({ message: 'Department not found' });
    }

    const positionExists = await Position.findById(position);
    if (!positionExists) {
      return res.status(404).json({ message: 'Position not found' });
    }

    const oldEmail = employee.email;

    employee.userName = userName;
    employee.firstName = firstName.trim();
    employee.lastName = lastName.trim();
    employee.email = email.toLowerCase();
    employee.gender = gender;
    employee.dateOfBirth = dateOfBirth;
    employee.telephone = telephone.trim();
    employee.address = address.trim();
    employee.hireDate = hireDate;
    employee.status = status;
    employee.department = department;
    employee.position = position;

    await employee.save();

    if (oldEmail !== email.toLowerCase()) {
      const user = await User.findOne({ email: oldEmail });
      if (user) {
        user.email = email.toLowerCase();
        await user.save();
      }
    }

    const updatedEmployee = await Employee.findById(req.params.id).populate('department position');
    res.json(updatedEmployee);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

exports.deleteEmployee = async (req, res) => {
  try {
    const employee = await Employee.findById(req.params.id);
    if (!employee) {
      return res.status(404).json({ message: 'Employee not found' });
    }

    await Employee.findByIdAndDelete(req.params.id);
    res.json({ message: 'Employee deleted successfully' });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};
