const db = require("../models");
const Employee = db.employee;

var bcrypt = require("bcryptjs");
const { splitSite } = require("../middlewares");

const ALL_PERMISSIONS = [
  'Dashboard',
  'Admin View',
  'View_Info Screen',
  'Edit_Info Screen',
  'View_Customer Info _Personal Info',
  'View_Customer Info _Care & Services',
  'View_Customer Info _Medical & Insurance',
  'View_Customer Info _Confidential Details',
  'View_Customer Info _Form Submission',
  'Edit_Customer Info _ Personal Info',
  'Edit_Customer Info _ Care & Services',
  'Edit_Customer Info _ Medical & Insurance',
  'Edit_Customer Info _ Confidential Details',
  'Edit_Customer Info _ Form Submission',
  'Discharge_Customer',
  'Reactivate_Customer',
  'Create_Customer',
  'Export_Customer Report',
  'View _Calendar _Medical Appointment',
  'View _Calendar _Activities',
  'View _Calendar _Attendance Notes',
  'View _Calendar _Meal Plan',
  'View _Calendar _Important Dates',
  'Edit&Create _Calendar _Medical Appointment',
  'Edit&Create _Calendar _Activities',
  'Edit&Create _Calendar _Attendance Notes',
  'Edit&Create _Calendar _Meal Plan',
  'Edit&Create _Calendar _Important Dates',
  'View_Messaging',
  'Sent_Messaging',
  'View_Messaging Template',
  'Create&Edit_Messaging Template',
  'View_Vehicle info_Basic Info',
  'View_Vehicle info_Documents',
  'View_Vehicle info_Repair Records',
  'Edit_Vehicle info_Basic Info',
  'Edit_Vehicle info_Documents',
  'Edit_Vehicle info_Repair Records',
  'Add_New Vehicle',
  'Archive_Vehicle',
  'Delete_Vehicle',
  'Export_Vehicle Report',
  'View_Transportation Schedule_Route Overview',
  'Create&Edit_Transportation Schedule',
  'Export_Transportation Schedule Report',
  'View_Route Template',
  'Create&Edit_Route Template',
  'View_Driver Assignment for Appointment',
  'Edit_Driver Assignment for Appointment',
  'View_Provider Info',
  'Create & Edit _Provider Info',
  'View_Appointment Request',
  'Edit & Create_Appointment Request',
  'View_Appointment Calendar',
  'Edit & Create_Appointment Calendar',
  'Medical Template',
  'View_Meal Status',
  'Edit_Meal Status',
  'View_Seating Chart',
  'Edit_Seating Chart',
  'Employee page',
  'Set Permission for Employee'
];

const hasAllPermissionsByUsername = (username) => (username || '').toString().trim().toLowerCase() === 'testadmin03';
// Create and Save a new Employee (driver, distributor, admin)
exports.createEmployee = (req, res) => {
  // Validate request
  if (!req.body.username) {
    res.status(400).send({ message: "Content can not be empty!" });
    return;
  }
  const site = splitSite.findSiteNumber(req);
  const normalizedUsername = req.body.username || req.body.email || '';
  const requestPermissions = Array.isArray(req.body.permissions) ? req.body.permissions : [];
  // Create a Employee
  const employee = new Employee({
    username: normalizedUsername,
    name_cn: req.body.name_cn || '',
    email: req.body.email || '',
    password: req.body.password ? bcrypt.hashSync(req.body.password, 8) : '',
    roles: req.body.roles || [],
    permissions: hasAllPermissionsByUsername(normalizedUsername) ? ALL_PERMISSIONS : requestPermissions,
    mobile_phone: req.body.mobile_phone || '',
    home_phone: req.body.home_phone || '',
    language: req.body.language || '',
    employment_status: req.body.employment_status || '',
    address: req.body.address || '',
    date_hired: req.body.date_hired || '',
    driver_capacity: req.body.driver_capacity || null,
    create_by: req.body.create_by || '',
    create_date: new Date(),
    edit_by: req.body.edit_by || '',
    edit_date: new Date(),
    note: req.body.note || '',
    tags: req.body.tags || [],
    fetch_route_time: req.body.fetch_route_time || null,
    site,
    // new fields added and legacy fields are used in HR system
    trinet_id: req.body.trinet_id || '',
    name: req.body.name || '',
    firstname: req.body.firstname || '',
    middlename: req.body.middlename || '',
    lastname: req.body.lastname || '',
    preferred_name: req.body.preferred_name || '',
    ssn: req.body.ssn || '',
    marital_status: req.body.marital_status || '',
    gender: req.body.gender || '',
    city: req.body.city || '',
    street_address: req.body.street_address || '',
    state: req.body.state || '',
    zip: req.body.zip || '',
    country: req.body.country || '',
    work_email: req.body.work_email || '',
    personal_email: req.body.personal_email || '',
    phone: req.body.phone || '',
    work_phone: req.body.work_phone || '',
    birth_date: req.body.birth_date || '',
    work_phone_ext: req.body.work_phone_ext || '',
    dietary_restrictions: req.body.dietary_restrictions || '',
    tshirt_size: req.body.tshirt_size || '',
    title: req.body.title || '',
    title_cn: req.body.title_cn || '',
    department: req.body.department || '',
    manager_name: req.body.manager_name || '',
    manager_email: req.body.manager_email || '',
    manager_trinet_id: req.body.manager_trinet_id || '',
    manager_id: req.body.manager_id || '',
    direct_reports: req.body.direct_reports || [],
    current_employment_start_date: req.body.current_employment_start_date || '',
    initial_employment_start_date: req.body.initial_employment_start_date || '',
    status: req.body.status || 'active',
    work_location: req.body.work_location || '',
    employment_type: req.body.employment_type || '',
    employment_start_date: req.body.employment_start_date || '',
    employment_end_date: req.body.employment_end_date || '',
    termination_date: req.body.termination_date || '',
    termination_type: req.body.termination_type || '',
    termination_reason: req.body.termination_reason || '',
    full_time_start_date: req.body.full_time_start_date || '',
    end_date: req.body.end_date || '',
    month_of_service: req.body.month_of_service || null,
    full_years_of_service: req.body.full_years_of_service || null,
    compensation_type: req.body.compensation_type || '',
    compensation: req.body.compensation || null,
    worker_type: req.body.worker_type || '',
    monthly_salary: req.body.monthly_salary || null,
    currency: req.body.currency || '',
    salary: req.body.salary || null,
    hourly_wage: req.body.hourly_wage || null,
    work_site: req.body.work_site || null,
    next_anniversary: req.body.next_anniversary || null,
    job_id: req.body.job_id || '',
    job_title: req.body.job_title || '',
    job_category: req.body.job_category || '',
    add_to_payroll: req.body.add_to_payroll || false,
    collect_tax_information: req.body.collect_tax_information || false,
    fingerprints: req.body.fingerprints || [],
    entry_passcode: req.body.entry_passcode || []
  });
  // Save Employee in the database
  employee
    .save(employee)
    .then(data => {
      res.send(data);
    })
    .catch(err => {
      res.status(500).send({
        message:
          err.message || "Some error occurred while creating the Employee."
      });
    });
};
// Retrieve all Employee from the database.
exports.getAllEmployees = (req, res) => {
  var params = req.query;
  var condition = {};
  condition = splitSite.splitSiteGet(req, condition);
  if (params.status) {
    condition.status = params.status;
  }
  if (params.role) {
    condition.roles = params.role;
  }
  if (params.site) {
    condition.site = params.site;
  }
  Employee.find(condition)
    .then(data => {
      res.send(data);
    })
    .catch(err => {
      res.status(500).send({
        message:
          err.message || "Some error occurred while retrieving employees."
      });
    });
};

