package com.fsd.hellovelo.controller;

import com.fsd.hellovelo.entity.Bike;
import com.fsd.hellovelo.entity.EStatus;
import com.fsd.hellovelo.entity.Station;
import com.fsd.hellovelo.exceptions.ResourceNotFoundException;
import com.fsd.hellovelo.payload.request.BikeTransferRequest;
import com.fsd.hellovelo.payload.request.UpdateBikeRequest;
import com.fsd.hellovelo.payload.response.MessageResponse;
import com.fsd.hellovelo.repository.BikeRepository;
import com.fsd.hellovelo.service.BikeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.config.ConfigDataResourceNotFoundException;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

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

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@PreAuthorize("hasRole('ADMIN')")
@RequestMapping("/api/admin/bikes")
public class BikeController {

    @Autowired
    private final BikeService bikeService;

    @Autowired
    public BikeController(BikeService bikeService) {
        this.bikeService = bikeService;
    }

    @Autowired
    private BikeRepository bikeRepository;


    // **********************************  GET LIST Of ALL BIKES (without search,sort,pagination) **********************************
    @GetMapping()
    public List<Bike> getAllBikes(@RequestParam(required = false) String deleted) {
        if( deleted == null){
            return bikeService.findAllBikes(false);
        }
        else {
            return  bikeService.findAllBikes(true);
        }
        // /api/admin/bikes?deleted=true
        //return bikeService.findAllBikes();
    }



    /**********************************  GET LIST Of ALL BIKES WITH SEARCH, SORT, PAGINATION **********************************/

    @GetMapping("/search/{searchText}")
    public Page<Bike> getAllPaginatedBikes( int pageNumber, int pageSize, String sortBy, String sortDir, @PathVariable String searchText) {
            return  bikeService.findAllPaginatedBikeListWithSearch( pageNumber,pageSize,sortBy,sortDir,searchText);
    }

    /**********************************  GET LIST Of ALL BIKES(SORT, PAGINATION) **********************************/

    @GetMapping("/paginated")
    public Page<Bike> getAllPaginatedBikes(@RequestParam(required = false) String deleted, int pageNumber, int pageSize, String sortBy, String sortDir) {
        if( deleted == null) {
            return bikeService.findAllPaginatedBikeListWithoutSearch(false, pageNumber, pageSize, sortBy, sortDir);
        }else{
            return bikeService.findAllPaginatedBikeListWithoutSearch(true, pageNumber, pageSize, sortBy, sortDir);
        }
    }

    // **********************************  ADD A NEW BIKE **********************************
    @PostMapping
    //@PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<?> addBike(@Valid @RequestBody Bike bike) {
        try {
            return ResponseEntity.status(HttpStatus.OK).body(bikeService.addBike(bike));
        }
        catch (IllegalArgumentException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new MessageResponse(e.getMessage()));
        }

    }

    // **********************************  GET A BIKE BY ID **********************************

        @GetMapping(path = "{bikeId}")
        public ResponseEntity<?> getBikeById (@PathVariable("bikeId") Long bikeId){
            try {
                Bike bike = bikeService.getBike(bikeId);
                return ResponseEntity.status(HttpStatus.OK).body(bike);
            } catch (ResourceNotFoundException e) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new MessageResponse(e.getMessage()));
            }
//        Bike bike = bikeRepository.findById(id)
//                .orElseThrow(()-> new ResourceNotFoundException("Bike does not exists with this ID" + id));
//        return bike;
        }

    @GetMapping(path = "/edit/{bikeId}")
    public ResponseEntity<?> getBikeModelById (@PathVariable("bikeId") Long bikeId){
        try {
            Bike bike = bikeService.getBike(bikeId);
            UpdateBikeRequest bikeModel = new UpdateBikeRequest();
            bikeModel.setId(bike.getId());
            bikeModel.setBikeType(bike.getBikeType());
            bikeModel.setCurrentlyInUse(bike.isCurrentlyInUse());
            bikeModel.setLastMaintenance(bike.getLastMaintenance());
            bikeModel.setSerialNumber(bike.getSerialNumber());
            if(bike.getStation() == null){
                bikeModel.setStationId(0L);
            }else {
                bikeModel.setStationId(bike.getStation().getId());
            }
            return ResponseEntity.status(HttpStatus.OK).body(bikeModel);
        } catch (ResourceNotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new MessageResponse(e.getMessage()));
        }
//        Bike bike = bikeRepository.findById(id)
//                .orElseThrow(()-> new ResourceNotFoundException("Bike does not exists with this ID" + id));
//        return bike;
    }



    // **********************************  UPDATE A BIKE **********************************

    @PutMapping(path = "{bikeId}")
    //@PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<?> updateBike(@PathVariable("bikeId") Long bikeId, @RequestBody @Valid UpdateBikeRequest newBike) {
        System.out.println(newBike);
        try {
            return ResponseEntity.status(HttpStatus.OK).body(bikeService.updateBike(bikeId, newBike));
        }
        catch (ResourceNotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body( new MessageResponse(e.getMessage()));
        }
        catch (IllegalArgumentException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new MessageResponse(e.getMessage()));
        }

    }

    // **********************************  DELETE A BIKE **********************************
    @DeleteMapping(path = "{bikeId}")
    //@PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<?> deleteStation(@PathVariable("bikeId") Long bikeId) {
        try {
            bikeService.deleteBike(bikeId);
            return ResponseEntity.status(HttpStatus.OK).body("Bike is Removed");
        }
        catch (ResourceNotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new MessageResponse(e.getMessage()));
        }
        catch (IllegalArgumentException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new MessageResponse(e.getMessage()));
        }
    }

    // ********************************** TRANSFER BIKES **********************************
    @PutMapping("/transfer")
    public ResponseEntity<?> transferBikes(@Valid @RequestBody BikeTransferRequest bikeTransferRequest) {
        try {
            Long transferStationId = bikeService.transferBikes(bikeTransferRequest);
            return ResponseEntity.status(HttpStatus.OK).body("Bikes have been transferred to station with id: " + transferStationId);
        }
        catch (ResourceNotFoundException e) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new MessageResponse(e.getMessage()));
        }
        catch (IllegalArgumentException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new MessageResponse(e.getMessage()));
        }
    }

    }
