package com.nisum.myteam.schedular;


import com.nisum.myteam.exception.handler.MyTeamException;
import com.nisum.myteam.model.AttendenceData;
import com.nisum.myteam.model.FunctionalGroup;
import com.nisum.myteam.model.Mail;
import com.nisum.myteam.model.dao.Employee;
import com.nisum.myteam.service.IFunctionalGroupService;
import com.nisum.myteam.service.IMailService;
import com.nisum.myteam.service.impl.AttendanceService;
import com.nisum.myteam.service.impl.EmployeeService;
import com.nisum.myteam.statuscodes.EmployeeStatus;
import com.nisum.myteam.utils.MyTeamUtils;
import com.nisum.myteam.utils.constants.EmpSubStatus;
import com.nisum.myteam.utils.constants.Shifts;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.mail.MessagingException;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Component
public class LeaveNotificationScheduler {
    private static final Logger logger = LoggerFactory.getLogger(LeaveNotificationScheduler.class);
    private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @Autowired
    private IMailService mailService;

    @Autowired
    private AttendanceService attendanceService;

    @Autowired
    private Environment environment;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private IFunctionalGroupService functionalGroupService;


    //@Scheduled(cron = "0 * * * * ?")
    //@Scheduled(cron = "00 50 15 * * 1-5")
    public void scheduleLeaveMailForShift1Empls() throws IOException, MessagingException, MyTeamException {
        //Shift 1(9:00 AM - 6:00 PM)
        logger.info(Shifts.SHIFT1.getShiftType() + " :: Execution Time - {}", dateTimeFormatter.format(LocalDateTime.now()));
        sendMailToAbsentees(Shifts.SHIFT1.getShiftType());

    }

    //@Scheduled(cron = "00 00 18 * * 1-5")
    public void scheduleLeaveMailForShift2Empls() throws IOException, MessagingException, MyTeamException {
        //Shift-2(2:00 PM - 11:00 PM)--General Shift
        logger.info(Shifts.SHIFT2.getShiftType() + " :: Execution Time - {}", dateTimeFormatter.format(LocalDateTime.now()));
        sendMailToAbsentees(Shifts.SHIFT2.getShiftType());

    }

    //@Scheduled(cron = "00 00 02 * * 2-6")
    public void scheduleLeaveMailForShift3Empls() throws IOException, MessagingException, MyTeamException {
        //Shift 3(10:00 PM - 6:00 AM)
        logger.info(Shifts.SHIFT3.getShiftType() + " :: Execution Time - {}", dateTimeFormatter.format(LocalDateTime.now()));
        sendMailToAbsentees(Shifts.SHIFT3.getShiftType());
    }


    //@Scheduled(cron = "00 30 11 * * 1-5")
    public void scheduleLeaveMailForShift4Empls() throws IOException, MessagingException, MyTeamException {
        //Shift 4(7:30 AM - 3:30 PM)
        logger.info(Shifts.SHIFT4.getShiftType() + " :: Execution Time - {}", dateTimeFormatter.format(LocalDateTime.now()));
        sendMailToAbsentees(Shifts.SHIFT4.getShiftType());

    }

    //@Scheduled(cron = "00 30 15 * * 1-5")
    public void scheduleLeaveMailForShift5Empls() throws IOException, MessagingException, MyTeamException {
        //Shift 5(11:30 AM - 7:30 PM)
        logger.info(Shifts.SHIFT5.getShiftType() + " :: Execution Time - {}", dateTimeFormatter.format(LocalDateTime.now()));
        sendMailToAbsentees(Shifts.SHIFT5.getShiftType());
    }


    private void sendMailToAbsentees(String shift) throws IOException, MessagingException, MyTeamException {

        Mail mail = new Mail();
        mail.setFrom(environment.getProperty("email.leave.notification.from"));
        mail.setSubject(environment.getProperty("email.leave.notification.subject"));

        Map<String, Object> model = new HashMap<String, Object>();
        String currentDate = dateTimeFormatter.format(LocalDateTime.now());
        String functionalGroupName;
        FunctionalGroup functionalGroup;
        Employee employee;
        String empSubStatus;
        try {

            List<AttendenceData> attendenceList = attendanceService.getAttendanciesReport(currentDate, shift);

            List<AttendenceData> absentiesList = attendenceList.stream()
                    .filter(attendance -> attendance.getPresent().equalsIgnoreCase(MyTeamUtils.ABSENT)).collect(Collectors.toList());

            for (AttendenceData absentee : absentiesList) {
                //model.put("employeeName", );//mail.setModel(model);

                employee = employeeService.getEmployeeById(absentee.getEmployeeId());
                empSubStatus = employee.getEmpSubStatus();

                if(empSubStatus==null)
                    empSubStatus="";

                if (employee.getEmpStatus().equalsIgnoreCase(EmployeeStatus.ACTIVE.getStatus()) && !empSubStatus.equalsIgnoreCase(EmpSubStatus.LONG_LEAVE.getLeaveType()) &&
                        !empSubStatus.equalsIgnoreCase(EmpSubStatus.MATERNITY_LEAVE.getLeaveType()) &&
                        !empSubStatus.equalsIgnoreCase(EmpSubStatus.ONSITE_TRAVEL.getLeaveType())) {

                    logger.info("Mail Notification is sending to:" + absentee.getEmployeeName() + "::" + absentee.getEmailId());
                    //mail.setEmpName(absentee.getEmployeeName());
                    //mail.setTo(absentee.getEmailId());

                    mail.setEmpName("Vijay");
                    mail.setTo("vakula@nisum.com");

                    functionalGroup = functionalGroupService.getFunctionalGroup(employee.getFunctionalGroup());
                    //mail.setCc(new String[]{functionalGroup.getGroupHeadEmailId()});
                    mail.setCc(new String[]{"mduppanapudi@nisum.com"});
                    mailService.sendLeaveNotification(mail);

                }

            }

        } catch (MyTeamException e) {
            e.printStackTrace();
        }

    }

}
