package ru.soune.nocopy.handler; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.stereotype.Component; import ru.soune.nocopy.dto.BaseRequest; import ru.soune.nocopy.dto.BaseResponse; import ru.soune.nocopy.dto.MessageCode; import ru.soune.nocopy.dto.violation.ViolationRequest; import ru.soune.nocopy.dto.violation.ViolationResponse; import ru.soune.nocopy.entity.file.FileEntity; import ru.soune.nocopy.entity.violation.Violation; import ru.soune.nocopy.repository.FileEntityRepository; import ru.soune.nocopy.service.complaint.ComplaintEntityService; import ru.soune.nocopy.service.complaint.LawCaseService; import ru.soune.nocopy.service.file.FileEntityService; import ru.soune.nocopy.service.geo.GeoCountryService; import ru.soune.nocopy.service.violation.ViolationService; import ru.soune.nocopy.service.violation.ViolationStatus; import java.io.FileNotFoundException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; @Component @Slf4j @RequiredArgsConstructor public class ViolationHandler implements RequestHandler { private final ObjectMapper objectMapper; private final ViolationService violationService; private final FileEntityRepository fileRepository; private final FileEntityService fileEntityService; private final GeoCountryService geoCountryService; private final LawCaseService lawCaseService; private final ComplaintEntityService complaintEntityService; private final HttpServletRequest httpServletRequest; private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Override public BaseResponse handle(BaseRequest request) throws Exception { ViolationRequest violationRequest = objectMapper.convertValue(request.getMessageBody(), ViolationRequest.class); validateRequest(violationRequest); Long userId = (Long) httpServletRequest.getAttribute("userId"); List targetFiles; if (violationRequest.getFileId() != null && !violationRequest.getFileId().isEmpty()) { FileEntity file = fileRepository.findById(violationRequest.getFileId()) .orElseThrow(() -> new FileNotFoundException("File not found with id: " + violationRequest.getFileId())); if (!Objects.equals(file.getUserId(), userId)) { return BaseResponse.builder() .messageCode(MessageCode.USER_NOT_HAD_PERMISSION.getCode()) .messageDesc(MessageCode.USER_NOT_HAD_PERMISSION.getDescription()) .msgId(request.getMsgId()) .messageBody(Map.of("user_id", userId)) .build(); } targetFiles = List.of(file); } else { targetFiles = fileEntityService.getAllUserFiles(userId); } LocalDateTime startDate = null; LocalDateTime endDate = null; if (violationRequest.getStartDate() != null && violationRequest.getEndDate() != null) { startDate = parseDate(violationRequest.getStartDate()); endDate = parseDate(violationRequest.getEndDate()); if (endDate != null && !violationRequest.getEndDate().contains(" ")) { endDate = endDate.withHour(23).withMinute(59).withSecond(59); } } if ("updateStatus".equals(violationRequest.getAction())) { String status = violationRequest.getStatus(); Long violationId = violationRequest.getViolationId(); if (status.equals(ViolationStatus.NOT_OWNER_FILE.name()) && lawCaseService.fetchByViolationId(violationId) != null && complaintEntityService.fetchComplaintByViolation(violationId) != null) { return BaseResponse.builder() .messageCode(MessageCode.COMPLAINT_OR_LAW_CASE_IN_WORK.getCode()) .messageCode(MessageCode.COMPLAINT_OR_LAW_CASE_IN_WORK.getCode()) .msgId(request.getMsgId()) .messageBody(Map.of("status", status)) .build(); } violationService.changeStatus(ViolationStatus.valueOf(status), violationId); return BaseResponse.builder() .msgId(request.getMsgId()) .messageCode(MessageCode.SUCCESS.getCode()) .messageDesc(MessageCode.SUCCESS.getDescription()) .messageBody(Map.of("status", status)) .build(); } if ("group".equalsIgnoreCase(violationRequest.getAction())) { Map groupedData = violationService.getGroupedViolations( targetFiles, violationRequest.getGroupBy(), violationRequest.getStatus(), startDate, endDate, violationRequest.getSortDirection()); return BaseResponse.builder() .msgId(request.getMsgId()) .messageCode(MessageCode.SUCCESS.getCode()) .messageDesc(MessageCode.SUCCESS.getDescription()) .messageBody(groupedData) .build(); } else { Page violationPage = violationService.getViolationsByFilesAndFilters( targetFiles, startDate, endDate, violationRequest.getStatus(), violationRequest.getPage(), violationRequest.getSize(), violationRequest.getSortDirection()); ViolationResponse.ViolationDto firstShowViolation = null; List content = violationPage.getContent(); List violationDtos = new ArrayList<>(); if ("getByViolationId".equals(violationRequest.getAction())) { Violation violation = violationService.getById(violationRequest.getViolationId()); if (violation != null) { firstShowViolation = ViolationResponse.ViolationDto.fromEntity(violation); violationDtos.add(firstShowViolation); } } for (Violation violation : content) { if (firstShowViolation != null && Objects.equals(firstShowViolation.getId(), violation.getId())) continue; String country; String countryCode; ViolationResponse.ViolationDto violationDto = ViolationResponse.ViolationDto.fromEntity(violation); try { country = geoCountryService.getCountryName(violation.getHost()); countryCode = geoCountryService.getCountryCode(violation.getHost()); } catch (Exception e) { country = geoCountryService.getCountryName(violation.getUrl()); countryCode = geoCountryService.getCountryCode(violation.getUrl()); } violationDto.setCountry(country); violationDto.setCountryCode(countryCode); violationDtos.add(violationDto); } ViolationResponse response = ViolationResponse.builder() .violations(violationDtos) .totalElements(violationPage.getTotalElements()) .totalPages(violationPage.getTotalPages()) .currentPage(violationPage.getNumber()) .pageSize(violationPage.getSize()) .hasNext(violationPage.hasNext()) .hasPrevious(violationPage.hasPrevious()) .build(); return BaseResponse.builder() .msgId(request.getMsgId()) .messageBody(response) .messageCode(MessageCode.SUCCESS.getCode()) .messageDesc(MessageCode.SUCCESS.getDescription()) .build(); } } private void validateRequest(ViolationRequest request) { if (request.getPage() < 0) { request.setPage(0); } if (request.getSize() <= 0 || request.getSize() > 100) { request.setSize(10); } if (!request.getSortDirection().equalsIgnoreCase("asc") && !request.getSortDirection().equalsIgnoreCase("desc")) { request.setSortDirection("desc"); } } private LocalDateTime parseDate(String dateStr) { try { return LocalDateTime.parse(dateStr, DATE_FORMATTER); } catch (DateTimeParseException e) { log.error(e.getMessage()); return null; } } }