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.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 = "${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 {
  
        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())&&
                        !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 = 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();
        }

    }

}
