using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using AutoMapper;
using Qusion.Cms.Classifications;
using Qusion.Cms.Classifications.Core;
using Qusion.Cms.Core.Domain;
using Qusion.Cms.Core.Exceptions;
using Qusion.Cms.Media.Core;
using Qusion.Cms.Modules.Articles;
using Qusion.Cms.Modules.Articles.Core;
using Qusion.Cms.Web.Http;
using Qusion.WebApp.Areas.Qusion.Filters;
using Qusion.WebApp.Areas.Qusion.Models.Articles;
using Qusion.WebApp.Areas.Qusion.Models.Classifications;
using Qusion.WebApp.Areas.Qusion.Models.Karte;
using Qusion.Cms.Modules.Karte.Core;
using Qusion.Framework.Queries;
using System.Threading;
using Qusion.Framework.Configuration;
using System.Web;
using System.Globalization;
using Qusion.WebApp.Areas.Qusion.Helpers;
using Qusion.Cms.Notifications;
using Qusion.Cms.Users.Domain;
using Qusion.Cms.Modules.Newsletters.Core;
using Qusion.Cms.Modules.Newsletters.Domain;
using Qusion.WebApp.Areas.Qusion.Mailers.News;




namespace Qusion.WebApp.Areas.Qusion.Controllers.Api
{
    [Authorize]
    public class ArticleController : ApiController
    {
        private readonly ArticleService _articleService;
        private readonly ClassificationService _classificationService;
        private readonly ImageService _imageService;
        private readonly DocumentService _documentService;
        private readonly LabelService _labelService;
        private readonly LibraryService _libraryService;
        private readonly NewsletterService _newsletterService;
        private readonly KartaService _kartaService;
        public ArticleController(ArticleService articleService, ImageService imageService,
                                 ClassificationService classificationService, LabelService labelService, LibraryService libraryService, DocumentService documentService, NewsletterService newsletterService, KartaService kartaService)
        {
            _articleService = articleService;
            _imageService = imageService;
            _documentService = documentService;
            _classificationService = classificationService;
            _labelService = labelService;
            _libraryService = libraryService;
            _newsletterService = newsletterService;
            _kartaService = kartaService;
        }

        /// <summary>
        ///   Queries all articles.
        /// </summary>
        /// <param name="input"> </param>
        /// <returns> </returns>
        [HttpGet]
        public PageResult<ArticleListModel> Query([FromUri] ArticleQueryInput input)
        {
            
                ArticleQuery query = Mapper.Map(input, ArticleQuery.Default) ?? ArticleQuery.Default;
                IEnumerable<Article> articles = _articleService.Search(query);
                var a = articles.ToList().Where(x => x.Title != null);
                IList<ArticleListModel> model = Mapper.Map<IList<Article>, IList<ArticleListModel>>(a.ToList());

                return new PageResult<ArticleListModel>
                           {
                               Items = model,
                               Count = query.Paging.TotalCount
                           };
            

        }

        [HttpGet]
        public ArticleModel Get(Guid id)
        {
           
                Article article = _articleService.GetById(id);
                ArticleModel mapped = Mapper.Map<Article, ArticleModel>(article);
                if (article.Thumb != null)
                {
                    mapped.Thumb = new[] { article.Thumb.GuidID.ToString() };
                }

                if (article.Library != null)
                {
                    mapped.Library = new[] { article.Library.GuidID.ToString() };
                }

                if (article.Document != null)
                {
                    mapped.Document = new[] { article.Document.GuidID.ToString() };
                }

                if (article.LibraryDocument != null)
                {
                    mapped.LibraryDocument = new[] { article.LibraryDocument.GuidID.ToString() };
                }
                if (article.Karta != null)
                {
                    mapped.Karta = new[] { article.Karta.GuidID.ToString() };
                }
                return mapped;

            

        }

