package com.social.media.controller;

import com.social.media.dto.PostMediaDto;
import com.social.media.service.PostMediaService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * REST Controller for managing post-media relationships
 */
@RestController
@RequestMapping("/api/post-media")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "Post Media", description = "Post-Media Relationship Management API")
public class PostMediaController {
    
    private final PostMediaService postMediaService;
    
    // ==========================================
    // BASIC CRUD OPERATIONS
    // ==========================================
    
    @PostMapping
    @Operation(summary = "Create post-media relationship", 
               description = "Creates a new relationship between a post and media file")
    public ResponseEntity<PostMediaDto> createPostMedia(
            @Valid @RequestBody PostMediaDto postMediaDto) {
        log.info("Creating post-media relationship: post={}, media={}", 
                postMediaDto.getPostId(), postMediaDto.getMediaId());
        
        try {
            PostMediaDto created = postMediaService.createPostMedia(postMediaDto);
            return ResponseEntity.status(HttpStatus.CREATED).body(created);
        } catch (IllegalArgumentException e) {
            log.error("Invalid post-media relationship data", e);
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("Failed to create post-media relationship", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PostMapping("/batch")
    @Operation(summary = "Create multiple post-media relationships", 
               description = "Creates multiple relationships in batch")
    public ResponseEntity<List<PostMediaDto>> createPostMediaBatch(
            @Valid @RequestBody List<PostMediaDto> postMediaDtos) {
        log.info("Creating {} post-media relationships in batch", postMediaDtos.size());
        
        try {
            List<PostMediaDto> created = postMediaService.createPostMediaBatch(postMediaDtos);
            return ResponseEntity.status(HttpStatus.CREATED).body(created);
        } catch (Exception e) {
            log.error("Failed to create post-media relationships in batch", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @GetMapping("/{id}")
    @Operation(summary = "Get post-media relationship", 
               description = "Retrieves a specific post-media relationship by ID")
    public ResponseEntity<PostMediaDto> getPostMedia(
            @Parameter(description = "Post-media relationship ID") @PathVariable Long id) {
        log.debug("Fetching post-media relationship: {}", id);
        
        Optional<PostMediaDto> postMedia = postMediaService.getPostMediaById(id);
        return postMedia.map(ResponseEntity::ok)
                       .orElse(ResponseEntity.notFound().build());
    }
    
    @PutMapping("/{id}")
    @Operation(summary = "Update post-media relationship", 
               description = "Updates an existing post-media relationship")
    public ResponseEntity<PostMediaDto> updatePostMedia(
            @Parameter(description = "Post-media relationship ID") @PathVariable Long id,
            @Valid @RequestBody PostMediaDto postMediaDto) {
        log.info("Updating post-media relationship: {}", id);
        
        try {
            PostMediaDto updated = postMediaService.updatePostMedia(id, postMediaDto);
            return ResponseEntity.ok(updated);
        } catch (IllegalArgumentException e) {
            log.error("Invalid update data for post-media relationship: {}", id, e);
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            log.error("Failed to update post-media relationship: {}", id, e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @DeleteMapping("/{id}")
    @Operation(summary = "Delete post-media relationship", 
               description = "Deletes a post-media relationship")
    public ResponseEntity<Void> deletePostMedia(
            @Parameter(description = "Post-media relationship ID") @PathVariable Long id) {
        log.info("Deleting post-media relationship: {}", id);
        
        try {
            postMediaService.deletePostMedia(id);
            return ResponseEntity.ok().build();
        } catch (IllegalArgumentException e) {
            log.error("Post-media relationship not found: {}", id);
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            log.error("Failed to delete post-media relationship: {}", id, e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @GetMapping
    @Operation(summary = "Get all post-media relationships", 
               description = "Retrieves all post-media relationships with pagination")
    public ResponseEntity<Page<PostMediaDto>> getAllPostMedia(
            @Parameter(description = "Page number (0-based)") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "Page size") @RequestParam(defaultValue = "20") int size,
            @Parameter(description = "Sort by field") @RequestParam(defaultValue = "createdAt") String sortBy,
            @Parameter(description = "Sort direction") @RequestParam(defaultValue = "desc") String sortDir) {
        
        Sort sort = Sort.by(Sort.Direction.fromString(sortDir), sortBy);
        Pageable pageable = PageRequest.of(page, size, sort);
        
        Page<PostMediaDto> postMediaPage = postMediaService.getAllPostMedia(pageable);
        return ResponseEntity.ok(postMediaPage);
    }
    
    // ==========================================
    // POST-SPECIFIC OPERATIONS
    // ==========================================
    
    @GetMapping("/post/{postId}")
    @Operation(summary = "Get media for post", 
               description = "Retrieves all media files for a specific post")
    public ResponseEntity<List<PostMediaDto>> getMediaForPost(
            @Parameter(description = "Post ID") @PathVariable Long postId) {
        log.debug("Fetching media for post: {}", postId);
        
        List<PostMediaDto> media = postMediaService.getMediaForPost(postId);
        return ResponseEntity.ok(media);
    }
    
    @GetMapping("/post/{postId}/paginated")
    @Operation(summary = "Get media for post with pagination", 
               description = "Retrieves media files for a post with pagination")
    public ResponseEntity<Page<PostMediaDto>> getMediaForPostPaginated(
            @Parameter(description = "Post ID") @PathVariable Long postId,
            @Parameter(description = "Page number (0-based)") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "Page size") @RequestParam(defaultValue = "10") int size) {
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("displayOrder"));
        Page<PostMediaDto> mediaPage = postMediaService.getMediaForPost(postId, pageable);
        return ResponseEntity.ok(mediaPage);
    }
    
    @GetMapping("/post/{postId}/primary")
    @Operation(summary = "Get primary media for post", 
               description = "Retrieves the primary media file for a specific post")
    public ResponseEntity<PostMediaDto> getPrimaryMediaForPost(
            @Parameter(description = "Post ID") @PathVariable Long postId) {
        log.debug("Fetching primary media for post: {}", postId);
        
        Optional<PostMediaDto> primaryMedia = postMediaService.getPrimaryMediaForPost(postId);
        return primaryMedia.map(ResponseEntity::ok)
                          .orElse(ResponseEntity.notFound().build());
    }
    
    @GetMapping("/post/{postId}/secondary")
    @Operation(summary = "Get secondary media for post", 
               description = "Retrieves all secondary media files for a specific post")
    public ResponseEntity<List<PostMediaDto>> getSecondaryMediaForPost(
            @Parameter(description = "Post ID") @PathVariable Long postId) {
        log.debug("Fetching secondary media for post: {}", postId);
        
        List<PostMediaDto> secondaryMedia = postMediaService.getSecondaryMediaForPost(postId);
        return ResponseEntity.ok(secondaryMedia);
    }
    
    @PostMapping("/post/{postId}/media/{mediaId}")
    @Operation(summary = "Add media to post", 
               description = "Adds a media file to a post with specified order and primary status")
    public ResponseEntity<PostMediaDto> addMediaToPost(
            @Parameter(description = "Post ID") @PathVariable Long postId,
            @Parameter(description = "Media ID") @PathVariable Long mediaId,
            @Parameter(description = "Display order") @RequestParam(required = false) Integer displayOrder,
            @Parameter(description = "Is primary media") @RequestParam(defaultValue = "false") Boolean isPrimary) {
        
        log.info("Adding media {} to post {} with order {} and primary status {}", 
                mediaId, postId, displayOrder, isPrimary);
        
        try {
            PostMediaDto created = postMediaService.addMediaToPost(postId, mediaId, displayOrder, isPrimary);
            return ResponseEntity.status(HttpStatus.CREATED).body(created);
        } catch (IllegalArgumentException e) {
            log.error("Invalid media addition request", e);
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("Failed to add media to post", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PostMapping("/post/{postId}/media/batch")
    @Operation(summary = "Add multiple media to post", 
               description = "Adds multiple media files to a post")
    public ResponseEntity<List<PostMediaDto>> addMultipleMediaToPost(
            @Parameter(description = "Post ID") @PathVariable Long postId,
            @RequestBody List<Long> mediaIds) {
        
        log.info("Adding {} media files to post {}", mediaIds.size(), postId);
        
        try {
            List<PostMediaDto> created = postMediaService.addMultipleMediaToPost(postId, mediaIds);
            return ResponseEntity.status(HttpStatus.CREATED).body(created);
        } catch (Exception e) {
            log.error("Failed to add multiple media to post", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @DeleteMapping("/post/{postId}/media/{mediaId}")
    @Operation(summary = "Remove media from post", 
               description = "Removes a specific media file from a post")
    public ResponseEntity<Void> removeMediaFromPost(
            @Parameter(description = "Post ID") @PathVariable Long postId,
            @Parameter(description = "Media ID") @PathVariable Long mediaId) {
        
        log.info("Removing media {} from post {}", mediaId, postId);
        
        try {
            postMediaService.removeMediaFromPost(postId, mediaId);
            return ResponseEntity.ok().build();
        } catch (Exception e) {
            log.error("Failed to remove media from post", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @DeleteMapping("/post/{postId}/media")
    @Operation(summary = "Remove all media from post", 
               description = "Removes all media files from a post")
    public ResponseEntity<Void> removeAllMediaFromPost(
            @Parameter(description = "Post ID") @PathVariable Long postId) {
        
        log.info("Removing all media from post: {}", postId);
        
        try {
            postMediaService.removeAllMediaFromPost(postId);
            return ResponseEntity.ok().build();
        } catch (Exception e) {
            log.error("Failed to remove all media from post", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @GetMapping("/post/{postId}/count")
    @Operation(summary = "Count media for post", 
               description = "Returns the number of media files for a post")
    public ResponseEntity<Long> countMediaForPost(
            @Parameter(description = "Post ID") @PathVariable Long postId) {
        
        Long count = postMediaService.countMediaForPost(postId);
        return ResponseEntity.ok(count);
    }
    
    @GetMapping("/post/{postId}/has-media")
    @Operation(summary = "Check if post has media", 
               description = "Checks if a post has any media files")
    public ResponseEntity<Boolean> postHasMedia(
            @Parameter(description = "Post ID") @PathVariable Long postId) {
        
        Boolean hasMedia = postMediaService.postHasMedia(postId);
        return ResponseEntity.ok(hasMedia);
    }
    
    @GetMapping("/post/{postId}/has-primary")
    @Operation(summary = "Check if post has primary media", 
               description = "Checks if a post has a primary media file")
    public ResponseEntity<Boolean> postHasPrimaryMedia(
            @Parameter(description = "Post ID") @PathVariable Long postId) {
        
        Boolean hasPrimary = postMediaService.postHasPrimaryMedia(postId);
        return ResponseEntity.ok(hasPrimary);
    }
    
    // ==========================================
    // MEDIA-SPECIFIC OPERATIONS
    // ==========================================
    
    @GetMapping("/media/{mediaId}/posts")
    @Operation(summary = "Get posts using media", 
               description = "Retrieves all posts that use a specific media file")
    public ResponseEntity<List<PostMediaDto>> getPostsUsingMedia(
            @Parameter(description = "Media ID") @PathVariable Long mediaId) {
        
        log.debug("Fetching posts using media: {}", mediaId);
        
        List<PostMediaDto> posts = postMediaService.getPostsUsingMedia(mediaId);
        return ResponseEntity.ok(posts);
    }
    
    @GetMapping("/media/{mediaId}/primary-posts")
    @Operation(summary = "Get posts where media is primary", 
               description = "Retrieves posts where the specified media is used as primary")
    public ResponseEntity<List<PostMediaDto>> getPostsWherePrimary(
            @Parameter(description = "Media ID") @PathVariable Long mediaId) {
        
        log.debug("Fetching posts where media {} is primary", mediaId);
        
        List<PostMediaDto> posts = postMediaService.getPostsWherePrimary(mediaId);
        return ResponseEntity.ok(posts);
    }
    
    @GetMapping("/media/{mediaId}/usage-count")
    @Operation(summary = "Count posts using media", 
               description = "Returns the number of posts using a specific media file")
    public ResponseEntity<Long> countPostsUsingMedia(
            @Parameter(description = "Media ID") @PathVariable Long mediaId) {
        
        Long count = postMediaService.countPostsUsingMedia(mediaId);
        return ResponseEntity.ok(count);
    }
    
    @GetMapping("/media/{mediaId}/is-used")
    @Operation(summary = "Check if media is used", 
               description = "Checks if a media file is used in any post")
    public ResponseEntity<Boolean> mediaIsUsed(
            @Parameter(description = "Media ID") @PathVariable Long mediaId) {
        
        Boolean isUsed = postMediaService.mediaIsUsed(mediaId);
        return ResponseEntity.ok(isUsed);
    }
    
    @GetMapping("/media/{mediaId}/is-primary")
    @Operation(summary = "Check if media is used as primary", 
               description = "Checks if a media file is used as primary in any post")
    public ResponseEntity<Boolean> mediaIsUsedAsPrimary(
            @Parameter(description = "Media ID") @PathVariable Long mediaId) {
        
        Boolean isUsedAsPrimary = postMediaService.mediaIsUsedAsPrimary(mediaId);
        return ResponseEntity.ok(isUsedAsPrimary);
    }
    
    @DeleteMapping("/media/{mediaId}/remove-all")
    @Operation(summary = "Remove media from all posts", 
               description = "Removes a media file from all posts")
    public ResponseEntity<Void> removeMediaFromAllPosts(
            @Parameter(description = "Media ID") @PathVariable Long mediaId) {
        
        log.info("Removing media {} from all posts", mediaId);
        
        try {
            postMediaService.removeMediaFromAllPosts(mediaId);
            return ResponseEntity.ok().build();
        } catch (Exception e) {
            log.error("Failed to remove media from all posts", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    // ==========================================
    // PRIMARY MEDIA MANAGEMENT
    // ==========================================
    
    @PutMapping("/post/{postId}/primary/{mediaId}")
    @Operation(summary = "Set primary media", 
               description = "Sets a specific media as primary for a post")
    public ResponseEntity<PostMediaDto> setPrimaryMedia(
            @Parameter(description = "Post ID") @PathVariable Long postId,
            @Parameter(description = "Media ID") @PathVariable Long mediaId) {
        
        log.info("Setting media {} as primary for post {}", mediaId, postId);
        
        try {
            PostMediaDto updated = postMediaService.setPrimaryMedia(postId, mediaId);
            return ResponseEntity.ok(updated);
        } catch (IllegalArgumentException e) {
            log.error("Invalid primary media request", e);
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("Failed to set primary media", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @DeleteMapping("/post/{postId}/primary")
    @Operation(summary = "Remove primary status", 
               description = "Removes primary status from all media in a post")
    public ResponseEntity<Void> removePrimaryStatusFromPost(
            @Parameter(description = "Post ID") @PathVariable Long postId) {
        
        log.info("Removing primary status from all media in post: {}", postId);
        
        try {
            postMediaService.removePrimaryStatusFromPost(postId);
            return ResponseEntity.ok().build();
        } catch (Exception e) {
            log.error("Failed to remove primary status", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PostMapping("/post/{postId}/auto-assign-primary")
    @Operation(summary = "Auto-assign primary media", 
               description = "Automatically assigns primary media if none exists")
    public ResponseEntity<PostMediaDto> autoAssignPrimaryMedia(
            @Parameter(description = "Post ID") @PathVariable Long postId) {
        
        log.info("Auto-assigning primary media for post: {}", postId);
        
        try {
            Optional<PostMediaDto> assigned = postMediaService.autoAssignPrimaryMedia(postId);
            return assigned.map(ResponseEntity::ok)
                          .orElse(ResponseEntity.notFound().build());
        } catch (Exception e) {
            log.error("Failed to auto-assign primary media", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    // ==========================================
    // DISPLAY ORDER MANAGEMENT
    // ==========================================
    
    @PutMapping("/post/{postId}/reorder")
    @Operation(summary = "Reorder post media", 
               description = "Reorders media files for a post")
    public ResponseEntity<List<PostMediaDto>> reorderPostMedia(
            @Parameter(description = "Post ID") @PathVariable Long postId,
            @RequestBody List<Long> mediaIdsInOrder) {
        
        log.info("Reordering media for post {}: {}", postId, mediaIdsInOrder);
        
        try {
            List<PostMediaDto> reordered = postMediaService.reorderPostMedia(postId, mediaIdsInOrder);
            return ResponseEntity.ok(reordered);
        } catch (Exception e) {
            log.error("Failed to reorder post media", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PutMapping("/post/{postId}/media/{mediaId}/move-up")
    @Operation(summary = "Move media up", 
               description = "Moves a media file up in the display order")
    public ResponseEntity<PostMediaDto> moveMediaUp(
            @Parameter(description = "Post ID") @PathVariable Long postId,
            @Parameter(description = "Media ID") @PathVariable Long mediaId) {
        
        log.info("Moving media {} up in post {}", mediaId, postId);
        
        try {
            PostMediaDto moved = postMediaService.moveMediaUp(postId, mediaId);
            return ResponseEntity.ok(moved);
        } catch (Exception e) {
            log.error("Failed to move media up", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PutMapping("/post/{postId}/media/{mediaId}/move-down")
    @Operation(summary = "Move media down", 
               description = "Moves a media file down in the display order")
    public ResponseEntity<PostMediaDto> moveMediaDown(
            @Parameter(description = "Post ID") @PathVariable Long postId,
            @Parameter(description = "Media ID") @PathVariable Long mediaId) {
        
        log.info("Moving media {} down in post {}", mediaId, postId);
        
        try {
            PostMediaDto moved = postMediaService.moveMediaDown(postId, mediaId);
            return ResponseEntity.ok(moved);
        } catch (Exception e) {
            log.error("Failed to move media down", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PutMapping("/post/{postId}/media/{mediaId}/move-to/{position}")
    @Operation(summary = "Move media to position", 
               description = "Moves a media file to a specific position")
    public ResponseEntity<PostMediaDto> moveMediaToPosition(
            @Parameter(description = "Post ID") @PathVariable Long postId,
            @Parameter(description = "Media ID") @PathVariable Long mediaId,
            @Parameter(description = "New position") @PathVariable Integer position) {
        
        log.info("Moving media {} to position {} in post {}", mediaId, position, postId);
        
        try {
            PostMediaDto moved = postMediaService.moveMediaToPosition(postId, mediaId, position);
            return ResponseEntity.ok(moved);
        } catch (Exception e) {
            log.error("Failed to move media to position", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PutMapping("/post/{postId}/media/{mediaId}/move-to-first")
    @Operation(summary = "Move media to first", 
               description = "Moves a media file to the first position")
    public ResponseEntity<PostMediaDto> moveMediaToFirst(
            @Parameter(description = "Post ID") @PathVariable Long postId,
            @Parameter(description = "Media ID") @PathVariable Long mediaId) {
        
        log.info("Moving media {} to first position in post {}", mediaId, postId);
        
        try {
            PostMediaDto moved = postMediaService.moveMediaToFirst(postId, mediaId);
            return ResponseEntity.ok(moved);
        } catch (Exception e) {
            log.error("Failed to move media to first", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PutMapping("/post/{postId}/media/{mediaId}/move-to-last")
    @Operation(summary = "Move media to last", 
               description = "Moves a media file to the last position")
    public ResponseEntity<PostMediaDto> moveMediaToLast(
            @Parameter(description = "Post ID") @PathVariable Long postId,
            @Parameter(description = "Media ID") @PathVariable Long mediaId) {
        
        log.info("Moving media {} to last position in post {}", mediaId, postId);
        
        try {
            PostMediaDto moved = postMediaService.moveMediaToLast(postId, mediaId);
            return ResponseEntity.ok(moved);
        } catch (Exception e) {
            log.error("Failed to move media to last", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PostMapping("/post/{postId}/normalize-orders")
    @Operation(summary = "Normalize display orders", 
               description = "Normalizes display orders for a post (1, 2, 3, ...)")
    public ResponseEntity<List<PostMediaDto>> normalizeDisplayOrders(
            @Parameter(description = "Post ID") @PathVariable Long postId) {
        
        log.info("Normalizing display orders for post: {}", postId);
        
        try {
            List<PostMediaDto> normalized = postMediaService.normalizeDisplayOrders(postId);
            return ResponseEntity.ok(normalized);
        } catch (Exception e) {
            log.error("Failed to normalize display orders", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @GetMapping("/post/{postId}/next-order")
    @Operation(summary = "Get next display order", 
               description = "Gets the next available display order for a post")
    public ResponseEntity<Integer> getNextDisplayOrder(
            @Parameter(description = "Post ID") @PathVariable Long postId) {
        
        Integer nextOrder = postMediaService.getNextDisplayOrder(postId);
        return ResponseEntity.ok(nextOrder);
    }
    
    // ==========================================
    // STATISTICS AND ANALYTICS
    // ==========================================
    
    @GetMapping("/statistics")
    @Operation(summary = "Get media usage statistics", 
               description = "Retrieves comprehensive media usage statistics")
    public ResponseEntity<Map<String, Object>> getMediaUsageStatistics() {
        log.debug("Fetching media usage statistics");
        
        Map<String, Object> statistics = postMediaService.getMediaUsageStatistics();
        return ResponseEntity.ok(statistics);
    }
    
    @GetMapping("/posts/most-media")
    @Operation(summary = "Get posts with most media", 
               description = "Retrieves posts with the highest number of media files")
    public ResponseEntity<List<Map<String, Object>>> getPostsWithMostMedia(
            @Parameter(description = "Limit results") @RequestParam(defaultValue = "10") int limit) {
        
        List<Map<String, Object>> posts = postMediaService.getPostsWithMostMedia(limit);
        return ResponseEntity.ok(posts);
    }
    
    @GetMapping("/media/most-used")
    @Operation(summary = "Get most used media", 
               description = "Retrieves media files used in the most posts")
    public ResponseEntity<List<Map<String, Object>>> getMostUsedMedia(
            @Parameter(description = "Limit results") @RequestParam(defaultValue = "10") int limit) {
        
        List<Map<String, Object>> media = postMediaService.getMostUsedMedia(limit);
        return ResponseEntity.ok(media);
    }
    
    @GetMapping("/distribution/display-order")
    @Operation(summary = "Get media distribution by display order", 
               description = "Shows how media is distributed across display orders")
    public ResponseEntity<Map<Integer, Long>> getMediaDistributionByDisplayOrder() {
        
        Map<Integer, Long> distribution = postMediaService.getMediaDistributionByDisplayOrder();
        return ResponseEntity.ok(distribution);
    }
    
    @GetMapping("/usage/primary-status")
    @Operation(summary = "Get media usage by primary status", 
               description = "Shows primary vs secondary usage for each media")
    public ResponseEntity<Map<Long, Map<String, Long>>> getMediaUsageByPrimaryStatus() {
        
        Map<Long, Map<String, Long>> usage = postMediaService.getMediaUsageByPrimaryStatus();
        return ResponseEntity.ok(usage);
    }
    
    // ==========================================
    // SEARCH AND FILTERING
    // ==========================================
    
    @GetMapping("/search")
    @Operation(summary = "Search post-media relationships", 
               description = "Searches relationships by various criteria")
    public ResponseEntity<Page<PostMediaDto>> searchPostMedia(
            @Parameter(description = "Post ID filter") @RequestParam(required = false) Long postId,
            @Parameter(description = "Media ID filter") @RequestParam(required = false) Long mediaId,
            @Parameter(description = "Primary status filter") @RequestParam(required = false) Boolean isPrimary,
            @Parameter(description = "Minimum display order") @RequestParam(required = false) Integer minDisplayOrder,
            @Parameter(description = "Maximum display order") @RequestParam(required = false) Integer maxDisplayOrder,
            @Parameter(description = "Page number") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "Page size") @RequestParam(defaultValue = "20") int size) {
        
        Pageable pageable = PageRequest.of(page, size);
        
        Page<PostMediaDto> results = postMediaService.searchPostMedia(
            postId, mediaId, isPrimary, minDisplayOrder, maxDisplayOrder, pageable);
        
        return ResponseEntity.ok(results);
    }
    
    @GetMapping("/posts/multiple-media")
    @Operation(summary = "Get posts with multiple media", 
               description = "Retrieves posts that have multiple media files")
    public ResponseEntity<List<Long>> getPostsWithMultipleMedia() {
        
        List<Long> postIds = postMediaService.getPostsWithMultipleMedia();
        return ResponseEntity.ok(postIds);
    }
    
    @GetMapping("/posts/without-primary")
    @Operation(summary = "Get posts without primary media", 
               description = "Retrieves posts that don't have a primary media file")
    public ResponseEntity<List<Long>> getPostsWithoutPrimaryMedia() {
        
        List<Long> postIds = postMediaService.getPostsWithoutPrimaryMedia();
        return ResponseEntity.ok(postIds);
    }
    
    @GetMapping("/media/multiple-posts")
    @Operation(summary = "Get media used in multiple posts", 
               description = "Retrieves media files used in multiple posts")
    public ResponseEntity<List<Long>> getMediaUsedInMultiplePosts() {
        
        List<Long> mediaIds = postMediaService.getMediaUsedInMultiplePosts();
        return ResponseEntity.ok(mediaIds);
    }
    
    // ==========================================
    // MAINTENANCE AND HEALTH
    // ==========================================
    
    @GetMapping("/health")
    @Operation(summary = "Get health check information", 
               description = "Retrieves system health information")
    public ResponseEntity<Map<String, Object>> getHealthCheckInfo() {
        
        Map<String, Object> health = postMediaService.getHealthCheckInfo();
        return ResponseEntity.ok(health);
    }
    
    @PostMapping("/maintenance/fix-display-orders")
    @Operation(summary = "Fix display order gaps", 
               description = "Fixes gaps in display orders across all posts")
    public ResponseEntity<Map<String, Object>> fixDisplayOrderGaps() {
        log.info("Fixing display order gaps");
        
        try {
            int fixed = postMediaService.fixDisplayOrderGaps();
            Map<String, Object> result = Map.of("fixedPosts", fixed);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("Failed to fix display order gaps", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PostMapping("/maintenance/cleanup-invalid")
    @Operation(summary = "Clean up invalid relationships", 
               description = "Removes invalid post-media relationships")
    public ResponseEntity<Map<String, Object>> cleanupInvalidRelationships() {
        log.info("Cleaning up invalid relationships");
        
        try {
            int cleaned = postMediaService.cleanupInvalidRelationships();
            Map<String, Object> result = Map.of("cleanedRelationships", cleaned);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("Failed to cleanup invalid relationships", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @GetMapping("/validate/integrity")
    @Operation(summary = "Validate relationships integrity", 
               description = "Validates the integrity of all relationships")
    public ResponseEntity<Map<String, Object>> validateRelationshipsIntegrity() {
        
        Map<String, Object> validation = postMediaService.validateAllRelationshipsIntegrity();
        return ResponseEntity.ok(validation);
    }
    
    // ==========================================
    // BULK OPERATIONS
    // ==========================================
    
    @PostMapping("/copy/{sourcePostId}/to/{targetPostId}")
    @Operation(summary = "Copy media from post", 
               description = "Copies media from one post to another")
    public ResponseEntity<List<PostMediaDto>> copyMediaFromPost(
            @Parameter(description = "Source post ID") @PathVariable Long sourcePostId,
            @Parameter(description = "Target post ID") @PathVariable Long targetPostId) {
        
        log.info("Copying media from post {} to post {}", sourcePostId, targetPostId);
        
        try {
            List<PostMediaDto> copied = postMediaService.copyMediaFromPost(sourcePostId, targetPostId);
            return ResponseEntity.ok(copied);
        } catch (Exception e) {
            log.error("Failed to copy media from post", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PostMapping("/move/{sourcePostId}/to/{targetPostId}")
    @Operation(summary = "Move media from post", 
               description = "Moves media from one post to another")
    public ResponseEntity<List<PostMediaDto>> moveMediaFromPost(
            @Parameter(description = "Source post ID") @PathVariable Long sourcePostId,
            @Parameter(description = "Target post ID") @PathVariable Long targetPostId) {
        
        log.info("Moving media from post {} to post {}", sourcePostId, targetPostId);
        
        try {
            List<PostMediaDto> moved = postMediaService.moveMediaFromPost(sourcePostId, targetPostId);
            return ResponseEntity.ok(moved);
        } catch (Exception e) {
            log.error("Failed to move media from post", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PostMapping("/duplicate/{sourcePostId}/to/{targetPostId}")
    @Operation(summary = "Duplicate post media structure", 
               description = "Duplicates the complete media structure from one post to another")
    public ResponseEntity<List<PostMediaDto>> duplicatePostMediaStructure(
            @Parameter(description = "Source post ID") @PathVariable Long sourcePostId,
            @Parameter(description = "Target post ID") @PathVariable Long targetPostId) {
        
        log.info("Duplicating media structure from post {} to post {}", sourcePostId, targetPostId);
        
        try {
            List<PostMediaDto> duplicated = postMediaService.duplicatePostMediaStructure(sourcePostId, targetPostId);
            return ResponseEntity.ok(duplicated);
        } catch (Exception e) {
            log.error("Failed to duplicate post media structure", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}
