using CloudBuilder.AI.Data;
using CloudBuilder.AI.Entity;
using CloudBuilder.AI.Policy;
using CloudBuilder.AI.SearchCriteria;
using CloudBuilder.Core.DatabaseAccessor;
using CloudBuilder.Core.DatabaseAccessor.Entity;
using CloudBuilder.Core.Service;
using CloudBuilder.Security.Policy;
using CloudBuilder.Security.Service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
namespace CloudBuilder.AI.Service
{
    public class DmsFileService : IDmsFileService
    {
        private readonly IApplicationService service;
        private readonly IHttpContextAccessor httpContextAccessor;
        private IRepository<DmsFileEntity> repository;
        public DmsFileService(IApplicationService service, IHttpContextAccessor httpContextAccessor)
        {
            this.service = service;
            this.httpContextAccessor = httpContextAccessor;
            repository = service.GetRepository<IRepository<DmsFileEntity>>();
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Find)]
        public DmsFileEntity FindByKey(int key)
        {
            return repository.DetachedEntities.Where(x => x.FileId == key).FirstOrDefault()!;
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Find)]
        public DmsFileResultData FindBySearchCriteria(DmsFileSearchCriteria criteria)
        {
            DmsFileResultData data = new DmsFileResultData();
            BookDmsFileViewEntity[] list = null;

            int count = 0;

            string sqlWhere = null;

            if (criteria.Filter != null && criteria.Filter.Length > 0)
            {
                sqlWhere = SearchFilter.ComposeWhereClause(criteria.Filter);
            }

            sqlWhere = sqlWhere + string.Format(" and {0} ='{1}' ", BookDmsFileViewEntity.DB_CREATED_BY, service.UserId);

            BookDmsFileViewEntity entity = BookDmsFileViewEntity.GetInstance();
            string sql = entity.GetSelectTopFrom(criteria.limit, criteria.page, criteria.orderby.StringToDbField(), criteria.orderbytag, sqlWhere);

            IRepository<BookDmsFileViewEntity> repositoryView = repository.GetRepository<IRepository<BookDmsFileViewEntity>>();

            string err = null;
            try
            {
                list = repositoryView.FromSql(sql).ToArray();
            }
            catch (System.Exception ex)
            {
                err = ex.Message;
            }



            if (list != null && list.Length > 0)
            {
                //list = list.OrderByDescending(x => x.IsDirectoryIndc).ThenByDescending(x => x.CreatedDatetime).ToArray();
                sql = entity.GetSelectCountFrom(sqlWhere);
                count = (int)repository.ExecuteScalar(sql);

                var webRootPath = service.Configuration["FileServiceSettings:RequestPath"];
                var phy = service.Configuration["FileServiceSettings:PhysicalFileDirectory"];
                var scale = service.Configuration["FileServiceSettings:ScaleDmsFileDirectory"].Replace(phy, "");
                List<string> prvs = new List<string>();
                //bool isAttached = Debugger.IsAttached;
                foreach (var item in list)
                {
                    item.Url = FileTypePolicy.PackUrl(service, item.CreatedBy, item.OrderKey, item.TranscodeIndc);
                }

                data.Datas = list.Select(x => new BookDmsFileViewDisplayData(x)
                {
                    FormattedPic = FileTypePolicy.PackUrl(service, x.CreatedBy, x.OrderKey, YesNoPolicy.YES)
                }).ToArray();
            }

            data.Limit = criteria.limit;
            data.Page = criteria.page;

            data.Total = count;
            //data.Sql = sql;
            data.ErrorMessage = err;
            return data;
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Find)]
        public DmsFileResultData FindDatasBySearchCriteria(DmsFileSearchCriteria criteria)
        {
            DmsFileResultData data = new DmsFileResultData();
            BookDmsFileViewEntity[] list = null;

            int count = 0;

            string sqlWhere = null;

            if (criteria.Filter != null && criteria.Filter.Length > 0)
            {
                sqlWhere = SearchFilter.ComposeWhereClause(criteria.Filter);
            }

            sqlWhere = sqlWhere + string.Format(" and {0} ='{1}' and {2} ='{3}' ",
                BookDmsFileViewEntity.DB_CREATED_BY, service.UserId,
                BookDmsFileViewEntity.DB_IS_DIRECTORY_INDC, YesNoPolicy.NO
                );

            BookDmsFileViewEntity entity = BookDmsFileViewEntity.GetInstance();
            string sql = entity.GetSelectTopFrom(criteria.limit, criteria.page, criteria.orderby.StringToDbField(), criteria.orderbytag, sqlWhere);

            IRepository<BookDmsFileViewEntity> repositoryView = repository.GetRepository<IRepository<BookDmsFileViewEntity>>();

            string err = null;
            try
            {
                list = repositoryView.FromSql(sql).ToArray();
            }
            catch (System.Exception ex)
            {
                err = ex.Message;
            }



            if (list != null && list.Length > 0)
            {
                //list = list.OrderByDescending(x => x.IsDirectoryIndc).ThenByDescending(x => x.CreatedDatetime).ToArray();
                sql = entity.GetSelectCountFrom(sqlWhere);
                count = (int)repository.ExecuteScalar(sql);

                var webRootPath = service.Configuration["FileServiceSettings:RequestPath"];
                var phy = service.Configuration["FileServiceSettings:PhysicalFileDirectory"];
                var scale = service.Configuration["FileServiceSettings:ScaleDmsFileDirectory"].Replace(phy, "");
                List<string> prvs = new List<string>();
                //bool isAttached = Debugger.IsAttached;
                foreach (var item in list)
                {
                    item.Url = FileTypePolicy.PackUrl(service, item.CreatedBy, item.OrderKey, item.TranscodeIndc);
                }

                data.Datas = list.Select(x => new BookDmsFileViewDisplayData(x)
                {
                    FormattedPic = FileTypePolicy.PackUrl(service, x.CreatedBy, x.OrderKey, YesNoPolicy.YES)
                }).ToArray();
            }

            data.Limit = criteria.limit;
            data.Page = criteria.page;

            data.Total = count;
            //data.Sql = sql;
            data.ErrorMessage = err;
            return data;
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Print)]
        public dynamic PrintBySearchCriteria(DmsFileSearchCriteria criteria)
        {
            throw new NotImplementedException();
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Insert)]
        [UnitOfWork]
        public DmsFileEntity Insert(DmsFileEntity data)
        {
            throw new NotImplementedException();
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Update)]
        [UnitOfWork]
        public DmsFileEntity Update(DmsFileEntity data)
        {
            throw new NotImplementedException();
        }


        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Delete)]
        [UnitOfWork]
        public void Delete(int key)
        {
            DmsFileEntity dmsFile = repository.DetachedEntities.Where(x => x.FileId == key).FirstOrDefault()!;

            if (dmsFile == null) return;

            IRepository<BookDmsFileEntity> repositoryUpload = repository.GetRepository<IRepository<BookDmsFileEntity>>();
            IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
            IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();

            repository.DeleteNow(dmsFile);


            BookDmsFileEntity uploadDmsFile = repositoryUpload.DetachedEntities.Where(x => x.FileId == key).FirstOrDefault()!;


            if (uploadDmsFile != null)
            {
                repositoryUpload.DeleteNow(uploadDmsFile);
            }

            if (dmsFile.IsDirectoryIndc == YesNoPolicy.YES)
            {
                DmsFolderEntity folder = repositoryFolder.DetachedEntities.Where(x => x.FolderName == dmsFile.FileName).FirstOrDefault()!;

                if (folder == null) return;

                if (folder != null)
                {
                    repositoryFolder.DeleteNow(folder);
                }

                DmsFolderMapEntity[] folderMaps = repositoryFolderMap.DetachedEntities.Where(x => x.FolderNameSon == dmsFile.FileName || x.FolderNameParent == dmsFile.FileName).ToArray();

                if (folderMaps != null && folderMaps.Length > 0)
                {
                    foreach (var map in folderMaps)
                    {
                        repositoryFolderMap.DeleteNow(map);
                        if (map.FolderNameSon == folder.FolderName) continue;
                        //刪除dmsfoler下的所有內容
                        DeleteFolder(map.FolderNameSon);
                    }
                }


            }
            else
            {
                //删除文件与文件夹的映射关系
                DmsFolderMapEntity folderMap = repositoryFolderMap.DetachedEntities.Where(x => x.FolderNameSon == dmsFile.FileName).FirstOrDefault();
                if (folderMap != null)
                    repositoryFolderMap.DeleteNow(folderMap);
            }

        }


        public void DeleteFolder(string folderName)
        {
            DmsFileEntity[] dmsFiles = repository.DetachedEntities.Where(x => x.FileName == folderName).ToArray();
            if (dmsFiles == null || dmsFiles.Length == 0) return;
            foreach (var dmsFile in dmsFiles)
            {
                Delete(dmsFile.FileId);
            }
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Insert)]
        [UnitOfWork]
        public string GetFolderName(string folderLocalName)
        {
            IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
            DmsFolderEntity folder = repositoryFolder.DetachedEntities.Where(x => x.FolderLocalName == service.UserId).FirstOrDefault()!;

            if (folder != null) return folder.FolderName;

            DmsFileEntity dmsFile = new DmsFileEntity();
            dmsFile.FilePath = null;
            dmsFile.FileName = folderLocalName;

            return CreateDmsFolder(dmsFile);
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Insert)]
        [UnitOfWork]
        public string CreateDmsFolder(DmsFileEntity dmsFile)
        {
            IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
            ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
            DmsFolderEntity folder = null;
            string folderNameParent = dmsFile.FilePath;
            //父目录是空，创建顶级目录

            folder = repositoryFolder.DetachedEntities.Where(x => x.FolderLocalName == service.UserId).FirstOrDefault()!;
            if (folder == null)
            {
                folder = new DmsFolderEntity();
                folder.FolderName = securityGeneratorNumberService.GetNo(AIPrefixPolicy.DMS_FOLDER, AIPrefixPolicy.DMS_FOLDER_FOLDER_NAME, "DR", YesNoPolicy.NO, "00000000");
                folder.FolderLocalName = service.UserId;
                repositoryFolder.InsertNow(folder);
            }

            if (string.IsNullOrEmpty(dmsFile.FilePath))
            {
                folderNameParent = folder.FolderName;
            }

            //创建当前目录
            folder = new DmsFolderEntity();
            folder.FolderName = securityGeneratorNumberService.GetNo(AIPrefixPolicy.DMS_FOLDER, AIPrefixPolicy.DMS_FOLDER_FOLDER_NAME, "DR", YesNoPolicy.NO, "00000000");
            folder.FolderLocalName = dmsFile.FileName;
            repositoryFolder.InsertNow(folder);
            //创建目录关系表
            DmsFolderMapEntity map = new DmsFolderMapEntity();
            IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
            map.FolderNameParent = folderNameParent;
            map.FolderNameSon = folder.FolderName;
            repositoryFolderMap.InsertNow(map);

            //创建Dms目录
            DmsFileEntity entity = new DmsFileEntity();
            entity.OrderKey = entity.FileName = folder.FolderName;
            entity.OrgFileName = dmsFile.FileName;
            entity.AllowDeleteIndc = entity.AllowRenameIndc = entity.IsDirectoryIndc = YesNoPolicy.YES;

            entity.FilePath = folderNameParent;

            entity.OwerId = service.UserId;
            entity.IsLinkIndc = YesNoPolicy.NO;

            repository.InsertNow(entity);

            BookDmsFileEntity upload = new BookDmsFileEntity();
            upload.FileId = entity.FileId;
            upload.FileCategory = typeof(AiBookEntity).Name;
            upload.UploadName = securityGeneratorNumberService.GetNo(AIPrefixPolicy.BOOK_DMS_FILE, AIPrefixPolicy.BOOK_DMS_FILE_BOOK_NAME, "DR", YesNoPolicy.NO, AIPrefixPolicy.BOOK_DMS_FILE_FORMAT);
            upload.OrgFileName = entity.OrgFileName;

            IRepository<BookDmsFileEntity> repositoryUpload = repository.GetRepository<IRepository<BookDmsFileEntity>>();

            repositoryUpload.InsertNow(upload);

            return folder.FolderName;
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Update)]
        [UnitOfWork]
        public DmsFileEntity UpdateDmsFolder(DmsFileEntity dmsFile)
        {
            IRepository<BookDmsFileEntity> repositoryUpload = repository.GetRepository<IRepository<BookDmsFileEntity>>();

            BookDmsFileEntity upload = repositoryUpload.DetachedEntities.Where(x => x.FileId == dmsFile.FileId).FirstOrDefault()!;

            if (upload == null)
            {
                throw new ValidatedException("记录不存在.");
            }

            upload.OrgFileName = dmsFile.FileName;

            repositoryUpload.UpdateNow(upload);

            DmsFileEntity file = repository.DetachedEntities.Where(x => x.FileId == dmsFile.FileId).FirstOrDefault()!;
            //修改目录档对应的名称
            IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
            DmsFolderEntity dmsFolder = repositoryFolder.DetachedEntities.Where(x => x.FolderName == file.FileName).FirstOrDefault()!;

            if (dmsFolder == null) return dmsFile;
            dmsFolder.FolderLocalName = upload.OrgFileName;

            repositoryFolder.UpdateNow(dmsFolder);

            return dmsFile;
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Find)]
        public SelectOption[] FindDmsFolders()
        {
            IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
            //排除FamilyGroup创建的目录
            DmsFolderEntity[] ents = repositoryFolder.DetachedEntities.Where(x => x.FolderName.StartsWith("DR") && x.CreatedBy == service.UserId && x.FolderLocalName != service.UserId).ToArray();
            List<SelectOption> l = new List<SelectOption>();
            SelectOption selectOption;

            DmsFolderEntity my = repositoryFolder.DetachedEntities.Where(x => x.CreatedBy == service.UserId && x.FolderLocalName == service.UserId).FirstOrDefault()!;

            selectOption = new SelectOption();
            selectOption.BindValue = string.Empty;
            if (my == null)
            {
                selectOption.DisplayName = "我的网盘";
            }
            else
            {
                selectOption.DisplayName = "所有文件(夹)";
            }

            l.Add(selectOption);

            if (my != null)
            {
                selectOption = new SelectOption();
                selectOption.BindValue = my.FolderName;
                selectOption.DisplayName = "我的网盘";
                l.Add(selectOption);
            }

            if (ents == null || ents.Length == 0) return l.ToArray();

            foreach (DmsFolderEntity ent in ents)
            {
                selectOption = new SelectOption();
                selectOption.BindValue = ent.FolderName;
                selectOption.DisplayName = ent.FolderLocalName;
                l.Add(selectOption);
            }
            return l.ToArray();
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Find)]
        public DmsFolderTreeData FindDmsFolderTreeData()
        {
            DmsFolderTreeData data = new DmsFolderTreeData();

            IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
            DmsFolderEntity[] dmsFolders = repositoryFolder.DetachedEntities.Where(x => x.CreatedBy == service.UserId).ToArray();

            data.DmsFolders = dmsFolders;

            IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
            DmsFolderMapEntity[] dmsFolderMaps = repositoryFolderMap.DetachedEntities.Where(x => x.CreatedBy == service.UserId).ToArray();
            data.DmsFoldersMaps = dmsFolderMaps;

            return data;
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Update)]
        [UnitOfWork]
        public void MoveDmsFolder(DmsFileEntity dmsFile)
        {
            DmsFileEntity file = repository.DetachedEntities.Where(x => x.FileId == dmsFile.FileId).FirstOrDefault()!;

            if (file == null) return;
            if (file.FilePath == dmsFile.FilePath) return;

            file.FilePath = dmsFile.FilePath;

            repository.UpdateNow(file);

            IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();

            DmsFolderMapEntity map = repositoryFolderMap.Entities.Where(x => x.FolderNameSon == file.FileName).FirstOrDefault()!;
            if (map == null) return;
            repositoryFolderMap.DeleteNow(map);

            map = new DmsFolderMapEntity();
            map.FolderNameSon = file.FileName;
            map.FolderNameParent = dmsFile.FilePath;
            repositoryFolderMap.InsertNow(map);
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Insert)]
        [UnitOfWork]
        public BookDmsFileViewEntity UploadFile()
        {
            //采用分片上传文件（以及后面分片下载）
            DmsFileEntity dmsFile = null;

            var files = httpContextAccessor.HttpContext.Request.Form.Files;

            var currentDate = DateTime.Now;
            if (files.Any())
            {
                foreach (var file in files)
                {
                    string folderName = null;
                    if (httpContextAccessor.HttpContext.Request.Headers.ContainsKey("FilePath"))
                        folderName = httpContextAccessor.HttpContext.Request.Headers["FilePath"].ToString();
                    dmsFile = PackUploadFile(file, folderName);
                    break;
                }
            }
            else
            {
                return null!;
            }

            if (dmsFile != null)
            {
                dmsFile = CreateDmsFile(dmsFile);
            }
            else
            {
                return null!;
            }

            IRepository<BookDmsFileViewEntity> repositoryUploadDmsFile = service.GetRepository<IRepository<BookDmsFileViewEntity>>();
            return repositoryUploadDmsFile.DetachedEntities.Where(x => x.FileId == dmsFile.FileId).FirstOrDefault()!;
        }

        public DmsFileEntity PackUploadFile(IFormFile file, string folderName)
        {
            var webRootPath = service.Configuration["FileServiceSettings:UploadDmsFileDirectory"];

            DmsFileEntity dmsFile = new DmsFileEntity();
            dmsFile.OrgFileName = file.Name.Replace(" ", "");

            dmsFile.FilePath = folderName;

            //文件后缀
            var fileExtension = Path.GetExtension(file.Name.Replace(" ", "")).ToLower();//获取文件格式，拓展名

            if (string.IsNullOrEmpty(fileExtension)) fileExtension = "ext";

            var filePath = $"\\{service.UserId}\\{fileExtension.Replace(".", "")}\\";

            //创建存储文件夹
            if (!Directory.Exists(webRootPath + filePath))
            {
                Directory.CreateDirectory(webRootPath + filePath);
            }

            //判断文件大小
            var fileSize = file.Length;

            if (fileSize > 1024 * 1024 * 100) //100M TODO:(1mb=1024X1024b)
            {
                return null;
            }

            //保存的文件名称
            string fullName = webRootPath + filePath + file.FileName;
            if (File.Exists(fullName)) File.Delete(fullName);

            //文件保存
            using (var fs = System.IO.File.Create(fullName))
            {
                file.CopyTo(fs);
                fs.Flush();
            }

            //FileName上传Uid:xxxx-1-1.xxx
            string[] fns = file.FileName.Split('-');
            //如果上传的不是最后一个分片，不写入表
            if (fns[fns.Length - 2] != fns[fns.Length - 1].Split('.')[0])
            {
                dmsFile = null;
                return null;
            }
            else
            {
                dmsFile.OrderKey = file.FileName;
                //只有單一文件，不需合并，只有超過1個才要合并
                if (fns[fns.Length - 1].Split('.')[0] == "1")
                {
                    dmsFile.OrderKey = file.FileName;
                    dmsFile.FileName = file.FileName;
                    dmsFile.FileSize = Convert.ToInt32(fileSize / 1024);

                    var backupRootPath = service.Configuration["FileServiceSettings:BackupDmsFileDirectory"];
                    string backupName = backupRootPath + filePath + dmsFile.FileName;

                    if (!Directory.Exists(backupRootPath + filePath))
                    {
                        Directory.CreateDirectory(backupRootPath + filePath);
                    }

                    if (File.Exists(backupName)) File.Delete(backupName);

                    File.Copy(fullName, backupName, true);

                    //生成缩略图
                    if (FileTypePolicy.GetType(fileExtension.ToLower()) == FileTypePolicy.PHOTO)
                    {
                        RunMyProcess(service.Configuration["CloudBuilder.Topshelf:Path"], PackParameters(dmsFile));
                    }
                }
                else
                {
                    List<byte[]> all = new List<byte[]>();
                    List<string> fileNames = new List<string>();
                    //文件分片从1开始
                    for (int i = 1; i <= Convert.ToInt32(fns[fns.Length - 1].Split('.')[0]); i++)
                    {
                        fns[fns.Length - 2] = i.ToString();
                        //FileName上传Uid:xxxx-<1>-1.xxx
                        fileNames.Add(webRootPath + filePath + fns.ToDelimiteredList('-'));
                    }

                    dmsFile.FileName = Path.GetFileName(fullName);// Path.GetFileNameWithoutExtension(fullName) + "_" + file.Name.Replace(" ", "");
                    var backupRootPath = service.Configuration["FileServiceSettings:BackupDmsFileDirectory"];
                    fullName = backupRootPath + filePath + dmsFile.FileName;

                    if (!Directory.Exists(backupRootPath + filePath))
                    {
                        Directory.CreateDirectory(backupRootPath + filePath);
                    }

                    if (File.Exists(fullName)) File.Delete(fullName);
                    using (FileStream outputFile = File.Create(fullName)) // 创建输出文件流
                    {
                        foreach (string fileName in fileNames)
                        {
                            byte[] buffer = File.ReadAllBytes(fileName); // 读取每个文件内容到字节数组

                            outputFile.Write(buffer, 0, buffer.Length); // 将字节数组写入输出文件流

                            dmsFile.FileSize += buffer.Length;
                        }

                        dmsFile.FileSize = Convert.ToInt32(dmsFile.FileSize / 1024);//kb
                    }
                    //task:ImageSharpTask uid:SYSTEM file_size:5351 file_name:vc-upload-1709274146458-2-11-11_DSC_6141.JPG order_key:vc-upload-1709257162571-2-6-6.JPG

                    //生成缩略图
                    if (FileTypePolicy.GetType(fullName.ToLower()) == FileTypePolicy.PHOTO)
                    {
                        RunMyProcess(service.Configuration["CloudBuilder.Topshelf:Path"], PackParameters(dmsFile));
                    }
                    else if (FileTypePolicy.GetType(fullName.ToLower()) == FileTypePolicy.VIDEO)
                    {
                        foreach (string fileName in fileNames)
                        {
                            if (File.Exists(fileName)) File.Delete(fileName);
                        }
                        string m3u8FilePath = webRootPath + $"\\{service.UserId}\\m3u8\\" + Path.GetFileNameWithoutExtension(dmsFile.OrderKey);
                        if (!Directory.Exists(m3u8FilePath))
                        {
                            Directory.CreateDirectory(m3u8FilePath);
                        }
                        //生成m3u8
                        TsToM3u8(dmsFile.OrderKey, fullName, m3u8FilePath + "\\main.m3u8");
                    }
                }
            }

            return dmsFile;
        }

        public string FindM3u8Path(int fileId)
        {
            DmsFileEntity entity = repository.DetachedEntities.Where(x => x.FileId == fileId && x.CreatedBy == service.UserId).FirstOrDefault()!;

            return FileTypePolicy.PackUrl(service, entity.CreatedBy, entity.OrderKey, entity.TranscodeIndc);
        }

        public string FindSourceVideoPath(int fileId)
        {
            DmsFileEntity entity = repository.DetachedEntities.Where(x => x.FileId == fileId && x.CreatedBy == service.UserId).FirstOrDefault()!;

            return FileTypePolicy.PackSourceVideoUrl(service, entity.CreatedBy, entity.OrderKey);
        }

        private string PackParameters(DmsFileEntity dmsFile)
        {
            List<string> para = new List<string>();
            para.Add("task:" + "ImageSharpTask");
            para.Add("uid:" + service.UserId);
            para.Add("file_size:" + dmsFile.FileSize);
            para.Add("file_name:" + dmsFile.FileName);
            para.Add("order_key:" + dmsFile.OrderKey);
            return para.ToArray().ToDelimiteredList(' ');
        }

        public void TsToM3u8(string orderKey, string mp4Url, string m3u8Url, int videoLength = 6)
        {
            //string para = string.Format(service.Configuration["Ffmpeg:Pictrue"], mp4Url, m3u8Url);
            //RunMyProcess(service.Configuration["Ffmpeg:Path"], para.Replace(".m3u8", ".png"));

            //para = string.Format(service.Configuration["Ffmpeg:Arguments"], mp4Url, videoLength, m3u8Url);
            ////不直接转码视频文件，影响服务器性能，改为在闭时自动生成
            ////Task.Run(() =>
            ////{
            ////    Thread.Sleep(200);
            ////    RunMyProcess(service.Configuration["Ffmpeg:Path"], para);
            ////});
            //IRepository<VideoToM3u8LogEntity> logRepository = repository.GetRepository<IRepository<VideoToM3u8LogEntity>>();
            //VideoToM3u8LogEntity log = new VideoToM3u8LogEntity();
            //log.VideoName = para;
            //log.FilePath = Path.GetDirectoryName(m3u8Url)!;
            //log.OrderKey = orderKey;
            //log.Status = "S";
            //logRepository.InsertNow(log);
        }

        /// <summary>
        /// 执行cmd指令(异步不等待，await要求等待返回，转码太耗时)
        /// </summary>
        /// <param name="Parameters"></param>
        public void RunMyProcess(string exePath, string Parameters)
        {
            //try
            //{
            //    if (string.IsNullOrEmpty(exePath)) return;
            //    Cli.Wrap(exePath)
            //   .WithArguments(Parameters)
            //   .ExecuteAsync();
            //}
            //catch (Exception ex)
            //{
            //    throw new ValidatedException(ex.Message);
            //}

        }

        public DmsFileEntity CreateDmsFile(DmsFileEntity dmsFile)
        {
            IRepository<DmsFolderEntity> repositoryFolder = repository.GetRepository<IRepository<DmsFolderEntity>>();
            ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService<ISecurityGeneratorNumberService>()!;
            DmsFolderEntity folder = null;
            string folderNameParent = dmsFile.FilePath;
            //父目录是空，创建顶级目录
            if (string.IsNullOrEmpty(dmsFile.FilePath))
            {
                folder = repositoryFolder.DetachedEntities.Where(x => x.FolderLocalName == service.UserId).FirstOrDefault()!;
                if (folder == null)
                {
                    folder = new DmsFolderEntity();
                    folder.FolderName = securityGeneratorNumberService.GetNo(AIPrefixPolicy.DMS_FOLDER, AIPrefixPolicy.DMS_FOLDER_FOLDER_NAME, null, YesNoPolicy.NO, "00000000");
                    folder.FolderLocalName = service.UserId;
                    repositoryFolder.InsertNow(folder);
                }
                folderNameParent = folder.FolderName;
            }

            BookDmsFileEntity upload = new BookDmsFileEntity();

            upload.FileCategory = typeof(AiBookEntity).Name;
            upload.UploadName = securityGeneratorNumberService.GetNo(AIPrefixPolicy.BOOK_DMS_FILE, AIPrefixPolicy.BOOK_DMS_FILE_BOOK_NAME, "FL", YesNoPolicy.NO, AIPrefixPolicy.BOOK_DMS_FILE_FORMAT);
            upload.OrgFileName = dmsFile.OrgFileName;

            //创建Dms文件
            DmsFileEntity entity = new DmsFileEntity();
            entity.OrderKey = dmsFile.OrderKey;
            entity.FileName = upload.UploadName;
            entity.FileType = FileTypePolicy.GetType(entity.OrderKey);
            entity.OrgFileName = dmsFile.FileName;
            entity.FileSize = dmsFile.FileSize;
            entity.AllowDeleteIndc = entity.AllowRenameIndc = YesNoPolicy.YES;
            entity.IsDirectoryIndc = YesNoPolicy.NO;

            entity.FilePath = folderNameParent;

            entity.OwerId = service.UserId;
            entity.IsLinkIndc = YesNoPolicy.NO;

            repository.InsertNow(entity);

            IRepository<BookDmsFileEntity> repositoryUpload = repository.GetRepository<IRepository<BookDmsFileEntity>>();
            upload.FileId = entity.FileId;
            repositoryUpload.InsertNow(upload);

            //创建目录关系表
            DmsFolderMapEntity map = new DmsFolderMapEntity();
            IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
            map.FolderNameParent = folderNameParent;
            map.FolderNameSon = entity.FileName;
            repositoryFolderMap.InsertNow(map);


            return entity;
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Find)]
        public dynamic DownloadFile(int fileId)
        {
            DmsFileEntity entity = repository.DetachedEntities.Where(x => x.FileId == fileId && x.CreatedBy == service.UserId).FirstOrDefault()!;

            if (entity == null) throw new ValidatedException("文件不存在.");

            var fileExtension = Path.GetExtension(entity.OrderKey);//获取文件格式，拓展名

            string path = FileTypePolicy.PackFilePath(service, entity.CreatedBy, entity.OrderKey);

            IRepository<BookDmsFileEntity> repositoryUpload = repository.GetRepository<IRepository<BookDmsFileEntity>>();
            BookDmsFileEntity uploadDmsFile = repositoryUpload.DetachedEntities.Where(x => x.FileId == fileId).FirstOrDefault()!;

            if (uploadDmsFile == null || !File.Exists(path)) throw new ValidatedException("文件不存在.");

            var stream = System.IO.File.OpenRead(path);

            string contentType = "application/octet-stream";

            switch (fileExtension.Replace(".", "").ToLower())
            {
                case "xls":
                case "xlt":
                case "xla":
                    contentType = "application/vnd.ms-excel";
                    break;
                case "xlsx":
                case "xltx":
                    contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                    break;
                case "doc":
                    contentType = "application/msword";
                    break;
                case "docx":
                    contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
                    break;
                case "txt":
                    contentType = "text/plain";
                    break;
                case "png":
                case "jpg":
                case "jpeg":
                case "gif":
                    contentType = "image/*";
                    break;
                case "mp4":
                case "mpg":
                case "mpeg":
                case "avi":
                    contentType = "video/*";
                    break;
                case "pdf":
                    contentType = "application/pdf";
                    break;
                default:
                    break;
            }

            return new FileStreamResult(stream, contentType) { FileDownloadName = uploadDmsFile.OrgFileName };
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Find)]
        public dynamic DownloadFilePreview(DmsFileEntity dmsFile)
        {
            var webRootPath = service.Configuration["FileServiceSettings:ScaleDmsFileDirectory"];

            var fileExtension = Path.GetExtension(dmsFile.OrderKey);//获取文件格式，拓展名

            var filePath = $"\\{dmsFile.CreatedBy}\\{fileExtension.Replace(".", "")}\\";

            string path = webRootPath + filePath + dmsFile.OrderKey;

            if (!File.Exists(path)) throw new ValidatedException("文件不存在.");

            var stream = System.IO.File.OpenRead(path);

            //string contentType = "image/*";
            string contentType = "application/octet-stream";

            return new FileStreamResult(stream, contentType) { FileDownloadName = dmsFile.OrderKey };

        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Find)]
        public dynamic DownloadFileCombine(string fileName)
        {
            var webRootPath = service.Configuration["FileServiceSettings:UploadDmsFileDirectory"];

            var fileExtension = Path.GetExtension(fileName);//获取文件格式，拓展名

            var filePath = $"\\{service.UserId}\\{fileExtension.Replace(".", "")}\\";

            string path = webRootPath + filePath + fileName;

            if (!File.Exists(path)) throw new ValidatedException("文件不存在.");

            var stream = System.IO.File.OpenRead(path);

            //string contentType = "image/*";
            string contentType = "application/octet-stream";

            return new FileStreamResult(stream, contentType) { FileDownloadName = fileName };
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Find)]
        public int FindDmsFolderMapByFolderName(string folderName)
        {
            IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();

            return repositoryFolderMap.DetachedEntities.Where(x => x.FolderNameSon == folderName).Count();
        }

        [PermissionOperate(name: AIPermissionPolicy.DmsFile, operate: Operate.Find)]
        public string FindFolderNameParentByFolderName(string folderName)
        {
            IRepository<DmsFolderMapEntity> repositoryFolderMap = repository.GetRepository<IRepository<DmsFolderMapEntity>>();
            if (repositoryFolderMap.DetachedEntities.Where(x => x.FolderNameSon == folderName).Count() == 0) return string.Empty;

            return repositoryFolderMap.DetachedEntities.Where(x => x.FolderNameSon == folderName).FirstOrDefault()!.FolderNameParent;
        }

    }
}
