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.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.ViolationStatisticsRequest;
import ru.soune.nocopy.dto.violation.ViolationStatisticsResponse;
import ru.soune.nocopy.exception.FileEntityNotFoundException;
import ru.soune.nocopy.exception.UserNotHavePermission;
import ru.soune.nocopy.service.violation.ViolationService;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

@Slf4j
@Component
@RequiredArgsConstructor
public class ViolationStatisticsHandler implements RequestHandler {
    private final ObjectMapper objectMapper;

    private final ViolationService violationService;

    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 {
        ViolationStatisticsRequest statRequest = objectMapper.convertValue(request.getMessageBody(),
                ViolationStatisticsRequest.class);

        LocalDateTime startDate = null;
        LocalDateTime endDate = null;

        if (statRequest.getStartDate() != null && statRequest.getEndDate() != null) {
            startDate = parseDate(statRequest.getStartDate());
            endDate = parseDate(statRequest.getEndDate());

            if (endDate != null && !statRequest.getEndDate().contains(" ")) {
                endDate = endDate.withHour(23).withMinute(59).withSecond(59);
            }
        }

        Long userId = (Long) httpServletRequest.getAttribute("userId");
        ViolationStatisticsResponse statistics;

        try {
            statistics = violationService.getViolationStatistics(
                    userId,
                    statRequest.getFileId(),
                    startDate,
                    endDate);
        } catch (UserNotHavePermission e) {
            return BaseResponse.builder()
                    .msgId(request.getMsgId())
                    .messageBody("userId: " + userId)
                    .messageCode(MessageCode.USER_NOT_HAD_PERMISSION.getCode())
                    .messageDesc(MessageCode.USER_NOT_HAD_PERMISSION.getDescription())
                    .build();
        } catch (FileEntityNotFoundException e) {
            return BaseResponse.builder()
                    .msgId(request.getMsgId())
                    .messageBody("fileId: " + statRequest.getFileId())
                    .messageDesc(MessageCode.FILE_NOT_FOUND.getDescription())
                    .messageCode(MessageCode.FILE_NOT_FOUND.getCode())
                    .build();
        }


        return BaseResponse.builder()
                .msgId(request.getMsgId())
                .messageBody(statistics)
                .messageCode(MessageCode.SUCCESS.getCode())
                .messageDesc(MessageCode.SUCCESS.getDescription())
                .build();
    }

    private LocalDateTime parseDate(String dateStr) {
        try {
            return LocalDateTime.parse(dateStr, DATE_FORMATTER);
        } catch (DateTimeParseException e) {
            try {
                return LocalDateTime.parse(dateStr + " 00:00:00", DATE_FORMATTER);
            } catch (DateTimeParseException ex) {
                log.error("Error parsing date: {}", dateStr, ex);
                return null;
            }
        }
    }
}
