public IActionResult Get([FromQuery] IntervalsForWorkDayReservationQueryParams queryParams)
 {
     try
     {
         if (queryParams != null)
         {
             //TODO: QueryParamsResponseDto
             return(Ok(_intervalsForWorkDayService.GetIntervalsForWorkDayReservation(queryParams)));
         }
         return(Ok(_mapper.Map <List <IntervalsForWorkDayDto> >(_intervalsForWorkDayService.GetIntervalsForWorkDays())));
     }
     catch (Exception e)
     {
         if (e.GetType().IsAssignableFrom(typeof(InvalidReservationQueryParametersException)))
         {
             return(BadRequest(e.Message));
         }
         else if (e.GetType().IsAssignableFrom(typeof(IntervalForWorkDayNotFoundException)))
         {
             return(NotFound(e.Message));
         }
         else
         {
             return(StatusCode(StatusCodes.Status500InternalServerError, e.Message));
         }
     }
 }
        public IntervalsForWorkDayReservationQueryParamsResponse GetIntervalsForWorkDayReservation(IntervalsForWorkDayReservationQueryParams queryParams)
        {
            String workDayId = queryParams.WorkDayId;
            String startHour = queryParams.StartHour;
            String endHour   = queryParams.EndHour;
            //String numberOfPeople = queryParams.NumberOfPeople;
            String gameId = queryParams.GameId;
            Dictionary <Table, int> tablesDict = new Dictionary <Table, int>();
            Dictionary <Game, int>  gamesDict  = new Dictionary <Game, int>();

            try
            {
                if (workDayId == null || startHour == null || endHour == null)
                {
                    throw new InvalidReservationQueryParametersException("Bad query parameters, required params are missing");
                }
                if (!CheckIdHelpper.CheckId(workDayId))
                {
                    throw new InvalidReservationQueryParametersException("Work id is not a valid 24 digit hex string");
                }
                IntervalsForWorkDay intervalsForWorkDay = _intervalsForWorkDaysRepository.GetIntervalsForWorkDayByWorkDayId(workDayId);
                if (intervalsForWorkDay == null)
                {
                    //No free intervals (it's not a work day)
                    throw new IntervalForWorkDayNotFoundException("No intervals for a work day to show");
                }

                List <IntervalForWorkDay> freeTimeIntervals = intervalsForWorkDay.FreeTimeIntervals;
                if (freeTimeIntervals == null || freeTimeIntervals.Count == 0)
                {
                    //throw new Exception("No free intervals to show");
                    return(new IntervalsForWorkDayReservationQueryParamsResponse());
                }

                //TODO: Start hour should be larger than workDay schema startHour, frontend
                int s     = Convert.ToInt32(startHour);
                int e     = Convert.ToInt32(endHour);
                int hours = e - s;
                if (hours < 0 || hours > 3)
                {
                    throw new InvalidReservationQueryParametersException("Wrong query params StartHour should be smaller than EndHour with max difference 3");
                }
                int          i = 0;
                List <Table> freeTables;
                List <Game>  freeGames;
                List <Table> tables = new List <Table>();
                List <Game>  games  = new List <Game>();
                foreach (IntervalForWorkDay interval in freeTimeIntervals)
                {
                    if (interval.StartHour >= s && interval.EndHour >= e)
                    {
                        // For one day game name, price and other fields will be the same in every list of games
                        // even when reservations are cancelled (if name price changes it will stay the same as it was
                        // when intervals were made (work day was inserted))
                        freeTables = interval.FreeTables;
                        freeGames  = interval.FreeGames;

                        if (i == 0)
                        {
                            //TODO: should be better
                            try
                            {
                                InitializeTablesAndGamesDict(tablesDict, freeTables, gamesDict, freeGames, gameId);
                            }
                            catch (Exception exc)
                            {
                                Console.WriteLine(exc.Message);
                                return(new IntervalsForWorkDayReservationQueryParamsResponse());
                            }
                        }
                        else
                        {
                            GetTables(tablesDict, freeTables);
                            GetGames(gamesDict, freeGames, gameId);
                        }
                        i++;
                    }
                    if (i == hours)
                    {
                        break;
                    }
                } //foreach

                GetFreeTables(tables, tablesDict, hours);
                if (tables.Count > 0)
                {
                    IntervalsForWorkDayReservationQueryParamsResponse response = new IntervalsForWorkDayReservationQueryParamsResponse();

                    if (gameId == null) //Reservation
                    {
                        GetFreeGames(games, gamesDict, hours);
                        response.Tables = tables;
                        response.Games  = games;
                        return(response);
                    }
                    else //GameReservation
                    {
                        response.Tables = tables;
                        foreach (KeyValuePair <Game, int> kvp in gamesDict)
                        {
                            if (kvp.Value == hours)
                            {
                                games.Add(kvp.Key);
                                response.Games = games;
                                return(response);
                            }
                            else
                            {
                                //TODO: Should be nicer
                                //throw new Exception("Game is not available");
                                return(response);
                            }
                        }
                        //logically unreachable
                        //throw new Exception("Game is not available");
                        return(response);
                    }
                }
                else
                {
                    //No free tables
                    //throw new Exception("No free tables");
                    return(new IntervalsForWorkDayReservationQueryParamsResponse());
                }
            }
            catch (Exception e)
            {
                //TODO custom exception
                //Conversion not successfull or s>e
                throw new Exception(e.Message);
            }
        }