package ru.soune.nocopy.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
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.file.ActionResponse;
import ru.soune.nocopy.dto.file.AppealResponse;
import ru.soune.nocopy.dto.file.FileEntityRequest;
import ru.soune.nocopy.dto.file.FileModerationInfo;
import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.entity.file.FileStatus;
import ru.soune.nocopy.service.file.moderation.ModerationService;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

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

    private final ObjectMapper objectMapper;

    private final ModerationService moderationService;

    @Value("${server.baseurl}")
    private String baseUrl;

    @Override
    public BaseResponse handle(BaseRequest request) throws Exception {
        try {
            FileEntityRequest fileRequest = objectMapper.convertValue(
                    request.getMessageBody(), FileEntityRequest.class);

            String action = fileRequest.getAction();
            switch (action) {
                case "files_for_moderation":
                    return handleGetFilesForModeration(request, fileRequest);
                case "all_appeals":
                    return handleGetAllAppeals(request, fileRequest);
                default:
                    ActionResponse response = ActionResponse.builder()
                            .action(action)
                            .availableActions(Arrays.asList("files_for_moderation", "all_appeals"))
                            .build();

                    return new BaseResponse(request.getMsgId(),
                            MessageCode.INVALID_ACTION.getCode(),
                            "Invalid action: " + action,
                            response);

            }
        } catch (Exception e) {
            log.error("Error in FileEntityHandler", e);
            return new BaseResponse(request.getMsgId(),
                    MessageCode.FILE_UPLOAD_ERROR.getCode(),
                    "Handler error: " + e.getMessage(),
                    null);
        }
    }

    private BaseResponse handleGetFilesForModeration(BaseRequest request, FileEntityRequest fileRequest) {
        try {
            int page = fileRequest.getPage() != null ? fileRequest.getPage() : 0;
            int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
            List<String> statuses = fileRequest.getStatuses() == null ? List.of(FileStatus.MODERATION.name(),
                    FileStatus.BLOCKED.name(), FileStatus.ACTIVE.name()): fileRequest.getStatuses();

            Page<FileEntity> files = moderationService.getFilesForModeration(page, pageSize,
                    fileRequest.getSortOrder(), fileRequest.getSortBy(), statuses, fileRequest.getIsAppeal());

            List<Map<String, Object>> filesWithInfo = files.getContent().stream()
                    .map(file -> {
                        FileModerationInfo info = moderationService.getFileModerationInfo(file.getId());

                        Map<String, Object> fileMap = new HashMap<>();
                        fileMap.put("fileId", file.getId());
                        fileMap.put("fileName", file.getOriginalFileName());
                        fileMap.put("downloadUrl", "/api/admin/download/" + file.getId());
                        fileMap.put("image", baseUrl + "/api/files/public/" + file.getId() + "/thumbnail");

                        fileMap.put("userId", file.getUserId());
                        fileMap.put("status", file.getStatus() != null ? file.getStatus().name() : null);

                        Map<String, Object> moderationInfoMap = new HashMap<>();
                        moderationInfoMap.put("hasActiveAppeal", info != null && info.getHasActiveAppeal());

                        if (info != null && info.getActiveAppeal() != null) {
                            AppealResponse appealResponse = moderationService.convertToResponse(info.getActiveAppeal());
                            moderationInfoMap.put("appealInfo", appealResponse);
                        } else {
                            moderationInfoMap.put("appealInfo", null);
                        }

                        fileMap.put("moderationInfo", moderationInfoMap);

                        return fileMap;
                    })
                    .collect(Collectors.toList());

            Map<String, Object> response = Map.of(
                    "files", filesWithInfo,
                    "totalCount", files.getTotalElements(),
                    "totalPages", files.getTotalPages(),
                    "currentPage", page,
                    "statuses",List.of(FileStatus.ACTIVE.name(), FileStatus.BLOCKED.name(), FileStatus.MODERATION.name()),
                    "pageSize", pageSize
            );

            return new BaseResponse(request.getMsgId(),
                    MessageCode.SUCCESS.getCode(),
                    MessageCode.SUCCESS.getDescription(),
                    response);

        } catch (SecurityException e) {
            return new BaseResponse(request.getMsgId(),
                    MessageCode.ACCESS_DENIED.getCode(),
                    "Admin access required",
                    null);
        } catch (Exception e) {
            log.error("Error getting files for moderation", e);
            return new BaseResponse(request.getMsgId(),
                    MessageCode.INVALID_FIELD.getCode(),
                    "Failed to get files: " + e.getMessage(),
                    null);
        }
    }


    private BaseResponse handleGetAllAppeals(BaseRequest request, FileEntityRequest fileRequest) {
        try {
            int page = fileRequest.getPage() != null ? fileRequest.getPage() : 0;
            int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;

            Page<AppealResponse> appeals = moderationService.getAllAppeals(page, pageSize,
                    fileRequest.getSortOrder(), fileRequest.getSortBy());

            Map<String, Object> response = Map.of(
                    "appeals", appeals.getContent(),
                    "totalCount", appeals.getTotalElements(),
                    "totalPages", appeals.getTotalPages(),
                    "currentPage", page,
                    "pageSize", pageSize);

            return new BaseResponse(request.getMsgId(),
                    MessageCode.SUCCESS.getCode(),
                    MessageCode.SUCCESS.getDescription(),
                    response);

        } catch (SecurityException e) {
            return new BaseResponse(request.getMsgId(),
                    MessageCode.INVALID_TOKEN.getCode(),
                    "Authentication required",
                    null);
        } catch (Exception e) {
            log.error("Error getting user appeals", e);
            return new BaseResponse(request.getMsgId(),
                    MessageCode.INVALID_FIELD.getCode(),
                    "Failed to get appeals: " + e.getMessage(),
                    null);
        }
    }
}
