package org.academiadecodigo.enuminatti.restuser.controllers;

import org.academiadecodigo.enuminatti.restuser.models.User;
import org.academiadecodigo.enuminatti.restuser.services.UserService;
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.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import javax.validation.Valid;
import java.util.List;

/**
 * MIT License
 * (c) 2017 Ricardo Constantino
 */

@RestController
public class UserRestfulController {
    @Autowired
    private UserService userService;

    @RequestMapping(method = RequestMethod.GET, value = "/bananas",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<User>> listUsers() {
        return new ResponseEntity<>(userService.findAll(), HttpStatus.OK);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/bananas/{id}",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<User> getUserById(@PathVariable Integer id) {
        User user = userService.findById(id);

        if (user == null) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        return new ResponseEntity<>(user, HttpStatus.OK);
    }

    @RequestMapping(method = RequestMethod.POST, value = "/bananas",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> addUser(@Valid @RequestBody User user,
                                     BindingResult bindingResult,
                                     UriComponentsBuilder uriComponentsBuilder) {
        if (bindingResult.hasErrors() || user.getId() != null) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }

        if (userService.findByName(user.getName()) != null) {
            return new ResponseEntity<>(HttpStatus.CONFLICT);
        }

        userService.add(user);

        HttpHeaders headers = new HttpHeaders();

        UriComponents components = uriComponentsBuilder.path("/bananas/" + user.getId()).build();

        headers.setLocation(components.toUri());

        return new ResponseEntity<>(headers, HttpStatus.CREATED);
    }

    @RequestMapping(method = RequestMethod.PUT, value = "/bananas/{id}",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> editUser(@Valid @RequestBody User user,
                                      @PathVariable Integer id,
                                      BindingResult bindingResult,
                                      UriComponentsBuilder uriComponentsBuilder) {
        if (bindingResult.hasErrors() || user.getId() == null || !id.equals(user.getId())) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }

        if (userService.findById(id) == null) {
            return new ResponseEntity<>(HttpStatus.CONFLICT);
        }

        userService.add(user);

        HttpHeaders headers = new HttpHeaders();

        UriComponents components = uriComponentsBuilder.path("/bananas/" + user.getId()).build();

        headers.setLocation(components.toUri());

        return new ResponseEntity<>(headers, HttpStatus.CREATED);
    }

    @RequestMapping(method = RequestMethod.DELETE, value = "/bananas/{id}",
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> removeUser(@PathVariable Integer id) {
        if (userService.findById(id) == null) {
            return new ResponseEntity<>(HttpStatus.CONFLICT);
        }

        userService.remove(id);

        return new ResponseEntity<>(HttpStatus.OK);
    }
}
