package com.sn.sowsysrestapi.domain.service;

import com.sn.sowsysrestapi.domain.entity.CurrentTask;
import com.sn.sowsysrestapi.domain.entity.Report;
import com.sn.sowsysrestapi.domain.exception.CurrentTaskNotFoundException;
import com.sn.sowsysrestapi.domain.exception.EntityInUseException;
import com.sn.sowsysrestapi.domain.repository.CurrentTaskRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class CurrentTaskService {

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

    @Autowired
    private CurrentTaskRepo currentTaskRepo;

    @Autowired
    private ReportService reportService;

    @Transactional
    public CurrentTask save(Long reportId, CurrentTask currentTask) {

        Report report = reportService.findOrFail(reportId);

        currentTask.setReport(report);
        currentTaskRepo.save(currentTask);
        reportService.updateHoursAndQtyOnReport(reportId);

        return currentTaskRepo.save(currentTask);

    }

    public void delete(Long currentTaskId) {

        try {

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

            currentTaskRepo.deleteById(currentTaskId);
            currentTaskRepo.flush();

        } catch (EmptyResultDataAccessException e) {
            throw new CurrentTaskNotFoundException(currentTaskId);

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

    }

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

        CurrentTask currentTask = findOrFail(currentTaskId);
        Long reportId = currentTask.getReport().getId();
        Report report = reportService.findOrFail(reportId);

        report.setTotalWorkedHoursCurrentTasks(
                report.getTotalWorkedHoursCurrentTasks() - currentTask.getHoursSpent());
        report.setTotalWorkedHours(report.getTotalWorkedHours() - currentTask.getHoursSpent());
        report.setQtyCurrentTasks(report.getQtyCurrentTasks() - 1);

    }

    public CurrentTask findOrFail(Long id){
        return currentTaskRepo.findById(id)
                .orElseThrow(() -> new CurrentTaskNotFoundException(id));
    }


}

