package ru.soune.nocopy.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
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.file.ActionResponse;
import ru.soune.nocopy.dto.user.moderation.UserVerificationRequest;
import ru.soune.nocopy.dto.user.moderation.UserVerificationResponse;
import ru.soune.nocopy.entity.notification.NotificationType;
import ru.soune.nocopy.entity.user.ModerationStatus;
import ru.soune.nocopy.entity.user.moderation.UserVerification;
import ru.soune.nocopy.service.notification.NotificationService;
import ru.soune.nocopy.service.user.moderation.UserVerificationService;

import java.util.Arrays;
import java.util.List;

@Component
@RequiredArgsConstructor
@Slf4j
public class UserVerificationHandler implements RequestHandler {

    private final UserVerificationService userVerificationService;

    private final ObjectMapper objectMapper;

    private final NotificationService notificationService;

    @Override
    public BaseResponse handle(BaseRequest request) throws Exception {
        UserVerificationRequest userVerificationRequest = objectMapper.convertValue(request.getMessageBody(),
                UserVerificationRequest.class);
        String action = userVerificationRequest.getAction();

        switch (action) {
            case "get_all_verifications":
                return handleVerifications(request, userVerificationRequest);
            case "verified":
                return handleVerified(request, userVerificationRequest);
            default:
                ActionResponse response = ActionResponse.builder()
                        .action(action)
                        .availableActions(Arrays.asList(
                                "get_all_verifications", "verified"))
                        .build();
                return new BaseResponse(request.getMsgId(),
                        MessageCode.INVALID_ACTION.getCode(),
                        "Invalid action: " + action,
                        response);
        }
    }

    private BaseResponse handleVerifications(BaseRequest request, UserVerificationRequest userVerificationRequest) throws Exception {
        List<UserVerification> verifications = userVerificationService.verifications();

        if (verifications.isEmpty()) {
            return new BaseResponse(request.getMsgId(), MessageCode.USER_VERIFICATIONS_NOT_FOUND.getCode(),
                    MessageCode.USER_VERIFICATIONS_NOT_FOUND.getDescription(), null);
        }

        List<UserVerificationResponse> verificationResponses = verifications.stream().map(this::convertDto).toList();

        return BaseResponse.builder()
                .msgId(request.getMsgId())
                .messageBody(verificationResponses)
                .build();
    }

    private BaseResponse handleVerified(BaseRequest request, UserVerificationRequest userVerificationRequest) throws Exception {
        UserVerification userVerification = userVerificationService.verifyUser(userVerificationRequest.getUserId(), userVerificationRequest.getMessage(),
                userVerificationRequest.getAdminId(), userVerificationRequest.getVerified());

        if (userVerification == null) {
            return new BaseResponse(request.getMsgId(),
                    MessageCode.ADMIN_USER_NOT_FOUND.getCode(),
                    MessageCode.ADMIN_USER_NOT_FOUND.getDescription(),
                    null);
        }

        NotificationType notificationType = userVerification.getModerationStatus() == ModerationStatus.VERIFIED?
                NotificationType.USER_VERIFIED: NotificationType.USER_NOT_VERIFIED;

        notificationService.addNotification(notificationType, userVerification.getUserId());

        return BaseResponse.builder()
                .msgId(request.getMsgId())
                .messageBody(UserVerificationResponse.builder()
                        .userVerificationId(userVerification.getId())
                        .moderationStatus(userVerification.getModerationStatus().toString())
                        .userId(userVerification.getUserId()))
                .build();
    }


    private UserVerificationResponse convertDto(UserVerification userVerification) {
        return UserVerificationResponse.builder()
                .userVerificationId(userVerification.getId())
                .userId(userVerification.getUserId())
                .moderationStatus(userVerification.getModerationStatus().name())
                .updateTime(userVerification.getUpdatedAt())
                .build();

    }
}
