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.model.dao.EmployeeSubStatus;
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.service.impl.SubStatusService;
import com.nisum.myteam.statuscodes.EmployeeStatus;
import com.nisum.myteam.utils.MyTeamDateUtils;
import com.nisum.myteam.utils.MyTeamUtils;
import com.nisum.myteam.utils.constants.EmpSubStatus;
import com.nisum.myteam.utils.constants.Shifts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.scheduling.annotation.Scheduled;
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;

    @Autowired
    private SubStatusService subStatusService;


     @Scheduled(cron = "${email.leave.notification.shift1.cron}")
    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 = "${email.leave.notification.shift2.cron}")
    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 = "${email.leave.notification.shift3.cron}")
    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 = "${email.leave.notification.shift4.cron}")
    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 = "${email.leave.notification.shift5.cron}")
    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 {


        Map<String, Object> model = new HashMap<String, Object>();
        String currentDate = dateTimeFormatter.format(LocalDateTime.now());
        String functionalGroupName;
        final String mailSubject = String.valueOf("Date::").concat(MyTeamDateUtils.FormatTodaysDate() + "::").concat(environment.getProperty("email.leave.notification.subject"));

        Employee employee;
        String empSubStatus;
        try {

            if (!MyTeamDateUtils.isTodayHoliday(environment.getProperty("email.holidays.list.2019", "14-01-2019,21-03-2019,19-04-2019,05-06-2019,12-08-2019,15-08-2019,02-09-2019,02-10-2019,08-10-2019,25-12-2019"))) {

                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);

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

                    employee = employeeService.getEmployeeById(absentee.getEmployeeId());
                    EmployeeSubStatus subStatus = subStatusService.getCurrentSubStatus(employee.getEmployeeId());
                    empSubStatus = (String) subStatus.getSubStatus();

                    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()) &&
                                    !empSubStatus.equalsIgnoreCase(EmpSubStatus.AT_CLIENT_LOCATION.getLeaveType()))) {

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

                        FunctionalGroup functionalGroup = functionalGroupService.getFunctionalGroup(employee.getFunctionalGroup());
                        if (functionalGroup != null) {
                            mail.setCc(new String[]{functionalGroup.getGroupHeadEmailId()});//mail.setCc(new String[]{"prayasjain21@gmail.com"});
                        }
                        mailService.sendLeaveNotification(mail);

                    }

                }
            }

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


    }

}
