package cz.utb.tadis.news.controller;

import cz.utb.tadis.common.http.ApiResponse;
import cz.utb.tadis.news.model.Attachment;
import cz.utb.tadis.news.model.New;
import cz.utb.tadis.news.repository.AttachmentsRepository;
import cz.utb.tadis.news.repository.NewsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.Optional;
import java.util.Set;

@RestController
@RequestMapping("/news")
public class NewsController {

    @Autowired
    NewsRepository newsRepository;

    @Autowired
    AttachmentsRepository attachmentsRepository;

    Long batchSize;

    public NewsController(@Value("${cz.utb.tadis.news.batchSize}") Long batchSize) {
        this.batchSize = batchSize;
    }

    @GetMapping("/{id}")
    public ResponseEntity getBatch(@PathVariable("id") Long lastId){
        List<New> news;
        if (lastId < 0)
            news = newsRepository.findFirstBatch(this.batchSize);
        else
            news = newsRepository.findNextBatch(lastId, this.batchSize);
        for (New item : news){
            removeAttachementsData(item);
        }
        return new ResponseEntity(news, HttpStatus.OK);
    }

    @GetMapping
    public ResponseEntity getAllNews(){
        List<New> news = newsRepository.findAllByOrderByIdDesc();
        return new ResponseEntity(news, HttpStatus.OK);
    }

    @GetMapping("/attachment/{id}")
    public ResponseEntity getAttachment(@PathVariable("id") Long id, HttpServletResponse response){
        Optional<Attachment> attachment = attachmentsRepository.findById(id);
        if (!attachment.isPresent()){
            return new ResponseEntity(new ApiResponse(HttpStatus.NOT_FOUND, "Attachment not found"), HttpStatus.NOT_FOUND);
        }

        MediaType fileMediaType;
        try {
            fileMediaType = MediaType.valueOf(attachment.get().getFileType());
        }
        catch (Exception e){
            fileMediaType = MediaType.APPLICATION_OCTET_STREAM;
        }

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(fileMediaType);
        response.setHeader("Content-Disposition", "attachment; filename=" + attachment.get().getFileName());
        return new ResponseEntity(attachment.get().getData(), headers, HttpStatus.OK);
    }

    @PreAuthorize("hasRole('ADMIN')")
    @PutMapping
    public ResponseEntity saveNew(@Valid @RequestBody New newItem){
        New savedItem = newsRepository.save(newItem);
        removeAttachementsData(savedItem);
        return new ResponseEntity(savedItem, HttpStatus.OK);
    }

    @PreAuthorize("hasRole('ADMIN')")
    @DeleteMapping("/{id}")
    public ResponseEntity deleteNew(@PathVariable("id") Long id){
        newsRepository.deleteById(id);
        return new ResponseEntity(HttpStatus.OK);
    }

    private void removeAttachementsData(New item){
        Set<Attachment> attachments = item.getAttachments();
        if (attachments != null && attachments.size() > 0) {
            for (Attachment attachment : attachments) {
                attachment.setData(null);
            }
        }
    }
}