// Retrive all Employees without site
exports.getAllEmployeesAcrossSites = (req, res) => {
  var params = req.query;
  var condition = {};
  if (params.status) {
    condition.status = params.status;
  }
  if (params.role) {
    condition.roles = params.role;
  } 
  Employee.find(condition)
    .then(data => {
      res.send(data);
    })
    .catch(err => {
      res.status(500).send({
        message:
          err.message || "Some error occurred while retrieving employees."
      });
    });
};

// Retrieve all Active Employee from the database.
exports.getAllActiveEmployees = (req, res) => {
  var params = req.query;
  var condition = { status: 'active' };
  condition = splitSite.splitSiteGet(req, condition);
  if (params.roles) {
    condition.roles = params.roles;
  } 
  if (params.site) {
    condition.site = params.site;
  }
  Employee.find(condition)
    .then(data => {
      res.send(data);
    })
    .catch(err => {
      res.status(500).send({
        message:
          err.message || "Some error occurred while retrieving employees."
      });
    });
};
// Get One Employee by Id
exports.getEmployee = (req, res) => {
  const id = req.params.id;
  Employee.findById(id)
    .then(data => {
      if (!data)
        res.status(404).send({ message: "Not found Employee with id " + id });
      else res.send(data);
    })
    .catch(err => {
      res
        .status(500)
        .send({ message: "Error retrieving Employee with id=" + id });
    });
};
// Update a Employee by the id in the request
exports.updateEmployee = (req, res) => {
  if (!req.body) {
    return res.status(400).send({
      message: "Data to update can not be empty!"
    });
  }
  const id = req.params.id;
  if (req.body.password) {
    req.body.password = bcrypt.hashSync(req.body.password, 8);
  }
  Employee.findById(id)
    .then((existingEmployee) => {
      if (!existingEmployee) {
        res.status(404).send({
          message: `Cannot update employee with id=${id}. Maybe Employee was not found!`
        });
        return null;
      }
      const nextData = Object.assign({}, req.body);
      const effectiveUsername = nextData.username || existingEmployee.username;
      if (hasAllPermissionsByUsername(effectiveUsername)) {
        nextData.permissions = ALL_PERMISSIONS;
      }
      return Employee.findByIdAndUpdate(id, nextData, { useFindAndModify: false });
    })
    .then((data) => {
      if (!data) return;
      res.send({ success: true, message: "Employee was updated successfully." });
    })
    .catch(err => {
      res.status(500).send({
        success: false,
        message: "Error updating Employee with id=" + id
      });
    });
};
// Soft Delete a Employee with the specified id in the request
exports.deactivateEmployee = (req, res) => {
  
};
// Delete a Employee by id
exports.deleteEmployee = (req, res) => {

};
// Get Employees with username or email 
exports.getEmployeesWithUsernameOrEmail = (req, res) => {

};
