namespace Hims.Api.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;

    using Domain.Services;

    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;

    using Npgsql;

    using Shared.DataFilters;
    using Shared.EntityModels;
    using Shared.UserModels.Filters;

    using Utilities;

    using Hims.Api.Models.Icons;
    using Hims.Domain.Helpers;
    using Hims.Shared.Library.Enums;

    /// <inheritdoc />
    [Authorize]
    [Route("api/icons")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class IconsController : BaseController
    {
        /// <summary>
        /// The icon service.
        /// </summary>
        private readonly IIconService iconService;

        /// <summary>
        /// The document helper.
        /// </summary>
        private readonly IDocumentHelper documentHelper;

        /// <inheritdoc />
        public IconsController(IIconService iconService, IDocumentHelper documentHelper)
        {
            this.iconService = iconService;
            this.documentHelper = documentHelper;
        }

        /// <summary>
        /// The add icons async.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [AllowAnonymous]
        [Route("add-icons")]
        [Consumes("multipart/form-data")]
        [Produces("application/json")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(417)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> AddIconsAsync()
        {
            var files = this.Request.Form.Files;
            if (files.Count > 0)
            {
                var contentTypes = this.documentHelper.FetchContentTypes().ToList();

                if (!ListFilter.ContainsAll(contentTypes, files.Select(m => m.ContentType).Distinct()))
                {
                    return this.Failed($"Only {string.Join(", ", contentTypes)} files are allowed.");
                }

                foreach (var file in files)
                {
                    var fileName = $"I_{DateTime.Now:MM-dd-yyyy}_{file.FileName}";
                    var url = await this.documentHelper.UploadAttachmentsAsync(file, "vs", "Icons", fileName);
                    var fileUrl = $@"vs/{url}";
                    await this.iconService.AddIcons(new IconsModel { IconName = fileUrl });
                }

                return this.Success();
            }
            else
            {
                return this.BadRequest("Nothing to add.");
            }
        }

        /// <summary>
        /// The fetch icons async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("fetch-icons")]
        public async Task<ActionResult> FetchIconsAsync([FromBody] IconsRequestModel model)
        {
            model = (IconsRequestModel)EmptyFilter.Handler(model);
            var response = await this.iconService.FetchIcons(model.PageSize, model.PageIndex);
            foreach (var item in response)
            {
                if (item.Url != null)
                {
                    var substring = item.Url.Substring(0, 9);
                    if (substring == "vs/Icons/")
                    {
                        item.Url = item.Url.Substring(9);
                    }
                }
            }
            return this.Success(response);
        }

        /// <summary>
        /// The delete icons.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Route("delete")]
        public async Task<ActionResult> DeleteIcons([FromBody] IconsModel model)
        {
            model = (IconsModel)EmptyFilter.Handler(model);
            await this.documentHelper.DeleteAttachmentsAsync(model.IconName);
            var response = await this.iconService.DeleteIconsAsync(model.IconsId);
            return this.Success(response);
        }
    }
}