using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Web.Mvc;
using Qusion.Cms.Classifications.Core;
using Qusion.Cms.Media;
using Qusion.Cms.Media.Core;
using Qusion.Cms.Media.Documents;
using Qusion.Cms.Media.Extensions;
using Qusion.Framework.Extensions;
using Qusion.Framework.IO;
using Qusion.WebApp.Areas.Qusion.Models.Documents;
using Qusion.WebApp.Areas.Qusion.Models.Validation;

namespace Qusion.WebApp.Areas.Qusion.Controllers
{
    public class DocumentController : Controller
    {
        private readonly LibraryService _libraryService;
        private readonly LabelService _labelService;
        private readonly DocumentService _service;

        public DocumentController(DocumentService service, LibraryService libraryService, LabelService labelService)
        {
            _service = service;
            _libraryService = libraryService;
            _labelService = labelService;
        }

        public FileResult Download(Guid id)
        {
            DocumentItem document = _service.GetById(id);
            string dir = MediaService.GetCollectionPath(document.Library);
            string path = Path.Combine(dir, document.FilePath);

            return File(path, MimeType.GetMimeType(document.Extension), document.FileName);
        }

        /// <summary>
        /// Upload document in library.
        /// </summary>
        /// <param name="model">Model with properties.</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Upload(DocumentUploadModel model)
        {
            var errors = new List<ErrorModel>();
            if (model.File.ContentLength > _service.Settings.MaxAllowedSize)
                errors.Add(new ErrorModel { Key = "MaxSize", Value = "This file is larger then is allowed!" });

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

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

            if (isDocument == false)
            {
                errors.Add(new ErrorModel { Key = "NoDoc", Value = "This is not document!" });
            }

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

                    int count = 1;
                    string fileToUpload = System.IO.Path.Combine(library.Directory(), model.File.FileName);
                    string fileName = System.IO.Path.GetFileNameWithoutExtension(fileToUpload);
                    string extension = System.IO.Path.GetExtension(fileToUpload);
                    while (System.IO.File.Exists(fileToUpload))
                    {
                        string tempFileName = string.Format("{0}({1})", fileName, count++);
                        fileToUpload = System.IO.Path.Combine(library.Directory(), tempFileName + extension);
                    }
                    
                    model.File.SaveAs(fileToUpload);
                    if (extension == ".zip")
                    {
                        var fileExtended = ArchiveHelper.Extract(fileToUpload, library.Directory(), null, true);
                        foreach (var file in fileExtended)
                        {
                            string extExtension = Path.GetExtension(file);
                            string extFileName = Path.GetFileName(file);

                            var document = new DocumentItem
                            {
                                FileName = extFileName,
                                Title = model.File.FileName.TitleFromFileName(),
                                Extension = extExtension,
                                CreatedBy = User.Identity.Name,
                                Library = library,
                            };

                            foreach (string allowedExtension in allowedExtensions)
                            {

                                if (file.EndsWith(allowedExtension))
                                {
                                    isDocument = false;
                                    _service.Save(document);
                                }
                                
                            }
                            if (isDocument)
                            {
                                _service.DeleteDocument(document);
                                errors.Add(new ErrorModel {Key = "NoDoc", Value = "This is not document!"});
                                Response.StatusCode = (int) HttpStatusCode.UnsupportedMediaType.GetTypeCode();
                                return Json(errors);
                            }
                        }
                    }
                    else
                    {
                        var document = new DocumentItem
                        {
                            FileName = model.File.FileName,
                            Title = model.File.FileName.TitleFromFileName(),
                            Extension = Path.GetExtension(model.File.FileName),
                            CreatedBy = User.Identity.Name,
                            Library = library,
                        };

                        _service.Save(document);

                    }
                    
                }
                return Json(1);
            }
            Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType.GetTypeCode();
            return Json(errors);
        }

        /// <summary>
        /// Replace image file and change title
        /// </summary>
        /// <param name="model">Model with properties.</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Edit(DocumentEditModel model)
        {
            var errors = new List<ErrorModel>();
            if (model.File != null && model.File.ContentLength > _service.Settings.MaxAllowedSize)
                ModelState.AddModelError("MaxSize", "The image must be less than 3MB");

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

            if (errors.Count == 0)
            {
                DocumentItem document = _service.GetById(model.ID);
                document.Title = model.Title;

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

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

                    if (isDoc == false)
                    {
                        errors.Add(new ErrorModel { Key = "NoDoc", Value = "This is not document!" });
                        Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType.GetTypeCode();
                        return Json(errors);
                    }

                    _service.DeleteFile(document);
                    int count = 1;
                    string fileToUpload = Path.Combine(document.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(document.Library.Directory(), tempFileName + extension);
                    }

                    model.File.SaveAs(fileToUpload);

                    document.FileName = model.File.FileName;
                    document.Title = model.File.FileName.TitleFromFileName();
                    document.Extension = Path.GetExtension(model.File.FileName);

                }
                _service.Save(document);
                return Json(1);
            }
            Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType.GetTypeCode();
            return Json(errors);
        }
    }
}