package de.oaa.xxx.social;

import de.oaa.xxx.social.dto.ProfileImageDto;
import de.oaa.xxx.social.entity.ProfileImageEntity;
import de.oaa.xxx.social.repository.ProfileImageLikeRepository;
import de.oaa.xxx.social.repository.ProfileImageRepository;
import de.oaa.xxx.user.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/social/profile-images")
public class ProfileImageController {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProfileImageController.class);
    private static final int MAX_IMAGES_PER_USER = 20;

    private final ProfileImageRepository profileImageRepository;
    private final ProfileImageLikeRepository profileImageLikeRepository;
    private final UserService userService;
    private final LikeService likeService;

    public ProfileImageController(ProfileImageRepository profileImageRepository,
                                  ProfileImageLikeRepository profileImageLikeRepository,
                                  UserService userService,
                                  LikeService likeService) {
        this.profileImageRepository = profileImageRepository;
        this.profileImageLikeRepository = profileImageLikeRepository;
        this.userService = userService;
        this.likeService = likeService;
    }

    record UploadRequest(String imageData) {}

    @PostMapping
    public ResponseEntity<ProfileImageDto> uploadImage(@RequestBody UploadRequest request, Principal principal) {
        UUID myId = userService.requireUser(principal).getUserId();

        if (request.imageData() == null || request.imageData().isBlank()) {
            return ResponseEntity.badRequest().build();
        }
        if (profileImageRepository.countByUserId(myId) >= MAX_IMAGES_PER_USER) {
            return ResponseEntity.status(422).build();
        }

        ProfileImageEntity entity = new ProfileImageEntity();
        entity.setImageId(UUID.randomUUID());
        entity.setUserId(myId);
        entity.setImageData(request.imageData());
        entity.setUploadedAt(LocalDateTime.now());
        profileImageRepository.save(entity);
        LOGGER.debug("User {} hat Profilbild {} hochgeladen", myId, entity.getImageId());

        return ResponseEntity.status(201).body(toDto(entity, myId));
    }

    @GetMapping
    public ResponseEntity<List<ProfileImageDto>> getImages(@RequestParam UUID userId, Principal principal) {
        UUID myId = userService.requireUser(principal).getUserId();

        List<ProfileImageEntity> images = profileImageRepository.findByUserIdOrderByUploadedAtDesc(userId);
        List<ProfileImageDto> dtos = images.stream().map(img -> toDto(img, myId)).toList();
        return ResponseEntity.ok(dtos);
    }

    @DeleteMapping("/{imageId}")
    public ResponseEntity<Void> deleteImage(@PathVariable UUID imageId, Principal principal) {
        UUID myId = userService.requireUser(principal).getUserId();

        var imgOpt = profileImageRepository.findById(imageId);
        if (imgOpt.isEmpty()) return ResponseEntity.notFound().build();
        if (!imgOpt.get().getUserId().equals(myId)) return ResponseEntity.status(403).build();

        profileImageLikeRepository.deleteByImageId(imageId);
        profileImageRepository.delete(imgOpt.get());
        LOGGER.info("User {} hat Profilbild {} gelöscht", myId, imageId);
        return ResponseEntity.noContent().build();
    }

    @PostMapping("/{imageId}/like")
    public ResponseEntity<Void> toggleLike(@PathVariable UUID imageId, Principal principal) {
        UUID myId = userService.requireUser(principal).getUserId();

        if (profileImageRepository.findById(imageId).isEmpty()) return ResponseEntity.notFound().build();

        likeService.toggleProfileImageLike(imageId, myId);
        return ResponseEntity.ok().build();
    }

    private ProfileImageDto toDto(ProfileImageEntity entity, UUID myId) {
        long likeCount = profileImageLikeRepository.countByImageId(entity.getImageId());
        boolean likedByMe = profileImageLikeRepository.findByImageIdAndUserId(entity.getImageId(), myId).isPresent();
        return new ProfileImageDto(entity.getImageId(), entity.getUserId(), entity.getImageData(),
                entity.getUploadedAt(), likeCount, likedByMe);
    }
}
