using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using AutoMapper;
using Google.GData.YouTube;
using Qusion.Cms.Media;
using Qusion.Cms.Media.Core;
using Qusion.Cms.Media.Video;
using Qusion.WebApp.Areas.Qusion.Models.Libraries;
using Qusion.WebApp.Areas.Qusion.Models.Videos;
using Qusion.Framework.Configuration;
using Qusion.WebApp.Areas.Qusion.Helpers;

namespace Qusion.WebApp.Areas.Qusion.Controllers.Api
{
    public class VideoController : ApiController
    {
        private readonly LibraryService _libraryService;
        private readonly VideoService _videoService;

        public VideoController(VideoService videoService, LibraryService libraryService)
        {
            _videoService = videoService;
            _libraryService = libraryService;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet]
        public HttpResponseMessage Query([FromUri] VideoQueryInput input)
        {
          
                VideoQuery query = Mapper.Map<VideoQueryInput, VideoQuery>(input);
                if (input.LibraryID != null)
                {
                    // query.Sorting.SortOrder;
                }
                Library library = input.LibraryID.HasValue ? _libraryService.GetById(input.LibraryID) : null;

                IList<VideoItem> videos = _videoService.Search(query).ToList();
                var model = new VideoListWrapper
                {
                    Library = Mapper.Map<Library, LibraryListModel>(library),
                    Videos = Mapper.Map<IEnumerable<VideoItem>, IList<VideoListModel>>(videos),
                    Paging = query.Paging
                };
                return Request.CreateResponse(HttpStatusCode.OK, model);
            
        }

        /// <summary>
        /// Permanently delete library and all videos in it.
        /// </summary>
        /// <param name="id"> Id of library. </param>
        /// <returns> </returns>
        [HttpGet]
        public HttpResponseMessage RemoveLibrary(Guid id)
        {
            Library library = _libraryService.GetById(id);
            IList<VideoItem> videos = _videoService.GetForLibrary(id);

            foreach (VideoItem item in videos)
            {
                if(item.Extension != "youtube")
                    _videoService.DeleteFile(_videoService.GetById(item.GuidID));
                
                _videoService.Delete(_videoService.GetById(item.GuidID));
            }

            _libraryService.DeleteDirectory(library);
            _libraryService.Delete(library);

            return Request.CreateResponse(HttpStatusCode.OK, new { success = true });
        }

        /// <summary>
        /// Get one video by its id.
        /// </summary>
        /// <param name="id">Video id.</param>
        /// <returns></returns>
        public HttpResponseMessage Get(Guid id)
        {
            var video = _videoService.GetById(id);

            if(video != null)
            {
                var mapped = Mapper.Map<VideoItem, VideoModel>(video);
                return Request.CreateResponse(HttpStatusCode.OK, mapped);
            }

            return Request.CreateResponse(HttpStatusCode.NotFound);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <param name="libraryID"></param>
        /// <returns></returns>
        public HttpResponseMessage SaveYouTubeVideo(VideoCreateList model)
        {
            IList<VideoItem> videos = Mapper.Map<IList<VideoCreateModel>, IList<VideoItem>>(model.Videos);

            Library library = _libraryService.GetById(model.LibraryID);
            foreach (VideoItem video in videos)
            {
                video.Library = library;

                _videoService.Save(video);
            }
            return Request.CreateResponse(HttpStatusCode.OK);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public HttpResponseMessage EditYouTube(VideoEditModel model)
        {
            var video = _videoService.GetById(model.ID);

            Mapper.Map(model, video);
            _videoService.Save(video);
           
            return Request.CreateResponse(HttpStatusCode.OK);
        }

        /// <summary>
        /// Reordering videos in library.
        /// </summary>
        /// <param name="input">Input properties.</param>
        /// <returns>Http status ok.</returns>
        [HttpPost]
        public HttpResponseMessage Organize(OrganizeInput input)
        {
            _videoService.Organize(input.Members);
            return Request.CreateResponse(HttpStatusCode.OK);
        }

        /// <summary>
        ///   Remove video item.
        /// </summary>
        /// <param name="id"> Id of video item. </param>
        /// <param name="permanently"> Status for delteting video from file system. </param>
        /// <returns> </returns>
        [HttpGet]
        public HttpResponseMessage Remove(Guid id, bool permanently = false)
        {
            VideoItem video = _videoService.GetById(id);
            if (video.Extension == "youtube")
            {
                _videoService.Delete(video.GuidID);
            }
            else
            {
                try
                {
                    _videoService.Delete(_videoService.GetById(id), permanently);
                }
                catch (IOException e)
                {
                    return Request.CreateResponse(HttpStatusCode.InternalServerError, new {Error = true});
                }
            }

            return Request.CreateResponse(HttpStatusCode.OK);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="q"></param>
        /// <returns></returns>
        [HttpGet]
        public HttpResponseMessage SearchYoutTube(string q)
        {
            var provider = new YouTubeProvider();
            IEnumerable<VideoItem> result = provider.Search(new YouTubeQuery {Query = q});

            return Request.CreateResponse(HttpStatusCode.OK, result);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public HttpResponseMessage Settings()
        {
            VideoSettings settings = _videoService.Settings;
            VideoSettingsModel model = Mapper.Map<VideoSettings, VideoSettingsModel>(settings);
            return Request.CreateResponse(HttpStatusCode.OK, model);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public HttpResponseMessage Settings(VideoSettingsInput model)
        {
            VideoSettings settings = _videoService.Settings;
            Mapper.Map(model, settings);
            _videoService.Settings.Save();
            VideoSettingsModel response = Mapper.Map<VideoSettings, VideoSettingsModel>(settings);
            return Request.CreateResponse(HttpStatusCode.OK, response);
        }

        [HttpGet]
        public HttpResponseMessage RemoveSettings()
        {
            _videoService.Settings.Delete();
            return Request.CreateResponse(HttpStatusCode.OK);
        }
    }
}