package de.accso.flexinale.backoffice.api_in.rest;

import de.accso.flexinale.backoffice.application.services.VorfuehrungUploadService;
import de.accso.flexinale.backoffice.domain.model.Vorfuehrung;
import de.accso.flexinale.backoffice.application.services.VorfuehrungService;
import de.accso.flexinale.common.shared_kernel.Identifiable;
import de.accso.flexinale.ticketing_api_contract.api_contract.Ticketing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.util.Collection;
import java.util.List;

import static de.accso.flexinale.common.shared_kernel.RawWrapper.getRawOrNull;

@RestController
public class VorfuehrungRestController extends AbstractExcelRestController {

    @Autowired
    private VorfuehrungService vorfuehrungService;

    @Autowired
    private VorfuehrungUploadService vorfuehrungUploadService;

    @Autowired
    private Ticketing ticketing;

    @GetMapping(value = "/rest/vorfuehrungen", produces = "application/json")
    @PreAuthorize("hasRole('ROLE_BESUCHER')")
    public List<Vorfuehrung> vorfuehrungen() {
        return vorfuehrungService.vorfuehrungen();
    }

    @GetMapping(value = "/rest/vorfuehrungen/{id}", produces = "application/json")
    @PreAuthorize("hasRole('ROLE_BESUCHER')")
    public Vorfuehrung vorfuehrung(@PathVariable final String id) {
        Identifiable.Id vorfuehrungId = Identifiable.Id.of(id);
        Vorfuehrung vorfuehrung = vorfuehrungService.vorfuehrung(vorfuehrungId);
        if (vorfuehrung == null) {
            throw new RestResourceNotFoundException("no Vorfuehrung %s found.".formatted(id));
        }

        return vorfuehrung;
    }

    @PostMapping("/rest/vorfuehrungen")
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    public ResponseEntity<RestResponseMessage> uploadVorfuehrungen(@RequestParam("file") final MultipartFile file) {
        try(BufferedInputStream stream = new BufferedInputStream(file.getInputStream())) {
            Collection<Vorfuehrung> vorfuehrungen = vorfuehrungUploadService.loadDataFromExcelSheet(stream);

            // and advice ticketing (results in kontingente)
            for (Vorfuehrung vorfuehrung : vorfuehrungen) {
                try {
                    ticketing.gebeVorfuehrungInDenVerkauf(vorfuehrung.id(), getRawOrNull(vorfuehrung.kinoSaal.anzahlPlaetze));
                }
                catch (IllegalStateException ise) {
                    // do nothing... Kontingent already exists. We do not support any update of entities here
                }
            }
        } catch (Exception ex) {
            String message = "Could not upload the Excel file: %s: %s".formatted(file.getOriginalFilename(), ex.getMessage());
            throw new RestBadRequestException(message, ex);
        }

        RestUploadResult restUploadResult = uploadViaRestCall(vorfuehrungUploadService, file);
        return ResponseEntity.status(restUploadResult.status())
                .body(new RestResponseMessage(restUploadResult.message()));
    }
}
