package com.sn.sowsysrestapi.api.controller;

import com.sn.sowsysrestapi.api.converter.NextPeriodTaskConverter;
import com.sn.sowsysrestapi.api.dto.NextPeriodTaskDTO;
import com.sn.sowsysrestapi.api.dto.input.NextPeriodTaskInputDTO;
import com.sn.sowsysrestapi.domain.entity.NextPeriodTask;
import com.sn.sowsysrestapi.domain.exception.BusinessException;
import com.sn.sowsysrestapi.domain.exception.NextPeriodTaskNotFoundException;
import com.sn.sowsysrestapi.domain.repository.NextPeriodTaskRepo;
import com.sn.sowsysrestapi.domain.service.NextPeriodTaskService;
import com.sn.sowsysrestapi.domain.service.ReportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@RestController
@RequestMapping("/api/reports/{reportId}/next-period-tasks")
public class NextPeriodTaskController {

    @Autowired
    private NextPeriodTaskRepo nextPeriodTaskRepo;

    @Autowired
    private NextPeriodTaskService nextPeriodTaskService;

    @Autowired
    private NextPeriodTaskConverter nextPeriodTaskConverter;

    @Autowired
    private ReportService reportService;

    @GetMapping()
    public List<NextPeriodTaskDTO> findByReport(@PathVariable Long reportId) {

        reportService.findOrFail(reportId);

        return nextPeriodTaskConverter.toCollectionDTO(nextPeriodTaskRepo.findAllByReportId(reportId));
    }

    @GetMapping("/{nextPeriodTaskId}")
    public NextPeriodTaskDTO findByReport(@PathVariable Long reportId, @PathVariable Long nextPeriodTaskId) {

        reportService.findOrFail(reportId);

        NextPeriodTask nextPeriodTask = nextPeriodTaskService.findOrFail(nextPeriodTaskId);

        NextPeriodTaskDTO nextPeriodTaskDTO = nextPeriodTaskConverter.toDto(nextPeriodTask);

        return nextPeriodTaskDTO;

    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public NextPeriodTaskDTO add(@PathVariable Long reportId,
                                 @RequestBody @Valid NextPeriodTaskInputDTO nextPeriodTaskInputDTO) {

        reportService.findOrFail(reportId);

        try {
            NextPeriodTask nextPeriodTask = nextPeriodTaskConverter.toEntity(nextPeriodTaskInputDTO);

            return nextPeriodTaskConverter.toDto(nextPeriodTaskService.save(reportId, nextPeriodTask));

        } catch (NextPeriodTaskNotFoundException e) {
            throw new BusinessException(e.getMessage());
        }

    }

    @PutMapping("/{nextPeriodTaskId}")
    public NextPeriodTaskDTO update(@PathVariable Long reportId, @PathVariable Long nextPeriodTaskId,
                                    @RequestBody @Valid NextPeriodTaskInputDTO nextPeriodTaskInputDTO) {

        reportService.findOrFail(reportId);

        try {
            NextPeriodTask nextPeriodTaskPresent = nextPeriodTaskService.findOrFail(nextPeriodTaskId);

            nextPeriodTaskConverter.copyToEntity(nextPeriodTaskInputDTO, nextPeriodTaskPresent);

            return nextPeriodTaskConverter.toDto(nextPeriodTaskService.save(reportId, nextPeriodTaskPresent));

        } catch (NextPeriodTaskNotFoundException e) {
            throw new BusinessException(e.getMessage());
        }
    }

    @DeleteMapping("/{nextPeriodTaskId}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void delete(@PathVariable Long reportId, @PathVariable Long nextPeriodTaskId) {

        reportService.findOrFail(reportId);

        nextPeriodTaskService.delete(nextPeriodTaskId);
    }


}
