﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
using AutoMapper;
using Diacheck.Bll.Interfaces.Services;
using Diacheck.Domain.Models;
using DiaCheck.Api.ViewModels.Meal;
using Swashbuckle.Swagger.Annotations;

namespace DiaCheck.Api.Controllers
{
    [RoutePrefix("meals")]
    public class MealController : ApiController
    {
        private readonly IMealService _mealService;
        private readonly IMapper _mapper;

        public MealController(IMealService mealService, IMapper mapper)
        {
            _mealService = mealService;
            _mapper = mapper;
        }

        /// <summary>
        /// Return list of all meals for current user
        /// </summary>
        /// <returns>List of meals</returns>
        [SwaggerResponse(HttpStatusCode.OK, "Successful operation", typeof(List<MealViewModel>))]
        [Authorize]
        [Route("")]
        [HttpGet]
        public IHttpActionResult Get()
        {
            var meals = _mealService.Get();
            if (meals == null || !meals.Any())
            {
                return Ok(new List<MealViewModel>());
            }

            var mealsToReturn = _mapper.Map<IEnumerable<MealViewModel>>(meals);

            return Ok(mealsToReturn);
        }

        /// <summary>
        /// Get all meals for current user during the set period
        /// </summary>
        /// <param name="from">Search meals from</param>    
        /// <param name="to">Search meals to the date</param>
        /// <returns>List of meals</returns>
        [SwaggerResponse(HttpStatusCode.OK, "Successful operation", typeof(IEnumerable<MealViewModel>))]
        [Authorize]
        [Route("{from}/till/{to}")]
        [HttpGet]
        public IHttpActionResult GetForPeriod(DateTime from, DateTime to)
        {
            var meals = _mealService.Get(from, to);

            return Ok(_mapper.Map<IEnumerable<MealViewModel>>(meals));
        }

        /// <summary> 
        /// Get all meals for current user during the set period grouped by dateTime
        /// </summary>
        /// <param name="from">Search meals from</param>    
        /// <param name="to">Search meals to the date</param>
        /// <returns>List of meals grouped by date time</returns>
        [SwaggerResponse(HttpStatusCode.OK, "Successful operation", typeof(IEnumerable<MealViewModel>))]
        [Authorize]
        [Route("grouped/{from}/till/{to}")]
        [HttpGet]
        public IHttpActionResult GetGroupedForPeriod(DateTime from, DateTime to)
        {
            var meals = _mealService.Get(from, to);
            var mappedMeal = _mapper.Map<IEnumerable<MealViewModel>>(meals);
            var groupedMappedMeal = mappedMeal.GroupBy(m => m.DateTime.Date)
                .Select(m => new
                {
                    dateTime = m.Key,
                    meals = m.ToList()
                });

            return Ok(groupedMappedMeal);
        }

        /// <summary>
        /// Add new meal for current user
        /// </summary>
        /// <param name="level">New meal to add</param>
        /// <returns>Created meal</returns>
        [SwaggerResponse(HttpStatusCode.OK, "Successful operation", typeof(MealViewModel))]
        [Route("")]
        [HttpPost]
        public IHttpActionResult Post([FromBody]MealAddModel meal)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var mealToAdd = _mapper.Map<Meal>(meal);
            _mealService.Add(mealToAdd);

            return Ok(_mapper.Map<MealViewModel>(mealToAdd));
        }

        /// <summary>
        /// Delete meal
        /// </summary>
        /// <param name="mealId">Value of meal Id to delete</param>
        /// <returns>Created meal</returns>
        [SwaggerResponse(HttpStatusCode.OK, "Meal was deleted")]
        [Route("")]
        [HttpDelete]
        public IHttpActionResult Post(int mealId)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            _mealService.Delete(mealId);

            return Ok("Meal was deleted");
        }
    }
}
