using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.FileProviders.Physical;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace IRaCIS.Core.API
{


    public class MultiDiskStaticFilesMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IWebHostEnvironment _hostingEnv;
        private readonly ILoggerFactory _loggerFactory;

        private string iRaCISDefaultDataFolder = string.Empty;

        public MultiDiskStaticFilesMiddleware(RequestDelegate next, IWebHostEnvironment hostingEnv, ILoggerFactory loggerFactory)
        {
            _next = next;
            _hostingEnv = hostingEnv;
            _loggerFactory = loggerFactory;

            iRaCISDefaultDataFolder = FileStoreHelper.GetIRaCISRootDataFolder(_hostingEnv);

            if (!Directory.Exists(iRaCISDefaultDataFolder))
            {
                Directory.CreateDirectory(iRaCISDefaultDataFolder);
            }
        }

        public async Task Invoke(HttpContext context)
        {
            var path = context.Request.Path.Value;
            var isIRacisFile = path.StartsWith($"/{StaticData.Folder.IRaCISDataFolder}");

            var isDicomFile = isIRacisFile && path.Contains($"{StaticData.Folder.DicomFolder}");



            //先从默认里面去找
            if (isIRacisFile)
            {



                #region 方式二

                //var defaultFileProvider = new PhysicalFileProvider(iRaCISDefaultDataFolder);

                //var staticFileOptions = new StaticFileOptions
                //{
                //    FileProvider = defaultFileProvider,
                //    RequestPath = $"/{StaticData.Folder.IRaCISDataFolder}",
                //    ServeUnknownFileTypes = true,
                //    DefaultContentType = "application/octet-stream"
                //};

                //var a = defaultFileProvider.GetFileInfo(context.Request.Path).Exists;

                //var staticFileMiddleware = new StaticFileMiddleware(_next, _hostingEnv, Options.Create(staticFileOptions), _loggerFactory);
                //await staticFileMiddleware.Invoke(context);

                #endregion



                #region 文档上传默认会加wwwroot 奇怪...

                var defaultFileProvider = new PhysicalFileProvider(FileStoreHelper.GetIRaCISRootPath(_hostingEnv));

                if (defaultFileProvider.GetFileInfo(path).Exists)
                {

                    var actrualPath = defaultFileProvider.GetFileInfo(path).PhysicalPath;

                    await context.Response.SendFileAsync(new PhysicalFileInfo(new FileInfo(actrualPath)));

                    return;
                }
                #endregion

            }

            //没找到  
            //dicom影像,从多个文件夹尝试,因为会存在切换磁盘
            if (isDicomFile)
            {
                var defaultRoot = Path.GetPathRoot(iRaCISDefaultDataFolder);

                //除默认部署路径的其他路径
                var disks = DriveInfo.GetDrives()
                .Where(d => d.IsReady && d.DriveType == DriveType.Fixed)/*.Where(t => !t.Name.Contains("C") && !t.Name.Contains("c"))*/
                .OrderBy(d => d.AvailableFreeSpace)
                .Select(d => d.RootDirectory.FullName)
                .ToArray().Where(t => !t.Contains(defaultRoot));


                foreach (var item in disks)
                {
                    var otherFileStoreFolder = Path.Combine(item, _hostingEnv.EnvironmentName);

                    if (!Directory.Exists(otherFileStoreFolder))
                    {
                        continue;
                    }

                    var otherFileProvider = new PhysicalFileProvider(otherFileStoreFolder);



                    if (otherFileProvider.GetFileInfo(path).Exists)
                    {

                        var actrualPath = otherFileProvider.GetFileInfo(path).PhysicalPath;

                        //方式一
                        await context.Response.SendFileAsync(new PhysicalFileInfo(new FileInfo(actrualPath)));

                        #region 方式二  报错  otherFileProvider 应该还包含/{StaticData.Folder.IRaCISDataFolder} 这一层级
                        //var otherStaticFileOptions = new StaticFileOptions
                        //{
                        //    FileProvider = otherFileProvider,
                        //    RequestPath = $"/{StaticData.Folder.IRaCISDataFolder}",
                        //    ServeUnknownFileTypes = true,
                        //    DefaultContentType = "application/octet-stream"
                        //};
                        //var staticFileMiddleware = new StaticFileMiddleware(_next, _hostingEnv, Options.Create(otherStaticFileOptions), _loggerFactory);
                        //await staticFileMiddleware.Invoke(context);
                        #endregion



                        return;
                    }
                }

                // 如果没有找到文件,返回404
                context.Response.StatusCode = 404;
                context.Response.ContentType = "application/json";

                await context.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk("File not found")));
            }


            // 如果所有磁盘都不存在所请求的文件,则将请求传递给下一个中间件组件。
            await _next.Invoke(context);
        }






        //private static string GetContentType(string path)
        //{
        //    var provider = new FileExtensionContentTypeProvider();
        //    if (!provider.TryGetContentType(path, out var contentType))
        //    {
        //        contentType = "application/octet-stream";
        //    }

        //    return contentType;
        //}

        //private async Task ServeFileAsync(HttpContext context, IFileInfo fileInfo)
        //{
        //    var response = context.Response;
        //    response.ContentType = GetContentType(fileInfo.PhysicalPath);

        //    using (var fileStream = fileInfo.CreateReadStream())
        //    {
        //        await fileStream.CopyToAsync(response.Body);
        //    }
        //}
    }


}