package com.iqser.red.persistence.service.v1.external.api.impl.controller;

import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.CONVERT_HIGHLIGHTS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.DELETE_HIGHLIGHTS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.DELETE_IMPORTED_REDACTIONS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.GET_HIGHLIGHTS;
import static com.iqser.red.service.persistence.management.v1.processor.service.FeignExceptionHandler.processFeignException;
import static com.iqser.red.service.persistence.management.v1.processor.utils.StorageIdUtils.getStorageId;

import java.io.InputStream;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.iqser.red.service.pdftron.redaction.v1.api.model.highlights.Highlights;
import com.iqser.red.service.pdftron.redaction.v1.api.model.highlights.TextHighlightConversionOperation;
import com.iqser.red.service.pdftron.redaction.v1.api.model.highlights.TextHighlightConversionRequest;
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService;
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
import com.iqser.red.service.persistence.management.v1.processor.service.ReanalysisService;
import com.iqser.red.service.persistence.service.v1.api.external.resource.HighlightsResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.AnnotationIds;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.DeleteImportedRedactionsRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
import com.iqser.red.storage.commons.service.StorageService;
import com.knecon.fforesight.tenantcommons.TenantContext;

import feign.FeignException;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;

@RestController
@RequiredArgsConstructor
public class HighlightsController implements HighlightsResource {

    private final StorageService storageService;
    private final ObjectMapper objectMapper;
    private final AccessControlService accessControlService;
    private final FileStatusService fileStatusService;
    private final ReanalysisService reanalysisService;
    private final FileManagementStorageService fileManagementStorageService;


    @SneakyThrows
    @PreAuthorize("hasAuthority('" + GET_HIGHLIGHTS + "')")
    public Highlights getHighlights(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId) {

        fileStatusService.getStatus(fileId);

        if (storageService.objectExists(TenantContext.getTenantId(), getStorageId(dossierId, fileId, FileType.TEXT_HIGHLIGHTS))) {
            InputStream stream = fileManagementStorageService.getObject(TenantContext.getTenantId(), getStorageId(dossierId, fileId, FileType.TEXT_HIGHLIGHTS));
            Highlights highlights = objectMapper.readValue(stream, Highlights.class);
            stream.close();
            return highlights;
        }

        return new Highlights();
    }


    @PreAuthorize("hasAuthority('" + CONVERT_HIGHLIGHTS + "')")
    public void convertHighlights(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody AnnotationIds annotationIds) {

        try {
            accessControlService.verifyUserIsReviewerOrApprover(dossierId, fileId);
            accessControlService.verifyFileIsNotApproved(dossierId, fileId);

            reanalysisService.convertTextHighlights(new TextHighlightConversionRequest(dossierId, fileId, annotationIds.getIds(), TextHighlightConversionOperation.CONVERT));
        } catch (FeignException e) {
            throw processFeignException(e);
        }
    }


    @PreAuthorize("hasAuthority('" + DELETE_HIGHLIGHTS + "')")
    public void deleteHighlights(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody AnnotationIds annotationIds) {

        try {
            accessControlService.verifyUserIsReviewerOrApprover(dossierId, fileId);
            accessControlService.verifyFileIsNotApproved(dossierId, fileId);

            reanalysisService.convertTextHighlights(new TextHighlightConversionRequest(dossierId, fileId, annotationIds.getIds(), TextHighlightConversionOperation.REMOVE));
        } catch (FeignException e) {
            throw processFeignException(e);
        }

    }


    @PreAuthorize("hasAuthority('" + DELETE_IMPORTED_REDACTIONS + "')")
    public void deleteImportedRedactions(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody AnnotationIds annotationIds) {

        try {
            accessControlService.verifyUserIsReviewerOrApprover(dossierId, fileId);
            accessControlService.verifyFileIsNotApproved(dossierId, fileId);

            reanalysisService.deleteImportedRedactions(new DeleteImportedRedactionsRequest(dossierId, fileId, annotationIds.getIds()));
        } catch (FeignException e) {
            throw processFeignException(e);
        }
    }

}
