package de.oaa.xxx.games.vanilla.controller;

import de.oaa.xxx.games.common.aufgaben.Favorit;
import de.oaa.xxx.games.common.aufgaben.FavoritList;
import de.oaa.xxx.games.common.entity.FavoritEntity;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.FavoritRepository;
import de.oaa.xxx.user.UserService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

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

@RestController
@RequestMapping("/vanilla/favorit")
@Transactional
public class VanillaFavoritController {

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

    private final FavoritRepository favoritRepository;
    private final AufgabenGruppeRepository gruppeRepository;
    private final UserService userService;

    public VanillaFavoritController(FavoritRepository favoritRepository,
                                     AufgabenGruppeRepository gruppeRepository,
                                     UserService userService) {
        this.favoritRepository = favoritRepository;
        this.gruppeRepository = gruppeRepository;
        this.userService = userService;
    }

    @GetMapping("/{favoritId}")
    public ResponseEntity<Favorit> get(@PathVariable("favoritId") UUID favoritId) {
        return favoritRepository.findById(favoritId)
                .map(entity -> ResponseEntity.ok(entity.toFavorit()))
                .orElse(ResponseEntity.noContent().build());
    }

    @GetMapping
    public ResponseEntity<FavoritList> all(Principal principal) {
        UUID userId = userService.requireUser(principal).getUserId();
        List<FavoritEntity> entities = favoritRepository.findByUserId(userId);
        FavoritList result = new FavoritList();
        // Only return favorites pointing to vanilla-safe groups
        result.setFavoriten(entities.stream()
                .filter(f -> {
                    var gruppe = gruppeRepository.findById(f.getAufgabenGruppeId()).orElse(null);
                    return gruppe != null && gruppe.getStrafen().isEmpty() && gruppe.getSperren().isEmpty();
                })
                .map(FavoritEntity::toFavorit).toList());
        return ResponseEntity.ok(result);
    }

    @PostMapping
    public ResponseEntity<Void> create(@RequestBody Favorit favorit, Principal principal) {
        UUID userId = userService.requireUser(principal).getUserId();
        if (favorit.getAufgabenGruppeId() == null) {
            return ResponseEntity.badRequest().build();
        }
        // Validate vanilla-safe
        var gruppe = gruppeRepository.findById(favorit.getAufgabenGruppeId()).orElse(null);
        if (gruppe == null || !gruppe.getStrafen().isEmpty() || !gruppe.getSperren().isEmpty()) {
            return ResponseEntity.status(403).build();
        }
        List<FavoritEntity> existing = favoritRepository.findByUserIdAndAufgabenGruppeId(userId, favorit.getAufgabenGruppeId());
        FavoritEntity entity;
        if (existing.isEmpty()) {
            entity = FavoritEntity.fromFavorit(favorit, userId);
            favoritRepository.save(entity);
            LOGGER.debug("User {} hat Vanilla-AufgabenGruppe {} als Favorit gespeichert", userId, favorit.getAufgabenGruppeId());
        } else {
            entity = existing.get(0);
        }
        return ResponseEntity.created(
                ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getFavoritId()).toUri()
        ).build();
    }

    @DeleteMapping
    public ResponseEntity<Void> delete(@RequestBody Favorit favorit, Principal principal) {
        try {
            UUID userId = userService.requireUser(principal).getUserId();
            favoritRepository.findByUserIdAndAufgabenGruppeId(userId, favorit.getAufgabenGruppeId())
                    .forEach(favoritRepository::delete);
            return ResponseEntity.accepted().build();
        } catch (Exception exception) {
            LOGGER.error(exception.getMessage(), exception);
            return ResponseEntity.internalServerError().build();
        }
    }
}
