package de.oaa.xxx.aufgaben.controller;

import de.oaa.xxx.aufgaben.AufgabenGruppe;
import de.oaa.xxx.aufgaben.AufgabenGruppeList;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.util.UUID;

@RestController
@RequestMapping("/gruppe")
@Transactional
public class AufgabenGruppeController {

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

    private final AufgabenGruppeRepository gruppeRepository;

    public AufgabenGruppeController(AufgabenGruppeRepository gruppeRepository) {
        this.gruppeRepository = gruppeRepository;
    }

    @GetMapping("/all")
    public ResponseEntity<AufgabenGruppeList> getAll(@RequestParam(required = false) String search) {
        UUID userId = (UUID) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String searchPattern = search != null ? "%" + search + "%" : null;
        AufgabenGruppeList list = new AufgabenGruppeList();
        list.setGruppen(gruppeRepository.listWithUserAndSearch(userId, searchPattern, PageRequest.of(0, 500))
                .stream().map(AufgabenGruppeEntity::toAufgabenGruppeDisplay).toList());
        return ResponseEntity.ok(list);
    }

    @GetMapping("/own")
    public ResponseEntity<AufgabenGruppeList> getOwn(@RequestParam UUID userId) {
        AufgabenGruppeList list = new AufgabenGruppeList();
        list.setGruppen(gruppeRepository.findByUserId(userId)
                .stream().map(AufgabenGruppeEntity::toAufgabenGruppeDisplay).toList());
        return ResponseEntity.ok(list);
    }

    @GetMapping("/{gruppeId}")
    public ResponseEntity<AufgabenGruppe> get(@PathVariable UUID gruppeId) {
        return gruppeRepository.findById(gruppeId)
                .map(entity -> ResponseEntity.ok(entity.toAufgabenGruppe()))
                .orElse(ResponseEntity.noContent().build());
    }

    @PostMapping
    public ResponseEntity<Void> create(@RequestBody AufgabenGruppe gruppe) {
        AufgabenGruppeEntity entity = AufgabenGruppeEntity.create(gruppe);
        gruppeRepository.save(entity);
        return ResponseEntity.created(
                ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getGruppenId()).toUri()
        ).build();
    }

    @DeleteMapping
    public ResponseEntity<Void> delete(@RequestBody AufgabenGruppe gruppe) {
        try {
            gruppeRepository.findById(gruppe.getGruppenId()).ifPresent(gruppeRepository::delete);
            return ResponseEntity.accepted().build();
        } catch (Exception exception) {
            LOGGER.error(exception.getMessage(), exception);
            return ResponseEntity.internalServerError().build();
        }
    }
}
