package com.sapolar.document; import com.sapolar.auth.SecurityUser; import com.sapolar.common.dto.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; @RestController @RequestMapping("/api/documents") @RequiredArgsConstructor public class DocumentController { private final DocumentService documentService; @PostMapping("/upload") public ResponseEntity> upload( @RequestParam("file") MultipartFile file, @RequestParam("entityType") String entityType, @RequestParam("entityId") Long entityId, @RequestParam("documentTypeId") Integer documentTypeId, @RequestParam(required = false) String description, @AuthenticationPrincipal SecurityUser user) { Document doc = documentService.uploadFile(file, entityType, entityId, documentTypeId, description, user.userId()); return ResponseEntity.ok(ApiResponse.success("Archivo subido", doc)); } @GetMapping("/entity/{entityType}/{entityId}") public ResponseEntity>> getEntityDocuments( @PathVariable String entityType, @PathVariable Long entityId) { return ResponseEntity.ok(ApiResponse.success( documentService.getDocumentsForEntity(entityType, entityId))); } @GetMapping("/search") public ResponseEntity>> searchDocuments( @RequestParam(required = false) String entityType, @RequestParam(required = false) Long entityId, @RequestParam(required = false) Integer documentTypeId, @RequestParam(required = false) String originalName) { // Convert empty strings to null for proper query handling String entityTypeParam = (entityType != null && entityType.isBlank()) ? null : entityType; String originalNameParam = (originalName != null && originalName.isBlank()) ? null : originalName; return ResponseEntity.ok(ApiResponse.success( documentService.searchDocuments(entityTypeParam, entityId, documentTypeId, originalNameParam))); } @GetMapping("/{id}/download") public ResponseEntity download(@PathVariable Long id) { DocumentService.DocumentDownloadResult result = documentService.downloadFile(id); String mimeType = result.mimeType(); if (mimeType == null) { mimeType = "application/octet-stream"; } MediaType mediaType = MediaType.parseMediaType(mimeType); return ResponseEntity.ok() .contentType(mediaType) .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + result.filename() + "\"") .body(result.resource()); } @DeleteMapping("/{id}") public ResponseEntity> delete(@PathVariable Long id) { documentService.deleteDocument(id); return ResponseEntity.ok(ApiResponse.success("Documento eliminado", null)); } // Associations management @GetMapping("/{id}/entities") public ResponseEntity>> getDocumentEntities( @PathVariable Long id) { return ResponseEntity.ok(ApiResponse.success( documentService.getDocumentEntities(id))); } @PostMapping("/{id}/entities") public ResponseEntity> addEntity( @PathVariable Long id, @RequestParam String entityType, @RequestParam Long entityId) { Document doc = documentService.addEntityAssociation(id, entityType, entityId); return ResponseEntity.ok(ApiResponse.success("Documento asociado", doc)); } @DeleteMapping("/{id}/entities/{entityType}/{entityId}") public ResponseEntity> removeEntity( @PathVariable Long id, @PathVariable String entityType, @PathVariable Long entityId) { documentService.removeEntityAssociation(id, entityType, entityId); return ResponseEntity.ok(ApiResponse.success("Asociación eliminada", null)); } @GetMapping("/types") public ResponseEntity>> getDocumentTypes() { return ResponseEntity.ok(ApiResponse.success(documentService.getDocumentTypes())); } @GetMapping("/types/entity/{entityType}") public ResponseEntity>> getDocumentTypesForEntity( @PathVariable String entityType) { return ResponseEntity.ok(ApiResponse.success( documentService.getDocumentTypesForEntity(entityType))); } }