package com.social.media.controller;

import com.social.media.domain.entity.Media.MediaFormat;
import com.social.media.domain.entity.Media.MediaValidationStatus;
import com.social.media.dto.MediaDto;
import com.social.media.service.MediaService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@RestController
@RequestMapping("/api/media")
@Tag(name = "Media", description = "API para gerenciamento de mídias e arquivos")
@CrossOrigin(origins = "*")
public class MediaController {

    private static final Logger logger = LoggerFactory.getLogger(MediaController.class);

    @Autowired
    private MediaService mediaService;

    // Basic CRUD operations

    @GetMapping
    @Operation(summary = "Listar todas as mídias", description = "Retorna uma lista paginada de todas as mídias")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "Lista de mídias retornada com sucesso",
                    content = @Content(mediaType = "application/json", schema = @Schema(implementation = Page.class))),
        @ApiResponse(responseCode = "500", description = "Erro interno do servidor")
    })
    public ResponseEntity<Page<MediaDto>> getAllMedia(
            @Parameter(description = "Número da página") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "Tamanho da página") @RequestParam(defaultValue = "20") int size,
            @Parameter(description = "Campo para ordenação") @RequestParam(defaultValue = "uploadedAt") String sortBy,
            @Parameter(description = "Direção da ordenação") @RequestParam(defaultValue = "desc") String sortDir) {
        
        logger.info("Listando todas as mídias - página: {}, tamanho: {}", page, size);
        
        Sort sort = sortDir.equalsIgnoreCase("desc") ? 
                    Sort.by(sortBy).descending() : 
                    Sort.by(sortBy).ascending();
        
        Pageable pageable = PageRequest.of(page, size, sort);
        Page<MediaDto> mediaPage = mediaService.findAll(pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    @GetMapping("/{id}")
    @Operation(summary = "Buscar mídia por ID", description = "Retorna uma mídia específica pelo seu ID")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "Mídia encontrada",
                    content = @Content(mediaType = "application/json", schema = @Schema(implementation = MediaDto.class))),
        @ApiResponse(responseCode = "404", description = "Mídia não encontrada"),
        @ApiResponse(responseCode = "500", description = "Erro interno do servidor")
    })
    public ResponseEntity<MediaDto> getMediaById(
            @Parameter(description = "ID da mídia") @PathVariable Long id) {
        
        logger.info("Buscando mídia por ID: {}", id);
        
        Optional<MediaDto> media = mediaService.findById(id);
        
        return media.map(ResponseEntity::ok)
                   .orElse(ResponseEntity.notFound().build());
    }

    @GetMapping("/code/{mediaCode}")
    @Operation(summary = "Buscar mídia por código", description = "Retorna uma mídia específica pelo seu código")
    public ResponseEntity<MediaDto> getMediaByCode(
            @Parameter(description = "Código da mídia") @PathVariable String mediaCode) {
        
        logger.info("Buscando mídia por código: {}", mediaCode);
        
        Optional<MediaDto> media = mediaService.findByMediaCode(mediaCode);
        
        return media.map(ResponseEntity::ok)
                   .orElse(ResponseEntity.notFound().build());
    }

    @PostMapping
    @Operation(summary = "Criar nova mídia", description = "Cria uma nova mídia no sistema")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "201", description = "Mídia criada com sucesso",
                    content = @Content(mediaType = "application/json", schema = @Schema(implementation = MediaDto.class))),
        @ApiResponse(responseCode = "400", description = "Dados inválidos"),
        @ApiResponse(responseCode = "500", description = "Erro interno do servidor")
    })
    public ResponseEntity<MediaDto> createMedia(
            @Parameter(description = "Dados da mídia") @Valid @RequestBody MediaDto mediaDto) {
        
        logger.info("Criando nova mídia: {}", mediaDto.getOriginalFilename());
        
        MediaDto savedMedia = mediaService.save(mediaDto);
        
        return ResponseEntity.status(HttpStatus.CREATED).body(savedMedia);
    }

    @PutMapping("/{id}")
    @Operation(summary = "Atualizar mídia", description = "Atualiza uma mídia existente")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "Mídia atualizada com sucesso",
                    content = @Content(mediaType = "application/json", schema = @Schema(implementation = MediaDto.class))),
        @ApiResponse(responseCode = "404", description = "Mídia não encontrada"),
        @ApiResponse(responseCode = "400", description = "Dados inválidos"),
        @ApiResponse(responseCode = "500", description = "Erro interno do servidor")
    })
    public ResponseEntity<MediaDto> updateMedia(
            @Parameter(description = "ID da mídia") @PathVariable Long id,
            @Parameter(description = "Dados atualizados da mídia") @Valid @RequestBody MediaDto mediaDto) {
        
        logger.info("Atualizando mídia ID: {}", id);
        
        MediaDto updatedMedia = mediaService.update(id, mediaDto);
        
        return ResponseEntity.ok(updatedMedia);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "Excluir mídia", description = "Exclui uma mídia permanentemente")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "204", description = "Mídia excluída com sucesso"),
        @ApiResponse(responseCode = "404", description = "Mídia não encontrada"),
        @ApiResponse(responseCode = "500", description = "Erro interno do servidor")
    })
    public ResponseEntity<Void> deleteMedia(
            @Parameter(description = "ID da mídia") @PathVariable Long id) {
        
        logger.info("Excluindo mídia ID: {}", id);
        
        mediaService.delete(id);
        
        return ResponseEntity.noContent().build();
    }

    @DeleteMapping("/{id}/soft")
    @Operation(summary = "Excluir mídia (soft delete)", description = "Marca uma mídia como excluída sem removê-la fisicamente")
    public ResponseEntity<Void> softDeleteMedia(
            @Parameter(description = "ID da mídia") @PathVariable Long id) {
        
        logger.info("Soft delete da mídia ID: {}", id);
        
        mediaService.softDelete(id);
        
        return ResponseEntity.noContent().build();
    }

    @PutMapping("/{id}/restore")
    @Operation(summary = "Restaurar mídia", description = "Restaura uma mídia que foi marcada como excluída")
    public ResponseEntity<Void> restoreMedia(
            @Parameter(description = "ID da mídia") @PathVariable Long id) {
        
        logger.info("Restaurando mídia ID: {}", id);
        
        mediaService.restore(id);
        
        return ResponseEntity.noContent().build();
    }

    // Company-based operations

    @GetMapping("/company/{companyId}")
    @Operation(summary = "Listar mídias por empresa", description = "Retorna todas as mídias de uma empresa específica")
    public ResponseEntity<Page<MediaDto>> getMediaByCompanyId(
            @Parameter(description = "ID da empresa") @PathVariable Long companyId,
            @Parameter(description = "Incluir apenas mídias ativas") @RequestParam(defaultValue = "true") Boolean activeOnly,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(defaultValue = "uploadedAt") String sortBy,
            @RequestParam(defaultValue = "desc") String sortDir) {
        
        logger.info("Listando mídias da empresa ID: {} - ativos apenas: {}", companyId, activeOnly);
        
        Sort sort = sortDir.equalsIgnoreCase("desc") ? 
                    Sort.by(sortBy).descending() : 
                    Sort.by(sortBy).ascending();
        
        Pageable pageable = PageRequest.of(page, size, sort);
        
        Page<MediaDto> mediaPage = activeOnly ? 
                                   mediaService.findActiveByCompanyId(companyId, pageable) :
                                   mediaService.findByCompanyId(companyId, pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    // User-based operations

    @GetMapping("/user/{uploadedBy}")
    @Operation(summary = "Listar mídias por usuário", description = "Retorna todas as mídias carregadas por um usuário específico")
    public ResponseEntity<Page<MediaDto>> getMediaByUploadedBy(
            @Parameter(description = "ID do usuário") @PathVariable Long uploadedBy,
            @Parameter(description = "Incluir apenas mídias ativas") @RequestParam(defaultValue = "true") Boolean activeOnly,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(defaultValue = "uploadedAt") String sortBy,
            @RequestParam(defaultValue = "desc") String sortDir) {
        
        logger.info("Listando mídias do usuário ID: {} - ativos apenas: {}", uploadedBy, activeOnly);
        
        Sort sort = sortDir.equalsIgnoreCase("desc") ? 
                    Sort.by(sortBy).descending() : 
                    Sort.by(sortBy).ascending();
        
        Pageable pageable = PageRequest.of(page, size, sort);
        
        Page<MediaDto> mediaPage = activeOnly ? 
                                   mediaService.findActiveByUploadedBy(uploadedBy, pageable) :
                                   mediaService.findByUploadedBy(uploadedBy, pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    // Format-based operations

    @GetMapping("/format/{format}")
    @Operation(summary = "Listar mídias por formato", description = "Retorna todas as mídias de um formato específico")
    public ResponseEntity<Page<MediaDto>> getMediaByFormat(
            @Parameter(description = "Formato da mídia") @PathVariable MediaFormat format,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        logger.info("Listando mídias do formato: {}", format);
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("uploadedAt").descending());
        Page<MediaDto> mediaPage = mediaService.findByFormat(format, pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    @GetMapping("/company/{companyId}/format/{format}")
    @Operation(summary = "Listar mídias por empresa e formato", description = "Retorna mídias de uma empresa filtradas por formato")
    public ResponseEntity<Page<MediaDto>> getMediaByCompanyIdAndFormat(
            @Parameter(description = "ID da empresa") @PathVariable Long companyId,
            @Parameter(description = "Formato da mídia") @PathVariable MediaFormat format,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        logger.info("Listando mídias da empresa ID: {} com formato: {}", companyId, format);
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("uploadedAt").descending());
        Page<MediaDto> mediaPage = mediaService.findByCompanyIdAndFormat(companyId, format, pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    // Type-specific operations

    @GetMapping("/company/{companyId}/images")
    @Operation(summary = "Listar imagens por empresa", description = "Retorna todas as imagens de uma empresa")
    public ResponseEntity<Page<MediaDto>> getImagesByCompanyId(
            @Parameter(description = "ID da empresa") @PathVariable Long companyId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        logger.info("Listando imagens da empresa ID: {}", companyId);
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("uploadedAt").descending());
        Page<MediaDto> mediaPage = mediaService.findImagesByCompanyId(companyId, pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    @GetMapping("/company/{companyId}/videos")
    @Operation(summary = "Listar vídeos por empresa", description = "Retorna todos os vídeos de uma empresa")
    public ResponseEntity<Page<MediaDto>> getVideosByCompanyId(
            @Parameter(description = "ID da empresa") @PathVariable Long companyId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        logger.info("Listando vídeos da empresa ID: {}", companyId);
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("uploadedAt").descending());
        Page<MediaDto> mediaPage = mediaService.findVideosByCompanyId(companyId, pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    @GetMapping("/company/{companyId}/audios")
    @Operation(summary = "Listar áudios por empresa", description = "Retorna todos os áudios de uma empresa")
    public ResponseEntity<Page<MediaDto>> getAudiosByCompanyId(
            @Parameter(description = "ID da empresa") @PathVariable Long companyId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        logger.info("Listando áudios da empresa ID: {}", companyId);
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("uploadedAt").descending());
        Page<MediaDto> mediaPage = mediaService.findAudiosByCompanyId(companyId, pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    @GetMapping("/company/{companyId}/documents")
    @Operation(summary = "Listar documentos por empresa", description = "Retorna todos os documentos de uma empresa")
    public ResponseEntity<Page<MediaDto>> getDocumentsByCompanyId(
            @Parameter(description = "ID da empresa") @PathVariable Long companyId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        logger.info("Listando documentos da empresa ID: {}", companyId);
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("uploadedAt").descending());
        Page<MediaDto> mediaPage = mediaService.findDocumentsByCompanyId(companyId, pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    // File upload operations

    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Operation(summary = "Upload de arquivo", description = "Faz upload de um arquivo para o sistema")
    @ApiResponses(value = {
        @ApiResponse(responseCode = "201", description = "Arquivo carregado com sucesso",
                    content = @Content(mediaType = "application/json", schema = @Schema(implementation = MediaDto.class))),
        @ApiResponse(responseCode = "400", description = "Arquivo inválido ou dados obrigatórios ausentes"),
        @ApiResponse(responseCode = "413", description = "Arquivo muito grande"),
        @ApiResponse(responseCode = "415", description = "Tipo de arquivo não suportado"),
        @ApiResponse(responseCode = "500", description = "Erro interno do servidor")
    })
    public ResponseEntity<MediaDto> uploadFile(
            @Parameter(description = "Arquivo para upload") @RequestParam("file") MultipartFile file,
            @Parameter(description = "ID da empresa") @RequestParam("companyId") Long companyId,
            @Parameter(description = "ID do usuário que está fazendo o upload") @RequestParam("uploadedBy") Long uploadedBy,
            @Parameter(description = "Descrição do arquivo") @RequestParam(value = "description", required = false) String description,
            @Parameter(description = "Texto alternativo") @RequestParam(value = "altText", required = false) String altText,
            @Parameter(description = "Se o arquivo é público") @RequestParam(value = "isPublic", defaultValue = "false") Boolean isPublic) {
        
        logger.info("Upload de arquivo: {} para empresa ID: {}", file.getOriginalFilename(), companyId);
        
        MediaDto uploadedMedia = mediaService.uploadFile(file, companyId, uploadedBy, description, altText, isPublic);
        
        return ResponseEntity.status(HttpStatus.CREATED).body(uploadedMedia);
    }

    @PostMapping(value = "/upload/multiple", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Operation(summary = "Upload múltiplo de arquivos", description = "Faz upload de múltiplos arquivos para o sistema")
    public ResponseEntity<List<MediaDto>> uploadMultipleFiles(
            @Parameter(description = "Arquivos para upload") @RequestParam("files") MultipartFile[] files,
            @Parameter(description = "ID da empresa") @RequestParam("companyId") Long companyId,
            @Parameter(description = "ID do usuário que está fazendo o upload") @RequestParam("uploadedBy") Long uploadedBy,
            @Parameter(description = "Se os arquivos são públicos") @RequestParam(value = "isPublic", defaultValue = "false") Boolean isPublic) {
        
        logger.info("Upload múltiplo de {} arquivos para empresa ID: {}", files.length, companyId);
        
        List<MediaDto> uploadedFiles = mediaService.uploadMultipleFiles(files, companyId, uploadedBy, isPublic);
        
        return ResponseEntity.status(HttpStatus.CREATED).body(uploadedFiles);
    }

    // Validation operations

    @PutMapping("/{id}/approve")
    @Operation(summary = "Aprovar mídia", description = "Aprova uma mídia para uso")
    public ResponseEntity<Void> approveMedia(
            @Parameter(description = "ID da mídia") @PathVariable Long id,
            @Parameter(description = "Notas de aprovação") @RequestParam(value = "notes", required = false) String notes) {
        
        logger.info("Aprovando mídia ID: {}", id);
        
        mediaService.approveMedia(id, notes);
        
        return ResponseEntity.ok().build();
    }

    @PutMapping("/{id}/reject")
    @Operation(summary = "Rejeitar mídia", description = "Rejeita uma mídia")
    public ResponseEntity<Void> rejectMedia(
            @Parameter(description = "ID da mídia") @PathVariable Long id,
            @Parameter(description = "Notas de rejeição") @RequestParam(value = "notes", required = false) String notes) {
        
        logger.info("Rejeitando mídia ID: {}", id);
        
        mediaService.rejectMedia(id, notes);
        
        return ResponseEntity.ok().build();
    }

    @PutMapping("/{id}/flag")
    @Operation(summary = "Sinalizar mídia", description = "Sinaliza uma mídia para revisão")
    public ResponseEntity<Void> flagMedia(
            @Parameter(description = "ID da mídia") @PathVariable Long id,
            @Parameter(description = "Motivo da sinalização") @RequestParam(value = "notes", required = false) String notes) {
        
        logger.info("Sinalizando mídia ID: {}", id);
        
        mediaService.flagMedia(id, notes);
        
        return ResponseEntity.ok().build();
    }

    @PutMapping("/{id}/request-review")
    @Operation(summary = "Solicitar revisão", description = "Solicita revisão para uma mídia")
    public ResponseEntity<Void> requestReview(
            @Parameter(description = "ID da mídia") @PathVariable Long id) {
        
        logger.info("Solicitando revisão para mídia ID: {}", id);
        
        mediaService.requestReview(id);
        
        return ResponseEntity.ok().build();
    }

    @GetMapping("/company/{companyId}/pending-validation")
    @Operation(summary = "Listar mídias pendentes de validação", description = "Retorna mídias que aguardam validação")
    public ResponseEntity<Page<MediaDto>> getPendingValidation(
            @Parameter(description = "ID da empresa") @PathVariable Long companyId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        logger.info("Listando mídias pendentes de validação da empresa ID: {}", companyId);
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("uploadedAt").ascending());
        Page<MediaDto> mediaPage = mediaService.findPendingValidation(companyId, pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    // Search operations

    @GetMapping("/company/{companyId}/search")
    @Operation(summary = "Pesquisar mídias", description = "Pesquisa mídias por termos específicos")
    public ResponseEntity<Page<MediaDto>> searchMedia(
            @Parameter(description = "ID da empresa") @PathVariable Long companyId,
            @Parameter(description = "Termo de pesquisa") @RequestParam("q") String searchTerm,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        logger.info("Pesquisando mídias da empresa ID: {} com termo: {}", companyId, searchTerm);
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("uploadedAt").descending());
        Page<MediaDto> mediaPage = mediaService.searchByCompanyId(companyId, searchTerm, pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    @GetMapping("/company/{companyId}/filter")
    @Operation(summary = "Filtrar mídias", description = "Filtra mídias por múltiplos critérios")
    public ResponseEntity<Page<MediaDto>> filterMedia(
            @Parameter(description = "ID da empresa") @PathVariable Long companyId,
            @Parameter(description = "Formato da mídia") @RequestParam(required = false) MediaFormat format,
            @Parameter(description = "Status de validação") @RequestParam(required = false) MediaValidationStatus validationStatus,
            @Parameter(description = "Se é público") @RequestParam(required = false) Boolean isPublic,
            @Parameter(description = "ID do usuário que fez upload") @RequestParam(required = false) Long uploadedBy,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(defaultValue = "uploadedAt") String sortBy,
            @RequestParam(defaultValue = "desc") String sortDir) {
        
        logger.info("Filtrando mídias da empresa ID: {} com filtros: format={}, status={}, public={}, user={}", 
                   companyId, format, validationStatus, isPublic, uploadedBy);
        
        Sort sort = sortDir.equalsIgnoreCase("desc") ? 
                    Sort.by(sortBy).descending() : 
                    Sort.by(sortBy).ascending();
        
        Pageable pageable = PageRequest.of(page, size, sort);
        Page<MediaDto> mediaPage = mediaService.findWithFilters(companyId, format, validationStatus, isPublic, uploadedBy, pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    // Statistical operations

    @GetMapping("/company/{companyId}/statistics")
    @Operation(summary = "Estatísticas de mídia da empresa", description = "Retorna estatísticas de uso de mídia de uma empresa")
    public ResponseEntity<Map<String, Object>> getCompanyMediaStatistics(
            @Parameter(description = "ID da empresa") @PathVariable Long companyId) {
        
        logger.info("Obtendo estatísticas de mídia da empresa ID: {}", companyId);
        
        Map<String, Object> statistics = new HashMap<>();
        statistics.put("totalCount", mediaService.countActiveByCompanyId(companyId));
        statistics.put("totalSize", mediaService.getTotalFileSizeByCompanyId(companyId));
        statistics.put("averageSize", mediaService.getAverageFileSizeByCompanyId(companyId));
        statistics.put("formatStatistics", mediaService.getFormatStatisticsByCompanyId(companyId));
        statistics.put("topUploaders", mediaService.getTopUploadersByCompanyId(companyId));
        
        // Individual format counts
        for (MediaFormat format : MediaFormat.values()) {
            String key = format.name().toLowerCase() + "_count";
            statistics.put(key, mediaService.countByCompanyIdAndFormat(companyId, format));
        }
        
        // Validation status counts
        for (MediaValidationStatus status : MediaValidationStatus.values()) {
            String key = status.name().toLowerCase() + "_count";
            statistics.put(key, mediaService.countByCompanyIdAndValidationStatus(companyId, status));
        }
        
        return ResponseEntity.ok(statistics);
    }

    @GetMapping("/statistics/global")
    @Operation(summary = "Estatísticas globais de mídia", description = "Retorna estatísticas globais do sistema")
    public ResponseEntity<Map<String, Object>> getGlobalMediaStatistics() {
        logger.info("Obtendo estatísticas globais de mídia");
        
        Map<String, Object> statistics = mediaService.getGlobalMediaStatistics();
        
        return ResponseEntity.ok(statistics);
    }

    // Recent uploads

    @GetMapping("/company/{companyId}/recent")
    @Operation(summary = "Uploads recentes por empresa", description = "Retorna uploads recentes de uma empresa")
    public ResponseEntity<Page<MediaDto>> getRecentUploads(
            @Parameter(description = "ID da empresa") @PathVariable Long companyId,
            @Parameter(description = "Número de horas para considerar como recente") @RequestParam(defaultValue = "24") int hours,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        logger.info("Obtendo uploads recentes da empresa ID: {} das últimas {} horas", companyId, hours);
        
        LocalDateTime since = LocalDateTime.now().minusHours(hours);
        Pageable pageable = PageRequest.of(page, size, Sort.by("uploadedAt").descending());
        Page<MediaDto> mediaPage = mediaService.findRecentUploads(companyId, since, pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    // Maintenance operations

    @GetMapping("/deleted")
    @Operation(summary = "Listar mídias excluídas", description = "Retorna mídias que foram marcadas como excluídas")
    public ResponseEntity<Page<MediaDto>> getDeletedMedia(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size) {
        
        logger.info("Listando mídias excluídas");
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("deletedAt").descending());
        Page<MediaDto> mediaPage = mediaService.findDeleted(pageable);
        
        return ResponseEntity.ok(mediaPage);
    }

    @DeleteMapping("/cleanup/deleted")
    @Operation(summary = "Limpar arquivos excluídos", description = "Remove permanentemente arquivos excluídos há mais de X dias")
    public ResponseEntity<Void> cleanupDeletedFiles(
            @Parameter(description = "Dias para considerar para limpeza") @RequestParam(defaultValue = "30") int days) {
        
        logger.info("Iniciando limpeza de arquivos excluídos há mais de {} dias", days);
        
        LocalDateTime cutoffDate = LocalDateTime.now().minusDays(days);
        mediaService.cleanupDeletedFiles(cutoffDate);
        
        return ResponseEntity.ok().build();
    }

    // Batch operations

    @PostMapping("/batch/approve")
    @Operation(summary = "Aprovar múltiplas mídias", description = "Aprova múltiplas mídias de uma vez")
    public ResponseEntity<Void> approveMultiple(
            @Parameter(description = "Lista de IDs das mídias") @RequestBody List<Long> ids,
            @Parameter(description = "Notas de aprovação") @RequestParam(value = "notes", required = false) String notes) {
        
        logger.info("Aprovando {} mídias em lote", ids.size());
        
        mediaService.approveMultiple(ids, notes);
        
        return ResponseEntity.ok().build();
    }

    @PostMapping("/batch/reject")
    @Operation(summary = "Rejeitar múltiplas mídias", description = "Rejeita múltiplas mídias de uma vez")
    public ResponseEntity<Void> rejectMultiple(
            @Parameter(description = "Lista de IDs das mídias") @RequestBody List<Long> ids,
            @Parameter(description = "Notas de rejeição") @RequestParam(value = "notes", required = false) String notes) {
        
        logger.info("Rejeitando {} mídias em lote", ids.size());
        
        mediaService.rejectMultiple(ids, notes);
        
        return ResponseEntity.ok().build();
    }

    @DeleteMapping("/batch")
    @Operation(summary = "Excluir múltiplas mídias", description = "Exclui múltiplas mídias permanentemente")
    public ResponseEntity<Void> deleteMultiple(
            @Parameter(description = "Lista de IDs das mídias") @RequestBody List<Long> ids) {
        
        logger.info("Excluindo {} mídias em lote", ids.size());
        
        mediaService.deleteMultiple(ids);
        
        return ResponseEntity.ok().build();
    }

    @DeleteMapping("/batch/soft")
    @Operation(summary = "Soft delete de múltiplas mídias", description = "Marca múltiplas mídias como excluídas")
    public ResponseEntity<Void> softDeleteMultiple(
            @Parameter(description = "Lista de IDs das mídias") @RequestBody List<Long> ids) {
        
        logger.info("Soft delete de {} mídias em lote", ids.size());
        
        mediaService.softDeleteMultiple(ids);
        
        return ResponseEntity.ok().build();
    }

    @PutMapping("/batch/restore")
    @Operation(summary = "Restaurar múltiplas mídias", description = "Restaura múltiplas mídias marcadas como excluídas")
    public ResponseEntity<Void> restoreMultiple(
            @Parameter(description = "Lista de IDs das mídias") @RequestBody List<Long> ids) {
        
        logger.info("Restaurando {} mídias em lote", ids.size());
        
        mediaService.restoreMultiple(ids);
        
        return ResponseEntity.ok().build();
    }

    @PutMapping("/batch/visibility")
    @Operation(summary = "Alterar visibilidade de múltiplas mídias", description = "Altera a visibilidade de múltiplas mídias")
    public ResponseEntity<Void> updateVisibilityMultiple(
            @Parameter(description = "Lista de IDs das mídias") @RequestBody List<Long> ids,
            @Parameter(description = "Se deve ser público") @RequestParam("isPublic") Boolean isPublic) {
        
        logger.info("Alterando visibilidade de {} mídias para público: {}", ids.size(), isPublic);
        
        mediaService.updateVisibilityMultiple(ids, isPublic);
        
        return ResponseEntity.ok().build();
    }

    // Utility endpoints

    @GetMapping("/formats")
    @Operation(summary = "Listar formatos suportados", description = "Retorna todos os formatos de mídia suportados")
    public ResponseEntity<MediaFormat[]> getSupportedFormats() {
        return ResponseEntity.ok(MediaFormat.values());
    }

    @GetMapping("/validation-statuses")
    @Operation(summary = "Listar status de validação", description = "Retorna todos os status de validação disponíveis")
    public ResponseEntity<MediaValidationStatus[]> getValidationStatuses() {
        return ResponseEntity.ok(MediaValidationStatus.values());
    }

    @GetMapping("/{id}/exists")
    @Operation(summary = "Verificar se mídia existe", description = "Verifica se uma mídia existe no sistema")
    public ResponseEntity<Map<String, Boolean>> checkMediaExists(
            @Parameter(description = "ID da mídia") @PathVariable Long id) {
        
        Optional<MediaDto> media = mediaService.findById(id);
        Map<String, Boolean> result = new HashMap<>();
        result.put("exists", media.isPresent());
        
        return ResponseEntity.ok(result);
    }
}
