using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Net;
using System.Web.Helpers;
using System.Web.Mvc;
using Qusion.Cms.Classifications.Core;
using Qusion.Cms.Media;
using Qusion.Cms.Media.Core;
using Qusion.Cms.Media.Extensions;
using Qusion.Cms.Media.Images;
using Qusion.Cms.Users.Core;
using Qusion.Cms.Users.Domain;
using Qusion.Framework.Extensions;
using Qusion.Framework.IO;
using Qusion.WebApp.Areas.Qusion.Models.Images;
using Qusion.WebApp.Areas.Qusion.Models.Users;
using System.Web.Services;
using Ranslant.JSON.Linq;
using System.Security.Policy;
using System.Linq;


namespace Qusion.WebApp.Areas.Qusion.Controllers
{
    public class ImageController : Controller
    {
        private readonly ImageService _imageService;
        private readonly LabelService _labelService;
        private readonly LibraryService _libraryService;
        private readonly UserService _userService;



        public ImageController(ImageService imageService, LibraryService libraryService, UserService userService,
                               LabelService labelService)
        {
            _imageService = imageService;
            _libraryService = libraryService;
            _userService = userService;
            _labelService = labelService;
        }

        public WebImage Thumb(Guid id, int? width)
        {
            return Photo(id, width ?? 150);
        }

        public WebImage Photo(Guid id, int width)
        {
            ImageItem image = _imageService.GetById(id);
            string path = _imageService.GetCachedImagePath(image, width);
            var webImage = new WebImage(path);
            WebImage model = webImage.Write();
            return model;
        }

        /// <summary>
        /// Upload image in library.
        /// </summary>
        /// <param name="model">Model with properties.</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Upload(ImageUploadModel model)
        {
            var errors = new Dictionary<string, string>();
            if (model.File.ContentLength > _imageService.Settings.MaxAllowedSize)
                errors.Add("MaxSize", "This file is larger then is allowed!");

            string[] allowedExtensions = _imageService.Settings.AllowedExtensions.Split(',');

            bool isImage = false;
            foreach (string allowedExtension in allowedExtensions)
            {
                if (model.File.FileName.ToLower().EndsWith(allowedExtension))
                    isImage = true;
            }

            if (isImage == false)
            {
                errors.Add("NoImage", "This is not image!");
            }

            if (errors.Count == 0)
            {
                if (model.File != null)
                {
                    Library library = _libraryService.GetById(model.LibraryID);

                    int count = 1;
                    string fileToUpload = Path.Combine(library.Directory(), model.File.FileName);
                    string fileName = Path.GetFileNameWithoutExtension(fileToUpload);
                    string extension = Path.GetExtension(fileToUpload);

                    while (System.IO.File.Exists(fileToUpload))
                    {
                        string tempFileName = string.Format("{0}({1})", fileName, count++);
                        fileToUpload = Path.Combine(library.Directory(), tempFileName + extension);
                    }


                    model.File.SaveAs(fileToUpload);

                    if (extension == ".zip")
                    {
                        IList<string> fileExtended = ArchiveHelper.Extract(fileToUpload, library.Directory(), null,
                                                                           true);
                        foreach (string file in fileExtended)
                        {
                            Image img = Image.FromFile(file);
                            var image = new ImageItem
                            {
                                FileName = Path.GetFileName(file),
                                Title = Path.GetFileName(file).TitleFromFileName(),
                                Extension = Path.GetExtension(file),
                                CreatedBy = User.Identity.Name,
                                Width = img.Width,
                                Height = img.Height,
                                Library = library,
                            };
                            _imageService.Save(image);
                        }
                    }
                    else
                    {
                        Image img = Image.FromStream(model.File.InputStream);

                        var image = new ImageItem
                        {
                            FileName = model.File.FileName,
                            Title = model.File.FileName.TitleFromFileName(),
                            Extension = Path.GetExtension(model.File.FileName),
                            CreatedBy = User.Identity.Name,
                            Width = img.Width,
                            Height = img.Height,
                            Library = library,
                        };
                        _imageService.Save(image);
                    }
                }
               WriteJson();
                return Json(1);
            }
            Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType.GetTypeCode();
            return Json(errors);
        }
     
