package au.gov.dto.dibp.appointments.availabletimes;

import au.gov.dto.dibp.appointments.client.Client;
import au.gov.dto.dibp.appointments.util.CalendarIdValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class AvailableTimesController {

    private final AvailableTimesService availableTimesService;
    private final CalendarIdValidator calendarIdValidator;

    @Autowired
    public AvailableTimesController(AvailableTimesService availableTimesService, CalendarIdValidator calendarIdValidator){
        this.availableTimesService = availableTimesService;
        this.calendarIdValidator = calendarIdValidator;
    }

    @RequestMapping(value = "/get_available_times", method = RequestMethod.GET, produces = "application/json")
    public Map<String, Object> getAvailableTimes(@AuthenticationPrincipal Client client, @RequestParam(value="calendar_id", required=false) String calendarId) {

        if(!calendarIdValidator.isCalendarIdValid(calendarId)){
            throw new RuntimeException("Invalid format of the calendarId!");
        }

        Map<String, Object> map = new HashMap<>();
        map.put("times", availableTimesService.getAvailableTimes(client, calendarId));
        return map;
    }

    @RequestMapping(value = "/get_available_times_text_with_label", method = RequestMethod.GET, produces = "application/json")
    public Map<String, Object> getAvailableTimesWithLabel(@AuthenticationPrincipal Client client, @RequestParam(value="calendar_id", required=false) String calendarId) {

        if(!calendarIdValidator.isCalendarIdValid(calendarId)){
            throw new RuntimeException("Invalid format of the calendarId!");
        }

        final Map<String, List<String>> result = availableTimesService.getAvailableTimesWithCalendarDate(client, calendarId);
        String date = result.keySet().iterator().next();

        final List<String> availableTimes = result.get(date);
        List<TimeWithLabel> timesWithLabels = new ArrayList<>();
        for(String availableTime: availableTimes){
            LocalTime time = LocalTime.parse(availableTime);
            timesWithLabels.add(new TimeWithLabel(availableTime, time.format(DateTimeFormatter.ofPattern("h:mm a"))));
        }

        Map<String, Object> map = new HashMap<>();
        map.put("times", timesWithLabels);
        map.put("date", date);
        return map;
    }
}

@@ -160,16 +160,73 @@
 idator;%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A
 import o
@@ -404,30 +404,17 @@
 otation.
-RequestMapping
+*
 ;%0Aimport
@@ -442,98 +442,75 @@
 web.
-bind.annotation.RequestMethod;%0Aimport org.springframework.web.bind.annotation.
+servlet.ModelAndView;%0A%0Aimport javax.servlet.http.HttpServlet
 Request
-Param
 ;%0Aim
@@ -518,64 +518,47 @@
 ort 
-org.springframework.web.bind.annotation.RestController;%0A
+javax.servlet.http.HttpServletResponse;
 %0Aimp
@@ -780,16 +780,114 @@
 roller %7B
+%0A    private static final Logger LOGGER = LoggerFactory.getLogger(AvailableTimesController.class);
 %0A%0A    pr
@@ -3007,11 +3007,424 @@
 p;%0A    %7D
+%0A%0A    @ExceptionHandler(RuntimeException.class)%0A    public ModelAndView handleNoCalendarExistsException(HttpServletRequest request, HttpServletResponse response, RuntimeException exception)%7B%0A        LOGGER.warn(%22Unhandled RuntimeException%22, exception);%0A%0A        if (response.getStatus() == 200) %7B%0A            response.setStatus(500);%0A        %7D%0A        return new ModelAndView(%22error_page%22, new HashMap%3C%3E());%0A    %7D
 %0A%7D%0A

Fix bug with lack of retries for timeslot loading