package enseirb.myinpulse.service;

import enseirb.myinpulse.model.*;
import enseirb.myinpulse.service.database.*;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Service
public class SharedApiService {

    protected static final Logger logger = LogManager.getLogger();

    private final ProjectService projectService;
    private final EntrepreneurService entrepreneurService;
    private final SectionCellService sectionCellService;
    private final AppointmentService appointmentService;

    private final UtilsService utilsService;

    @Autowired
    SharedApiService(
            ProjectService projectService,
            EntrepreneurService entrepreneurService,
            SectionCellService sectionCellService,
            AppointmentService appointmentService,
            UtilsService utilsService) {
        this.projectService = projectService;
        this.entrepreneurService = entrepreneurService;
        this.sectionCellService = sectionCellService;
        this.appointmentService = appointmentService;
        this.utilsService = utilsService;
    }

    // TODO filter this with date
    public Iterable<SectionCell> getSectionCells(
            long projectId, long sectionId, String date, String mail) {

        if (!utilsService.isAllowedToCheckProject(mail, projectId)) {
            logger.warn(
                    "User {} tried to check section cells of the project {} but is not allowed to.",
                    mail,
                    projectId);
            throw new ResponseStatusException(
                    HttpStatus.UNAUTHORIZED, "You're not allowed to check this project");
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        LocalDateTime dateTime = LocalDateTime.parse(date, formatter);

        Project project = this.projectService.getProjectById(projectId);
        return this.sectionCellService.getSectionCellsByProjectAndSectionIdBeforeDate(
                project, sectionId, dateTime);
    }

    // TODO: test
    public Iterable<Entrepreneur> getEntrepreneursByProjectId(long projectId, String mail) {
        if (!utilsService.isAllowedToCheckProject(mail, projectId)) {
            logger.warn(
                    "User {} tried to check the member of the project {} but is not allowed to.",
                    mail,
                    projectId);
            throw new ResponseStatusException(
                    HttpStatus.UNAUTHORIZED, "You're not allowed to check this project");
        }
        Project project = this.projectService.getProjectById(projectId);
        return this.entrepreneurService.GetEntrepreneurByProject(project);
    }

    // TODO: test
    public Administrator getAdminByProjectId(long projectId, String mail) {
        if (!utilsService.isAllowedToCheckProject(mail, projectId)) {
            logger.warn(
                    "User {} tried to check the admin of the project {} but is not allowed to.",
                    mail,
                    projectId);
            throw new ResponseStatusException(
                    HttpStatus.UNAUTHORIZED, "You're not allowed to check this project");
        }
        Project project = this.projectService.getProjectById(projectId);
        return project.getAdministrator();
    }

    // TODO
    public Iterable<Appointment> getAppointmentsByProjectId(long projectId, String mail) {
        if (!utilsService.isAllowedToCheckProject(mail, projectId)) {
            logger.warn(
                    "User {} tried to check the appointments related to the project {} but is not allowed to.",
                    mail,
                    projectId);
            throw new ResponseStatusException(
                    HttpStatus.UNAUTHORIZED, "You're not allowed to check this project");
        }
        logger.info(
                "User {} tried to check the appointments related to the project {}",
                mail,
                projectId);
        Iterable<SectionCell> sectionCells =
                this.sectionCellService.getSectionCellsByProject(
                        projectService.getProjectById(projectId),
                        2L); // sectionId useless in this function ?
        List<Appointment> appointments = new ArrayList<Appointment>();
        sectionCells.forEach(
                sectionCell -> {
                    appointments.addAll(
                            this.sectionCellService.getAppointmentsBySectionCellId(
                                    sectionCell.getIdSectionCell()));
                });
        return appointments;
    }

    // TODO
    public void getPDFReport(long appointmentId, String mail) {
        long projectId =
                this.appointmentService
                        .getAppointmentById(appointmentId)
                        .getAppointmentListSectionCell()
                        .getFirst()
                        .getProjectSectionCell()
                        .getIdProject();
        if (!utilsService.isAllowedToCheckProject(mail, projectId)) {
            logger.warn(
                    "User {} tried to generate the PDF report {} related to the appointment {} but is not allowed to.",
                    mail,
                    this.appointmentService
                            .getAppointmentById(appointmentId)
                            .getAppointmentReport()
                            .getIdReport(),
                    appointmentId);
            throw new ResponseStatusException(
                    HttpStatus.UNAUTHORIZED, "You're not allowed to check this project");
        }
        /* return this.appointmentService
        .getAppointmentById(appointmentId)
        .getAppointmentReport().getReportContent(); */
        // generate pdf from this string, and format it to be decent looking
        throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED, "Not implemented yet");
    }

    // TODO
    public void createAppointmentRequest(Appointment appointment, String mail) {
        throw new ResponseStatusException(HttpStatus.NOT_IMPLEMENTED, "Not implemented yet");
    }
}