        [HttpGet]
        public ArticleModel GetShare(Guid id)
        {
          Article article = _articleService.GetById(id);
                ArticleModel mapped = Mapper.Map<Article, ArticleModel>(article);
                if (article.Thumb != null)
                {
                    mapped.Thumb = new[] { article.Thumb.GuidID.ToString() };
                }

                if (article.Library != null)
                {
                    mapped.Library = new[] { article.Library.GuidID.ToString() };
                }

                if (article.Document != null)
                {
                    mapped.Document = new[] { article.Document.GuidID.ToString() };
                }

                if (article.LibraryDocument != null)
                {
                    mapped.LibraryDocument = new[] { article.LibraryDocument.GuidID.ToString() };
                }
                if (article.Karta != null)
                {
                    mapped.Karta = new[] { article.Karta.GuidID.ToString() };
                }
                return mapped;

        }

        [HttpPost]
        [ModelValidationFilter]
        [Authorize(Roles = "Administrator,Administrators,Radnik")]
        public HttpResponseMessage Create(ArticleCreateInput article)
        {
            var newArticle = new Article
            {
                Status = WorkflowStatus.Draft,
                PublishedOn = DateTime.Now
            };
            try
            {
                newArticle.Alias = _articleService.GenerateAlias(String.IsNullOrEmpty(article.Alias) ? article.Title : article.Alias);
            }
            catch (AliasException e)
            {
                var errors = new Dictionary<string, string[]>();
                errors.Add("article.Alias", new string[] { "utility.InvalidAlias" });
                return Request.CreateResponse(HttpStatusCode.OK, new { Errors = errors });
            }

            Mapper.Map(article, newArticle);
            if (article.Labels != null)
            {
                foreach (string labelIds in article.Labels)
                {
                    Label addlabel = _labelService.GetById(new Guid(labelIds));
                    newArticle.Labels.Add(addlabel);
                }


            }

            if (article.Thumb != null && article.Thumb.Length > 0)
                newArticle.Thumb = _imageService.GetById(new Guid(article.Thumb[0]));

            if (article.Library != null && article.Library.Length > 0)
                newArticle.Library = _libraryService.GetById(new Guid(article.Library[0]));

            if (article.LibraryDocument != null && article.LibraryDocument.Length > 0)
                newArticle.LibraryDocument = _libraryService.GetById(new Guid(article.LibraryDocument[0]));

            if (article.Document != null && article.Document.Length > 0)
                newArticle.Document = _documentService.GetById(new Guid(article.Document[0]));

            if (article.Karta != null && article.Karta.Length > 0)
                newArticle.Karta = _kartaService.GetById(new Guid(article.Karta[0]));

            if (String.IsNullOrEmpty(article.Author))
                newArticle.Author = User.Identity.Name;

            if (String.IsNullOrEmpty(article.Source))
                newArticle.Source = User.Identity.Name;

            if (article.Karta != null && article.Karta.Length > 0)
                newArticle.Karta = _kartaService.GetById(new Guid(article.Karta[0]));

            _articleService.Save(newArticle);
            IList<Newsletter> primaoci = _newsletterService.GetAll();
            foreach (Newsletter primaoc in primaoci)
            {
                var mail = new CreateNewArticleNotification
                {
                    Email = primaoc.Email.ToString(),
                    ArticleUrl = "www.laktasi.net/#!/articles/" + newArticle.ID,
                    Body = "Поштовани, објављена је нова вијест" + " " + "http://www.laktasi.net/#!/articles/" + newArticle.ID
                };
                new NewsMailer().CreateNotification(mail).Send();
            }
            return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<Article, ArticleModel>(newArticle));

        }

        [HttpGet]
        public ArticleModel GetEdit(Guid id)
        {
            Article article = _articleService.GetByIdForEditing(id);
            ArticleModel mapped = Mapper.Map<Article, ArticleModel>(article);
            if (article.Thumb != null)
            {
                mapped.Thumb = new[] { article.Thumb.GuidID.ToString() };
            }

            if (article.Library != null)
            {
                mapped.Library = new[] { article.Library.GuidID.ToString() };
            }

            if (article.Document != null)
            {
                mapped.Document = new[] { article.Document.GuidID.ToString() };
            }

            if (article.LibraryDocument != null)
            {
                mapped.LibraryDocument = new[] { article.LibraryDocument.GuidID.ToString() };
            }
            if (article.Karta != null)
            {
                mapped.Karta = new[] { article.Karta.GuidID.ToString() };
            }
            return mapped;
        }

