using AutoMapper;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.StaticFiles;
using MTWorkHR.Application.Models;
using MTWorkHR.Application.Services.Interfaces;
using MTWorkHR.Core.Global;
using System.Net.Http.Headers;

namespace MTWorkHR.Application.Services
{
    public class FileService : IFileService
    {
        private readonly AppSettingsConfiguration settings;

        public FileService(AppSettingsConfiguration settings)
        {
            this.settings = settings;
        }
        public async Task<AttachmentResponseDto> UploadFile(IFormFile file)
        {
            var filesName = await UploadFiles(new List<IFormFile> { file });
            return  filesName.First() ;
        }

        public async Task< List<AttachmentResponseDto>> UploadFiles(List<IFormFile> files)
        {
            if (!AttachmentsMust(files))
                throw new AppException(ExceptionEnum.InvalidFileType);

            string pathToSave = GetActualAttachmentPath();
            if (!Directory.Exists(pathToSave))
                Directory.CreateDirectory(pathToSave);

            var fileNames = new List<AttachmentResponseDto>();
            foreach (var formFile in files)
            {
                var fname = ContentDispositionHeaderValue.Parse(formFile.ContentDisposition).FileName.Trim('"');
                var fnameSplit = fname.Split(".");
                var fNewName = Guid.NewGuid().ToString() + "." + fnameSplit[fnameSplit.Length - 1];
                var fullPath = Path.Combine(pathToSave, fNewName);
                fileNames.Add(new AttachmentResponseDto {FileName = fNewName, FilePath = fullPath });
                if (formFile.Length > 0)
                {
                    using (var stream = new FileStream(fullPath, FileMode.Create))
                    {
                        formFile.CopyToAsync(stream);
                    }
                }
                else
                    throw new AppException(ExceptionEnum.InCorrectFileLength);

            }
            return fileNames;
        }

        public async Task<Tuple<MemoryStream,string, string>> GetFileDownloadInfo(string fileUrl)
        {
            var filePath = Path.Combine(GetActualAttachmentPath(), fileUrl);
            if (!System.IO.File.Exists(filePath))
                throw new AppException(ExceptionEnum.RecordNotExist);
            var memory = new MemoryStream();
            await using (var stream = new FileStream(filePath, FileMode.Open))
            {
                await stream.CopyToAsync(memory);
            }
            memory.Position = 0;
            return new Tuple<MemoryStream, string, string>(memory, GetContentType(filePath), filePath);
        }

        private string GetContentType(string path)
        {
            var provider = new FileExtensionContentTypeProvider();
            string contentType;

            if (!provider.TryGetContentType(path, out contentType))
            {
                contentType = "application/octet-stream";
            }

            return contentType;
        }

        public async Task<bool> CopyFileToActualFolder(List<AttachmentDto> attachments)
        {
         
            foreach (var attachment in attachments)
            {
                var files = attachments.Select(a => a.FileData);
                foreach (var formFile in files)
                {
                    if (formFile.Length > 0)
                    {
                        var filePath = Path.Combine(GetTempAttachmentPath(), attachment.FileName);// Path.GetTempFileName();

                        using (var stream = System.IO.File.Create(filePath))
                        {
                            await formFile.CopyToAsync(stream);
                        }
                    }
                }

                if (!Directory.Exists(GetActualAttachmentPath()))
                    Directory.CreateDirectory(GetActualAttachmentPath());
                var tempFilePath = Path.Combine(GetTempAttachmentPath(), attachment.FileName);
                var destinationFilePath = Path.Combine(GetActualAttachmentPath(), attachment.FileName);
                if (File.Exists(tempFilePath))
                {
                    if (!File.Exists(destinationFilePath))
                        File.Copy(tempFilePath, destinationFilePath);
                }
                else
                    return false;
            }
            return true;
        }
        public bool CopyFileToActualFolder(string FileName)
        {
            if (!Directory.Exists(GetActualAttachmentPath()))
                Directory.CreateDirectory(GetActualAttachmentPath());
            var tempFilePath = Path.Combine(GetTempAttachmentPath(), FileName);
            var destinationFilePath = Path.Combine(GetActualAttachmentPath(), FileName);
            if (File.Exists(tempFilePath))
            {
                if (!File.Exists(destinationFilePath))
                    File.Copy(tempFilePath, destinationFilePath);
                return true;
            }
            return false;
        }

        public bool DeleteFileFromTempFolder(string FileName)
        {
            try
            {
                string pathToRemove = GetTempAttachmentPath();
                if (Directory.Exists(pathToRemove))
                {
                    var tempFilePath = Path.Combine(pathToRemove, FileName);
                    if (File.Exists(tempFilePath))
                    {
                        File.Delete(tempFilePath);
                    }
                }
            }
            catch (Exception ex) { }
            return true;
        }
        public string GetTempAttachmentPath()
        {
            var pathTemp = settings.AttachmentSettings.TempAttachment;

            return pathTemp;
        }
        public string GetActualAttachmentPath()
        {
            var pathActual = settings.AttachmentSettings.ActualAttachment ;

            return pathActual;
        }
       private bool AttachmentsMust(List<IFormFile> files)
        {
            // extensions whitelist
            string[] allowedExtensions = new string[]
            {
                ".jpeg"
                , ".jpg"
                , ".png"
                , ".pdf"
                , ".doc"
                , ".docx"
                , ".csv"
                , ".xls"
                , ".xlsx"
                , ".txt"
                , ".pptx"
                , ".svg"
                , ".webp"
            };

            // MIME types whitelist
            string[] allowedMIMETypes = new string[]
            {
                "image/jpeg"
                , "image/png"
                , "application/pdf"
                , "application/msword"
                , "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
                , "text/csv"
                , "application/vnd.ms-excel"
                , "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                , "text/plain"
                , "application/vnd.openxmlformats-officedocument.presentationml.presentation"
                , "image/svg+xml"
                , "image/webp"
            };

            foreach (IFormFile file in files)
            {
                if (!allowedExtensions.Contains(Path.GetExtension(file.FileName).ToLower()))
                    return false;

                if (!allowedMIMETypes.Contains(file.ContentType.ToLower()))
                    return false;
            }

            return true;
        }

        public void CopyFileToCloud(ref List<AttachmentDto> attachments)
        {
            throw new NotImplementedException();
        }

        public Task<BlobObject> Download(string url)
        {
            throw new NotImplementedException();
        }

        public Task<AttachmentResponseDto> UploadFile(byte[] pdfBytes, string fileName)
        {
            throw new NotImplementedException();
        }
    }
}
