package com.sn.sowsysrestapi.domain.service;

import com.sn.sowsysrestapi.domain.entity.CompletedTask;
import com.sn.sowsysrestapi.domain.entity.Report;
import com.sn.sowsysrestapi.domain.exception.CompletedTaskNotFoundException;
import com.sn.sowsysrestapi.domain.exception.EntityInUseException;
import com.sn.sowsysrestapi.domain.repository.CompletedTaskRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Service;

import javax.persistence.PrePersist;

@Service
public class CompletedTaskService {

    public static final String MSG_ENTITY_IN_USE = "Completed Task with ID %d can't be deleted." +
            " Reason: Other entity is using this entity.";

    @Autowired
    private CompletedTaskRepo completedTaskRepo;

    @Autowired
    private ReportService reportService;

    public CompletedTask save(Long reportId, CompletedTask completedTask){

        Report report = reportService.findOrFail(reportId);

        completedTask.setReport(report);
        completedTaskRepo.save(completedTask);
        reportService.updateHoursAndQtyOnReport(reportId);

        return completedTaskRepo.save(completedTask);

    }

    public void delete(Long completedTaskId) {

        try {

            // Method will subtract the values that refers to the Completed Task that will be deleted.
            updateHoursAndQtyOnReport(completedTaskId);

            completedTaskRepo.deleteById(completedTaskId);
            completedTaskRepo.flush();

        } catch (EmptyResultDataAccessException e) {
            throw new CompletedTaskNotFoundException(completedTaskId);

        } catch (DataIntegrityViolationException e) {
            throw new EntityInUseException(
                    String.format(MSG_ENTITY_IN_USE, completedTaskId));
        }

    }

    // To use on the delete method
    private void updateHoursAndQtyOnReport(Long completedTaskId) {

        CompletedTask completedTask = findOrFail(completedTaskId);
        Long reportId = completedTask.getReport().getId();
        Report report = reportService.findOrFail(reportId);

        report.setTotalWorkedHoursCompletedTasks(
                report.getTotalWorkedHoursCompletedTasks() - completedTask.getHoursSpent());
        report.setTotalWorkedHours(report.getTotalWorkedHours() - completedTask.getHoursSpent());
        report.setQtyCompletedTasks(report.getQtyCompletedTasks() - 1);

    }

    public CompletedTask findOrFail(Long id){
        return completedTaskRepo.findById(id)
                .orElseThrow(() -> new CompletedTaskNotFoundException(id));
    }


}
