using BrianMalingaPortfolio.ViewModels;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace BrianMalingaPortfolio.Controllers
{
    public class QualificationsController : Controller
    {
        private readonly IWebHostEnvironment _environment;

        private static readonly string[] AllowedExtensions =
        {
            ".pdf",
            ".doc",
            ".docx"
        };

        public QualificationsController(IWebHostEnvironment environment)
        {
            _environment = environment;
        }

        public IActionResult Index()
        {
            var model = new QualificationsViewModel
            {
                Categories = GetQualificationCategories()
            };

            return View("AllMyQualifications", model);
        }

        private List<QualificationCategoryViewModel> GetQualificationCategories()
        {
            string qualificationsFolder = Path.Combine(
                _environment.WebRootPath,
                "qualifications"
            );

            if (!Directory.Exists(qualificationsFolder))
            {
                Directory.CreateDirectory(qualificationsFolder);

                return new List<QualificationCategoryViewModel>();
            }

            return Directory
                .GetDirectories(qualificationsFolder)
                .Select(categoryFolder =>
                {
                    string folderName = Path.GetFileName(categoryFolder);

                    var documents = GetDocumentsFromCategory(
                        categoryFolder,
                        folderName
                    );

                    return new QualificationCategoryViewModel
                    {
                        Name = FormatCategoryName(folderName),
                        Documents = documents
                    };
                })
                .Where(category => category.Documents.Any())
                .OrderBy(category => category.Name)
                .ToList();
        }

        private List<QualificationDocumentViewModel> GetDocumentsFromCategory(
            string categoryFolder,
            string folderName)
        {
            return Directory
                .GetFiles(categoryFolder)
                .Where(file =>
                    AllowedExtensions.Contains(
                        Path.GetExtension(file),
                        StringComparer.OrdinalIgnoreCase
                    )
                )
                .Select(file =>
                {
                    string fileName = Path.GetFileName(file);

                    string displayName = FormatDocumentName(
                        Path.GetFileNameWithoutExtension(file)
                    );

                    string encodedFolderName = Uri.EscapeDataString(folderName);
                    string encodedFileName = Uri.EscapeDataString(fileName);

                    return new QualificationDocumentViewModel
                    {
                        Name = displayName,

                        Url = Url.Content(
                            $"~/qualifications/{encodedFolderName}/{encodedFileName}"
                        )
                    };
                })
                .OrderBy(document => document.Name)
                .ToList();
        }

        private static string FormatCategoryName(string folderName)
        {
            return folderName
                .Replace("-", " ")
                .Replace("_", " ")
                .Trim()
                .ToTitleCase();
        }

        private static string FormatDocumentName(string fileName)
        {
            return fileName
                .Replace("-", " ")
                .Replace("_", " ")
                .Trim();
        }
    }

    public static class StringExtensions
    {
        public static string ToTitleCase(this string value)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                return string.Empty;
            }

            return System.Globalization.CultureInfo
                .CurrentCulture
                .TextInfo
                .ToTitleCase(value.ToLower());
        }
    }
}