using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Nop.Core.Domain.Blogs;
using Nop.Core.Domain.BlogsB2C;
using Nop.Core.Infrastructure;
using Nop.Services.Blogs;
using Nop.Services.Events;
using Nop.Services.Localization;
using Nop.Services.Logging;
using Nop.Services.Messages;
using Nop.Services.Security;
using Nop.Services.Seo;
using Nop.Services.Stores;
using Nop.Web.Areas.Admin.Factories;
using Nop.Web.Areas.Admin.Infrastructure.Mapper.Extensions;
using Nop.Web.Areas.Admin.Models.Blogs;
using Nop.Web.Framework.Mvc;
using Nop.Web.Framework.Mvc.Filters;
using Nop.Web.Models.Media;

namespace Nop.Web.Areas.Admin.Controllers
{
    public class BlogB2CController : BlogController
    {
        #region Fields

        private readonly IBlogModelFactory _blogModelFactory;
        private readonly IBlogService _blogService;
        private readonly ICustomerActivityService _customerActivityService;
        private readonly IEventPublisher _eventPublisher;
        private readonly ILocalizationService _localizationService;
        private readonly IBlogsB2CService _blogsB2CService;
        private readonly INotificationService _notificationService;
        private readonly IPermissionService _permissionService;
        private readonly IStoreMappingService _storeMappingService;
        private readonly IStoreService _storeService;
        private readonly IUrlRecordService _urlRecordService;

        #endregion

        #region Ctor

        public BlogB2CController(IBlogModelFactory blogModelFactory,
            IBlogService blogService,
            ICustomerActivityService customerActivityService,
            IEventPublisher eventPublisher,
            ILocalizationService localizationService,
            INotificationService notificationService,
            IPermissionService permissionService,
            IStoreMappingService storeMappingService,
            IStoreService storeService,
            IUrlRecordService urlRecordService) : base(blogModelFactory,
            blogService,
            customerActivityService,
            eventPublisher,
            localizationService,
            notificationService,
            permissionService,
            storeMappingService,
            storeService,
            urlRecordService)
        {
            _blogModelFactory = blogModelFactory;
            _blogService = blogService;
            _blogsB2CService = EngineContext.Current.Resolve<IBlogsB2CService>();
            _customerActivityService = customerActivityService;
            _eventPublisher = eventPublisher;
            _localizationService = localizationService;
            _notificationService = notificationService;
            _permissionService = permissionService;
            _storeMappingService = storeMappingService;
            _storeService = storeService;
            _urlRecordService = urlRecordService;
        }

        #endregion

        public override IActionResult BlogPostCreate()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBlog))
                return AccessDeniedView();

            //prepare model
            var model = _blogModelFactory.PrepareBlogPostModel(new BlogPostModel(), null);

            return View(model);
        }

        [HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")]
        public override IActionResult BlogPostCreate(BlogPostModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBlog))
                return AccessDeniedView();

            if (ModelState.IsValid)
            {
                var blogPost = model.ToEntity<BlogPost>();
                blogPost.CreatedOnUtc = DateTime.UtcNow;
                _blogService.InsertBlogPost(blogPost);

                //activity log
                _customerActivityService.InsertActivity("AddNewBlogPost",
                    string.Format(_localizationService.GetResource("ActivityLog.AddNewBlogPost"), blogPost.Id), blogPost);

                //search engine name
                var seName = _urlRecordService.ValidateSeName(blogPost, model.SeName, model.Title, true);
                _urlRecordService.SaveSlug(blogPost, seName, blogPost.LanguageId);

                //Stores
                SaveStoreMappings(blogPost, model);

                var blogPostB2C = new BlogPostPictureB2C
                {
                    PictureId = model.PictureId,
                    BlogPostId = blogPost.Id
                };

                _blogsB2CService.InsertBlogPostPicture(blogPostB2C);

                _notificationService.SuccessNotification(_localizationService.GetResource("Admin.ContentManagement.Blog.BlogPosts.Added"));

                if (!continueEditing)
                    return RedirectToAction("BlogPosts");

                return RedirectToAction("BlogPostEdit", new { id = blogPost.Id });
            }

            //prepare model
            model = _blogModelFactory.PrepareBlogPostModel(model, null, true);

            //if we got this far, something failed, redisplay form
            return View(model);
        }

        public override IActionResult BlogPostEdit(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBlog))
                return AccessDeniedView();

            //try to get a blog post with the specified id
            var blogPost = _blogService.GetBlogPostById(id);
            if (blogPost == null)
                return RedirectToAction("BlogPosts");

            //prepare model
            var model = _blogModelFactory.PrepareBlogPostModel(null, blogPost);
            var blogPostPicture = _blogsB2CService.GetBlogPostPictureById(blogPost.Id);
            model.PictureId = blogPostPicture == null ? 0 : blogPostPicture.PictureId;

            return View(model);
        }

        [HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")]
        public override IActionResult BlogPostEdit(BlogPostModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBlog))
                return AccessDeniedView();

            //try to get a blog post with the specified id
            var blogPost = _blogService.GetBlogPostById(model.Id);
            if (blogPost == null)
                return RedirectToAction("BlogPosts");

            if (ModelState.IsValid)
            {
                blogPost = model.ToEntity(blogPost);
                _blogService.UpdateBlogPost(blogPost);

                //activity log
                _customerActivityService.InsertActivity("EditBlogPost",
                    string.Format(_localizationService.GetResource("ActivityLog.EditBlogPost"), blogPost.Id), blogPost);

                //search engine name
                var seName = _urlRecordService.ValidateSeName(blogPost, model.SeName, model.Title, true);
                _urlRecordService.SaveSlug(blogPost, seName, blogPost.LanguageId);

                //Stores
                SaveStoreMappings(blogPost, model);

                var blogPostB2C = new BlogPostPictureB2C
                {
                    PictureId = model.PictureId,
                    BlogPostId = model.Id
                };

                _blogsB2CService.UpdateBlogPostPicture(blogPostB2C);

                _notificationService.SuccessNotification(_localizationService.GetResource("Admin.ContentManagement.Blog.BlogPosts.Updated"));

                if (!continueEditing)
                    return RedirectToAction("BlogPosts");

                return RedirectToAction("BlogPostEdit", new { id = blogPost.Id });
            }

            //prepare model
            model = _blogModelFactory.PrepareBlogPostModel(model, blogPost, true);

            //if we got this far, something failed, redisplay form
            return View(model);
        }

        [HttpPost]
        public override IActionResult Delete(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBlog))
                return AccessDeniedView();

            //try to get a blog post with the specified id
            var blogPost = _blogService.GetBlogPostById(id);
            if (blogPost == null)
                return RedirectToAction("BlogPosts");

            var blogPostPicture = _blogsB2CService.GetBlogPostPictureById(id);
            _blogsB2CService.DeleteBlogPostPicture(blogPostPicture);
            _blogService.DeleteBlogPost(blogPost);

            //activity log
            _customerActivityService.InsertActivity("DeleteBlogPost",
                string.Format(_localizationService.GetResource("ActivityLog.DeleteBlogPost"), blogPost.Id), blogPost);

            _notificationService.SuccessNotification(_localizationService.GetResource("Admin.ContentManagement.Blog.BlogPosts.Deleted"));

            return RedirectToAction("BlogPosts");
        }
    }
}