        /// Replace image file and change title
        /// </summary>
        /// <param name="model">Model with properties.</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Edit(ImageEditModel model)
        {
            var errors = new Dictionary<string, string>();
            if (model.File != null && model.File.ContentLength > _imageService.Settings.MaxAllowedSize)
                errors.Add("MaxSize", "The image is larger than the allowed size.");

            string[] allowedExtensions = _imageService.Settings.AllowedExtensions.Split(',');

            if (errors.Count == 0)
            {
                ImageItem image = _imageService.GetById(model.ID);
                image.Title = model.Title;

                if (model.Labels != null)
                {
                    image.Labels.Clear();
                    foreach (string labelId in model.Labels)
                    {
                        image.Labels.Add(_labelService.GetById(new Guid(labelId)));
                    }
                }

                if (model.File != null)
                {
                    bool isImage = false;
                    foreach (string allowedExtension in allowedExtensions)
                    {
                        if (model.File.FileName.ToLower().EndsWith(allowedExtension))
                            isImage = true;
                    }

                    if (isImage == false)
                    {
                        errors.Add("NoImage", "This is not image!");
                        Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType.GetTypeCode();
                        return Json(errors);
                    }


                    _imageService.DeleteFile(image);
                    int count = 1;
                    string fileToUpload = Path.Combine(image.Library.Directory(), model.File.FileName);
                    string fileName = Path.GetFileNameWithoutExtension(fileToUpload);
                    string extension = Path.GetExtension(fileToUpload);

                    while (System.IO.File.Exists(fileToUpload))
                    {
                        string tempFileName = string.Format("{0}({1})", fileName, count++);
                        fileToUpload = Path.Combine(image.Library.Directory(), tempFileName + extension);
                    }

                    model.File.SaveAs(fileToUpload);
                    Image img = Image.FromStream(model.File.InputStream);

                    image.Width = img.Width;
                    image.Height = img.Height;
                    image.FileName = model.File.FileName;
                    image.Title = model.File.FileName.TitleFromFileName();
                    image.Extension = Path.GetExtension(model.File.FileName);

                    img.Dispose();
                }
                _imageService.Save(image);
                WriteJson();
                return Json(1);
            }
            Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType.GetTypeCode();
            return Json(errors);
        }


        /// <summary>
        /// Change user profile image.
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public ActionResult ChangePhoto(ProfileImageInput input)
        {
            User user = _userService.GetById(input.ID);
            var errors = new Dictionary<string, string>();
            if (user != null)
            {
                Library library = _libraryService.GetByTitleForUser(user.UserName);
                if (library == null)
                {
                    library = new Library
                    {
                        ApplicationName = "qusion/Users",
                        Title = user.UserName,
                        LibraryScope = LibraryScope.User,
                        Type = MediaType.eImage
                    };

                    _libraryService.Save(library);
                }

                if (input.Photo.ContentLength > _imageService.Settings.MaxAllowedSize)
                    errors.Add("MaxSize", "This file is larger then is allowed!");

                string[] allowedExtensions = _imageService.Settings.AllowedExtensions.Split(',');

                bool isImage = false;
                foreach (string allowedExtension in allowedExtensions)
                {
                    if (input.Photo.FileName.ToLower().EndsWith(allowedExtension))
                        isImage = true;
                }

                if (isImage == false)
                {
                    errors.Add("NoImage", "This is not image!");
                }

                if (errors.Count == 0)
                {
                    int count = 1;
                    string fileToUpload = Path.Combine(library.Directory(), input.Photo.FileName);
                    string fileName = Path.GetFileNameWithoutExtension(fileToUpload);
                    string extension = Path.GetExtension(fileToUpload);

                    while (System.IO.File.Exists(fileToUpload))
                    {
                        string tempFileName = string.Format("{0}({1})", fileName, count++);
                        fileToUpload = Path.Combine(library.Directory(), tempFileName + extension);
                    }

                    input.Photo.SaveAs(fileToUpload);
                    Image img = Image.FromStream(input.Photo.InputStream);
                    var image = new ImageItem
                    {
                        FileName = input.Photo.FileName,
                        Title = input.Photo.FileName.TitleFromFileName(),
                        Extension = Path.GetExtension(input.Photo.FileName),
                        CreatedBy = User.Identity.Name,
                        Width = img.Width,
                        Height = img.Height,
                        Library = library,
                    };
                    _imageService.Save(image);

                    user.Avatar = image;

                    _userService.Save(user);

                    return Json(new { AvatarID = image.ID });
                }
            }
            Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType.GetTypeCode();
            return Json(errors);
        }


       

        public JDocument WriteJson()
        {          
            string putanja = Server.MapPath(@"/Areas/Qusion/Scripts/App/images/json/data.json");
            if (putanja != null)
            {
              if (putanja.Length == 0)
                    return null;
                IEnumerable<ImageItem> images = _imageService.GetAll();

                JDocument doc = new JDocument();
                foreach (ImageItem ii in images)
                {
                    JObject jsonimage = new JObject(
                                     new JObjectMember("thumb", new JString("../../_content/_media/" + ii.Library.ID + "/" + ii.FileName)),
                                     new JObjectMember("image", new JString("../../_content/_media/" + ii.Library.ID + "/" + ii.FileName)),
                                     new JObjectMember("title", new JString(ii.Title)),
                                     new JObjectMember("folder", new JString(ii.Library.Title))
                     );

                    doc.Add(ii.GuidID.ToString(), jsonimage);
                }
                var url = Path.Combine(putanja);
                doc.Save(url);
                return doc;
            }
            return null;
        }
    }
}