        [HttpPost]
        [ModelValidationFilter]
        [Authorize(Roles = "Administrator,Administrators,Radnik")]
        public HttpResponseMessage Edit(ArticleEditInput article)
        {
            var newArticle = _articleService.GetById(article.Id);
            try
            {
                newArticle.Alias = _articleService.GenerateAlias(String.IsNullOrEmpty(article.Alias) ? article.Title : article.Alias);
            }
            catch (AliasException e)
            {
                var errors = new Dictionary<string, string[]>();
                errors.Add("article.Alias", new string[] { "utility.InvalidAlias" });
                return Request.CreateResponse(HttpStatusCode.OK, new { Errors = errors });
            }

            Mapper.Map(article, newArticle);
            newArticle.PublishedOn = article.PublishedOn;
            newArticle.ExpiresOn = article.ExpiresOn;
            if (article.Labels != null)
            {
                newArticle.Labels.Clear();
                foreach (string labelIds in article.Labels)
                    newArticle.Labels.Add(_labelService.GetById(new Guid(labelIds)));
            }

            if (article.Thumb != null && article.Thumb.Length > 0)
                newArticle.Thumb = _imageService.GetById(new Guid(article.Thumb[0]));

            if (article.Library != null && article.Library.Length > 0)
                newArticle.Library = _libraryService.GetById(new Guid(article.Library[0]));
            else
                newArticle.Library = null;

            if (article.LibraryDocument != null && article.LibraryDocument.Length > 0)
                newArticle.LibraryDocument = _libraryService.GetById(new Guid(article.LibraryDocument[0]));
            else
                newArticle.LibraryDocument = null;

            if (article.Document != null && article.Document.Length > 0)
                newArticle.Document = _documentService.GetById(new Guid(article.Document[0]));
            else
                newArticle.Document = null;

            if (article.Karta != null && article.Karta.Length > 0)
                newArticle.Karta = _kartaService.GetById(new Guid(article.Karta[0]));

            if (String.IsNullOrEmpty(article.Author))
                newArticle.Author = User.Identity.Name;

            if (String.IsNullOrEmpty(article.Source))
                newArticle.Source = User.Identity.Name;

            if (article.Karta != null && article.Karta.Length > 0)
                newArticle.Karta = _kartaService.GetById(new Guid(article.Karta[0]));

            _articleService.Save(newArticle);

            return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<Article, ArticleModel>(newArticle));

        }

        [HttpGet]
        public HttpResponseMessage Delete(Guid id)
        {
            Article article = _articleService.GetById(id);
            _articleService.Delete(article);
            return Request.CreateResponse(HttpStatusCode.OK);
        }

        [HttpGet]
        public HttpResponseMessage Settings()
        {
            ArticleSettings settings = _articleService.Settings;
            ArticleSettingsInput model = Mapper.Map<ArticleSettings, ArticleSettingsInput>(settings);

            model.ClassificationIds = settings.General.Classifications.Split(',');
            model.Classifications =
                Mapper.Map<IEnumerable<Classification>, IList<ClassificationSimpleModel>>(
                    _classificationService.GetAll().ToList());

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

        [HttpPost]
        public HttpResponseMessage Settings(ArticleSettingsInput model)
        {
            ArticleSettings settings = _articleService.Settings;
            // TODO: Ovdje moramo da napravimo generalni convertor za settings
            settings.General.PageSize = model.GeneralPageSize;
            //Mapper.Map(model, settings);

            _articleService.Settings.Save();
            model = Mapper.Map<ArticleSettings, ArticleSettingsInput>(settings);
            return Request.CreateResponse(HttpStatusCode.OK, model);
        }


    }
}