package cz.utb.tadis.attacks.controller;

import cz.utb.tadis.attacks.http.AttackFormData;
import cz.utb.tadis.attacks.model.*;
import cz.utb.tadis.attacks.repository.AttacksRepository;
import cz.utb.tadis.attacks.util.ExportUtil;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@PreAuthorize("hasAnyRole('ANALYST', 'ADMIN')")
@RestController
@RequestMapping("/attacks")
public class AttacksDatabaseController {

    @Autowired
    AttacksRepository attacksRepository;

    @Autowired
    ExportUtil exportUtil;

    @GetMapping
    public ResponseEntity getAttacks(){
        List<Attack> attacks = attacksRepository.findAll();
        return new ResponseEntity(attacks, HttpStatus.OK);
    }

    @PostMapping
    public ResponseEntity createAttack(@Valid @RequestBody Attack attack){
        attack.setAttackersCount(attack.getAttackers().size());
        Attack savedAttack = attacksRepository.save(attack);
        return new ResponseEntity(savedAttack, HttpStatus.OK);
    }

    @PutMapping("/{id}")
    public ResponseEntity updateAttack(@PathVariable("id") Long id, @Valid @RequestBody Attack attack){
        attack.setAttackersCount(attack.getAttackers().size());
        Attack updatedAttack = attacksRepository.save(attack);
        return new ResponseEntity(updatedAttack, HttpStatus.OK);
    }

    @DeleteMapping("/{id}")
    public ResponseEntity deleteAttack(@PathVariable("id") Long id){
        attacksRepository.deleteById(id);
        return new ResponseEntity(HttpStatus.OK);
    }

    @PostMapping("/export")
    public ResponseEntity export(@RequestBody List<Long> attackIds, HttpServletResponse response) throws IOException {

        List<Attack> attacks = new ArrayList<>();
        if(attackIds != null) {
            List<Attack> allAttacks = attacksRepository.findAll();
            for (Long attackId : attackIds) {
                for (Attack attack : allAttacks) {
                    if (attackId.equals(attack.getId())) {
                        attacks.add(attack);
                        break;
                    }
                }
            }
        }

        Workbook workbook = exportUtil.generateExport(attacks);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        workbook.write(baos);
        baos.close();
        byte[] workbookByteArray = baos.toByteArray();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        response.setHeader("Content-Disposition", "attachment; filename=attacks.xlsx");

        return new ResponseEntity(workbookByteArray, headers, HttpStatus.OK);
    }

    @GetMapping("/form")
    public ResponseEntity getFormData(){
        AttackFormData attackFormData = new AttackFormData(
                attacksRepository.findAllDistinctCountry(),
                attacksRepository.findAllDistinctCity(),
                attacksRepository.findAllDistinctSoftTargetDescription(),
                attacksRepository.findAllDistinctTerroristOrganization(),
                ClosedResponse.values(),
                Epicenter.values(),
                Gender.values(),
                Locality.values(),
                ModusOperandi.values(),
                SoftTargetTypeEnum.values()
        );
        return new ResponseEntity(attackFormData, HttpStatus.OK);
    }

}
