package de.oaa.xxx.social;

import de.oaa.xxx.social.dto.KommentarDto;
import de.oaa.xxx.social.entity.KommentarEntity;
import de.oaa.xxx.social.repository.KommentarLikeRepository;
import de.oaa.xxx.social.repository.KommentarRepository;
import de.oaa.xxx.user.UserEntity;
import de.oaa.xxx.user.UserRepository;
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/kommentare")
public class KommentarController {

    private static final Logger LOGGER = LoggerFactory.getLogger(KommentarController.class);

    private final KommentarRepository kommentarRepository;
    private final KommentarLikeRepository likeRepository;
    private final UserRepository userRepository;
    private final UserService userService;
    private final LikeService likeService;

    public KommentarController(KommentarRepository kommentarRepository,
                               KommentarLikeRepository likeRepository,
                               UserRepository userRepository,
                               UserService userService,
                               LikeService likeService) {
        this.kommentarRepository = kommentarRepository;
        this.likeRepository = likeRepository;
        this.userRepository = userRepository;
        this.userService = userService;
        this.likeService = likeService;
    }

    record CreateKommentarRequest(String targetType, UUID targetId, String text) {}

    @GetMapping
    public ResponseEntity<List<KommentarDto>> getKommentare(
            @RequestParam String targetType,
            @RequestParam("targetId") UUID targetId,
            Principal principal) {
        UUID myId = userService.requireUser(principal).getUserId();

        List<KommentarDto> dtos = kommentarRepository
                .findByTargetTypeAndTargetIdOrderByCreatedAtAsc(targetType, targetId)
                .stream()
                .map(k -> toDto(k, myId))
                .toList();
        return ResponseEntity.ok(dtos);
    }

    @PostMapping
    public ResponseEntity<KommentarDto> createKommentar(@RequestBody CreateKommentarRequest request, Principal principal) {
        UUID myId = userService.requireUser(principal).getUserId();

        if (request.text() == null || request.text().isBlank()) return ResponseEntity.badRequest().build();
        if (request.text().length() > 500) return ResponseEntity.badRequest().build();
        if (!List.of("PINNWAND", "IMAGE", "KOMMENTAR", "GROUP_POST", "FEED_POST").contains(request.targetType())) {
            return ResponseEntity.badRequest().build();
        }

        KommentarEntity entity = new KommentarEntity();
        entity.setKommentarId(UUID.randomUUID());
        entity.setAuthorId(myId);
        entity.setTargetType(request.targetType());
        entity.setTargetId(request.targetId());
        entity.setText(request.text().trim());
        entity.setCreatedAt(LocalDateTime.now());
        kommentarRepository.save(entity);
        LOGGER.debug("User {} hat Kommentar {} auf {} {} erstellt", myId, entity.getKommentarId(), request.targetType(), request.targetId());

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

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

        var kOpt = kommentarRepository.findById(kommentarId);
        if (kOpt.isEmpty()) return ResponseEntity.notFound().build();
        if (!kOpt.get().getAuthorId().equals(myId)) return ResponseEntity.status(403).build();

        // Delete nested replies and their likes
        List<KommentarEntity> replies = kommentarRepository
                .findByTargetTypeAndTargetIdOrderByCreatedAtAsc("KOMMENTAR", kommentarId);
        for (KommentarEntity reply : replies) {
            likeRepository.deleteByKommentarId(reply.getKommentarId());
            kommentarRepository.delete(reply);
        }
        likeRepository.deleteByKommentarId(kommentarId);
        kommentarRepository.delete(kOpt.get());
        LOGGER.debug("User {} hat Kommentar {} gelöscht", myId, kommentarId);
        return ResponseEntity.noContent().build();
    }

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

        if (kommentarRepository.findById(kommentarId).isEmpty()) return ResponseEntity.notFound().build();

        likeService.toggleKommentarLike(kommentarId, myId);
        return ResponseEntity.ok().build();
    }

    private KommentarDto toDto(KommentarEntity k, UUID myId) {
        UserEntity author = userRepository.findById(k.getAuthorId()).orElse(null);
        String authorName = author != null ? author.getName() : "Unbekannt";
        String authorPic = author != null ? author.getProfilePicture() : null;
        long likeCount = likeRepository.countByKommentarId(k.getKommentarId());
        boolean likedByMe = likeRepository.findByKommentarIdAndUserId(k.getKommentarId(), myId).isPresent();
        long replyCount = kommentarRepository.countByTargetTypeAndTargetId("KOMMENTAR", k.getKommentarId());
        return new KommentarDto(k.getKommentarId(), k.getAuthorId(), authorName, authorPic,
                k.getTargetType(), k.getTargetId(), k.getText(), k.getCreatedAt(),
                likeCount, likedByMe, replyCount);
    }
}
