using AipGateway.AIP;
using AipGateway.API.Domain.IRepositories.IGenericRepositories;
using AipGateway.API.Domain.Models.Request;
using AipGateway.API.Domain.Models.Response;
using AutoMapper;
using Quartz.Util;

namespace AipGateway.API.Services.impl
{
    public class ApiFileService : IApiFileService
    {
        private readonly ILogger<ApiFileService> _log;
        private readonly IUnitOfWork _unitOfWork;
        private readonly IMapper _mapper;

        public ApiFileService(ILogger<ApiFileService> logger, IUnitOfWork unitOfWork, IMapper mapper)
        {
            _log = logger;
            _unitOfWork = unitOfWork;
            _mapper = mapper;
            _log.LogError("ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo: ApiFileService");
        }

        public async Task<ResponseInfo> GetInfo(RequestFile req)
        {
            try
            {
                string reqFileName = ContainerService.aipConfig.SourceFileDir + req.realFileName;
                if (!File.Exists(reqFileName))
                {
                    return new ResponseInfo
                    {
                        errorCode = 101,
                        errorMessage = "파일이 존재하지 않습니다.",
                    };
                }
                string? newFileExt = ContainerService.GetSupportedFileType(reqFileName);
                if (newFileExt == null)
                {
                    return new ResponseInfo
                    {
                        errorCode = 102,
                        errorMessage = "지원하지 않는 파일형식 입니다.",
                    };
                }
                var task = Task.Run(() =>
                {
                    var fileInfo = ContainerService.aipFileManager.GetFileInfo(reqFileName);
                    bool isLabled = false;
                    bool isProtected = false;
                    DateTime creationTime = DateTime.Now;
                    string contentId  = string.Empty;
                    string owner = string.Empty;
                    string labelId  = string.Empty;
                    string labelName  = string.Empty;
                    string templateId  = string.Empty;
                    string templateName  = string.Empty;
                    Int64 fileSize = 0;
                    if (fileInfo != null)
                    {
                        fileSize = fileInfo.FileSize;
                        if (fileInfo.Content != null)
                        {
                            creationTime = fileInfo.Content.CreationTime;
                        }
                        if (fileInfo.Label != null)
                        {
                            isLabled = true;
                            labelId = fileInfo.Label.Id;
                            labelName = fileInfo.Label.Name;
                        }
                        if (fileInfo.Protection != null)
                        {
                            owner = fileInfo.Protection.Owner;
                            contentId = fileInfo.Protection.ContentId;
                            if (fileInfo.Protection.ProtectionDescriptor != null)
                            {
                                isProtected = true;
                                templateId = fileInfo.Protection.ProtectionDescriptor.TemplateId;
                                templateName = fileInfo.Protection.ProtectionDescriptor.Name;
                            }
                        }
                    }
                    return new ResponseInfo
                    {
                        isLabled = isLabled,
                        isProtected = isProtected,
                        creationTime = creationTime,
                        contentId = contentId,
                        owner = owner,
                        labelId = labelId,
                        labelName = labelName,
                        templateId = templateId,
                        templateName = templateName,
                        dispFileName = req.dispFileName,

                        FileLabelGuid = labelId,
                        FileProtectionGuid = templateId,
                        FileOwner = owner,
                        FileExt = Path.GetExtension(req.dispFileName),
                        FileSize = fileSize,
                    };
                });
                ResponseInfo result = await task;
                return result;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public async Task<ResponseFile> SetLabel(RequestFileSet req)
        {
            try
            {
                string reqFileName = ContainerService.aipConfig.SourceFileDir + req.realFileName;
                if (!File.Exists(reqFileName))
                {
                    return new ResponseFile
                    {
                        errorCode = 101,
                        errorMessage = "파일이 존재하지 않습니다.",
                        dispFileName = req.dispFileName,
                    };
                }

                var task = Task.Run(() =>
                {
                    string fileExt = Path.GetExtension(reqFileName).ToLower();
                    string? newFileExt = ContainerService.GetSupportedFileType(reqFileName);
                    if (newFileExt == null)
                    {
                        return new ResponseFile
                        {
                            errorCode = 102,
                            errorMessage = "지원하지 않는 파일형식 입니다.",
                            dispFileName = req.dispFileName,
                        };
                    }
                    string dispFileName = Path.GetFileNameWithoutExtension(req.realFileName) + newFileExt;
                    string actualFileName = Path.Combine(ContainerService.aipConfig.TargetFileDir, dispFileName);
                    string comment = req.comment.IsNullOrWhiteSpace() ? "SetLabel" : req.comment;
                    SetFileInfo result = ContainerService.aipFileManager.SetLabel(reqFileName, actualFileName, req.email, req.aipGuid, "", comment);
                    return new ResponseFile
                    {
                        errorCode = result.errorNo,
                        errorMessage = result.errorMsg,
                        dispFileName = dispFileName,
                        outputFileName = Path.GetFileName(actualFileName),

                        FileOwner = result.fileOwner,
                        FileExt = fileExt,
                        FileSize = result.fileSize,
                        FileLabelGuid = result.lableGuid,
                        FileProtectionGuid = result.templateGuid,

                        NewFileName = dispFileName,
                        NewFileOwner = result.newFileOwner,
                        NewFileExt = newFileExt,
                        NewFileSize = result.newFileSize,
                        NewFileLabelGuid = result.newFileLabelGuid,
                        NewFileProtectionGuid = result.newFileTemplateGuid,
                    };
                });
                ResponseFile result = await task;
                return result;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public async Task<ResponseFile> DelLabel(RequestFileDel req)
        {
            try
            {
                string reqFileName = ContainerService.aipConfig.SourceFileDir + req.realFileName;
                if (!File.Exists(reqFileName))
                {
                    return new ResponseFile
                    {
                        errorCode = 101,
                        errorMessage = "파일이 존재하지 않습니다.",
                        dispFileName = req.dispFileName,
                    };
                }

                var task = Task.Run(() =>
                {
                    string fileExt = Path.GetExtension(reqFileName).ToLower();
                    string? newFileExt = ContainerService.GetSupportedFileType(reqFileName);
                    if (newFileExt == null)
                    {
                        return new ResponseFile
                        {
                            errorCode = 102,
                            errorMessage = "지원하지 않는 파일형식 입니다.",
                            dispFileName = req.dispFileName,
                        };
                    }
                    string dispFileName = Path.GetFileNameWithoutExtension(req.realFileName) + newFileExt;
                    string actualFileName = Path.Combine(ContainerService.aipConfig.TargetFileDir, dispFileName);
                    string comment = req.comment.IsNullOrWhiteSpace() ? "DelLabel" : req.comment;
                    SetFileInfo result = ContainerService.aipFileManager.DeleteLabel(reqFileName, actualFileName, req.email, comment);
                    return new ResponseFile
                    {
                        errorCode = result.errorNo,
                        errorMessage = result.errorMsg,
                        dispFileName = dispFileName,
                        outputFileName = Path.GetFileName(actualFileName),

                        FileOwner = result.fileOwner,
                        FileExt = fileExt,
                        FileSize = result.fileSize,
                        FileLabelGuid = result.lableGuid,
                        FileProtectionGuid = result.templateGuid,

                        NewFileName = dispFileName,
                        NewFileOwner = result.newFileOwner,
                        NewFileExt = newFileExt,
                        NewFileSize = result.newFileSize,
                        NewFileLabelGuid = result.newFileLabelGuid,
                        NewFileProtectionGuid = result.newFileTemplateGuid,
                    };
                });
                ResponseFile result = await task;
                return result;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public async Task<ResponseFile> SetProtection(RequestFileSet req)
        {
            try
            {
                string reqFileName = ContainerService.aipConfig.SourceFileDir + req.realFileName;
                if (!File.Exists(reqFileName))
                {
                    return new ResponseFile
                    {
                        errorCode = 101,
                        errorMessage = "파일이 존재하지 않습니다.",
                        dispFileName = req.dispFileName,
                    };
                }

                var task = Task.Run(() =>
                {
                    string fileExt = Path.GetExtension(reqFileName).ToLower();
                    string? newFileExt = ContainerService.GetSupportedFileType(reqFileName);
                    if (newFileExt == null)
                    {
                        return new ResponseFile
                        {
                            errorCode = 102,
                            errorMessage = "지원하지 않는 파일형식 입니다.",
                            dispFileName = req.dispFileName,
                        };
                    }
                    string dispFileName = Path.GetFileNameWithoutExtension(req.realFileName) + newFileExt;
                    string actualFileName = Path.Combine(ContainerService.aipConfig.TargetFileDir, dispFileName);
                    string comment = req.comment.IsNullOrWhiteSpace() ? "SetProtection" : req.comment;
                    SetFileInfo result = ContainerService.aipFileManager.SetProtection(reqFileName, actualFileName, req.email, req.aipGuid, comment);
                    return new ResponseFile
                    {
                        errorCode = result.errorNo,
                        errorMessage = result.errorMsg,
                        dispFileName = dispFileName,
                        outputFileName = Path.GetFileName(actualFileName),

                        FileOwner = result.fileOwner,
                        FileExt = fileExt,
                        FileSize = result.fileSize,
                        FileLabelGuid = result.lableGuid,
                        FileProtectionGuid = result.templateGuid,

                        NewFileName = dispFileName,
                        NewFileOwner = result.newFileOwner,
                        NewFileExt = newFileExt,
                        NewFileSize = result.newFileSize,
                        NewFileLabelGuid = result.newFileLabelGuid,
                        NewFileProtectionGuid = result.newFileTemplateGuid,
                    };
                });
                ResponseFile result = await task;
                return result;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public async Task<ResponseFile> DelProtection(RequestFileDel req)
        {
            try
            {
                string reqFileName = ContainerService.aipConfig.SourceFileDir + req.realFileName;
                if (!File.Exists(reqFileName))
                {
                    return new ResponseFile
                    {
                        errorCode = 101,
                        errorMessage = "파일이 존재하지 않습니다.",
                        dispFileName = req.dispFileName,
                    };
                }

                var task = Task.Run(() =>
                {
                    string fileExt = Path.GetExtension(reqFileName).ToLower();
                    string? newFileExt = ContainerService.GetSupportedFileType(reqFileName);
                    if (newFileExt == null)
                    {
                        return new ResponseFile
                        {
                            errorCode = 102,
                            errorMessage = "지원하지 않는 파일형식 입니다.",
                            dispFileName = req.dispFileName,
                        };
                    }
                    string dispFileName = Path.GetFileNameWithoutExtension(req.realFileName) + newFileExt;
                    string actualFileName = Path.Combine(ContainerService.aipConfig.TargetFileDir, dispFileName);
                    string comment = req.comment.IsNullOrWhiteSpace() ? "DelLabel" : req.comment;
                    SetFileInfo result = ContainerService.aipFileManager.DeleteLabel(reqFileName, actualFileName, req.email, comment);
                    return new ResponseFile
                    {
                        errorCode = result.errorNo,
                        errorMessage = result.errorMsg,
                        dispFileName = dispFileName,
                        outputFileName = Path.GetFileName(actualFileName),

                        FileOwner = result.fileOwner,
                        FileExt = fileExt,
                        FileSize = result.fileSize,
                        FileLabelGuid = result.lableGuid,
                        FileProtectionGuid = result.templateGuid,

                        NewFileName = dispFileName,
                        NewFileOwner = result.newFileOwner,
                        NewFileExt = newFileExt,
                        NewFileSize = result.newFileSize,
                        NewFileLabelGuid = result.newFileLabelGuid,
                        NewFileProtectionGuid = result.newFileTemplateGuid,
                    };
                });
                ResponseFile result = await task;
                return result;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public async Task<ResponseFile> SetLabelProtection(RequestFileAllSet req)
        {
            try
            {
                string reqFileName = ContainerService.aipConfig.SourceFileDir + req.realFileName;
                if (!File.Exists(reqFileName))
                {
                    return new ResponseFile
                    {
                        errorCode = 101,
                        errorMessage = "파일이 존재하지 않습니다.",
                        dispFileName = req.dispFileName,
                    };
                }

                var task = Task.Run(() =>
                {
                    string fileExt = Path.GetExtension(reqFileName).ToLower();
                    string? newFileExt = ContainerService.GetSupportedFileType(reqFileName);
                    if (newFileExt == null)
                    {
                        return new ResponseFile
                        {
                            errorCode = 102,
                            errorMessage = "지원하지 않는 파일형식 입니다.",
                            dispFileName = req.dispFileName,
                        };
                    }
                    string dispFileName = Path.GetFileNameWithoutExtension(req.realFileName) + newFileExt;
                    string actualFileName = Path.Combine(ContainerService.aipConfig.TargetFileDir, dispFileName);
                    string comment = req.comment.IsNullOrWhiteSpace() ? "SetLabel" : req.comment;
                    SetFileInfo result = ContainerService.aipFileManager.SetLabel(reqFileName, actualFileName, req.email, req.labelGuid, req.templateGuid, comment);
                    return new ResponseFile
                    {
                        errorCode = result.errorNo,
                        errorMessage = result.errorMsg,
                        dispFileName = dispFileName,
                        outputFileName = Path.GetFileName(actualFileName),

                        FileOwner = result.fileOwner,
                        FileExt = fileExt,
                        FileSize = result.fileSize,
                        FileLabelGuid = result.lableGuid,
                        FileProtectionGuid = result.templateGuid,

                        NewFileName = dispFileName,
                        NewFileOwner = result.newFileOwner,
                        NewFileExt = newFileExt,
                        NewFileSize = result.newFileSize,
                        NewFileLabelGuid = result.newFileLabelGuid,
                        NewFileProtectionGuid = result.newFileTemplateGuid,
                    };
                });
                ResponseFile result = await task;
                return result;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public async Task<ResponseFile> DelLabelProtection(RequestFileDel req)
        {
            try
            {
                string reqFileName = ContainerService.aipConfig.SourceFileDir + req.realFileName;
                if (!File.Exists(reqFileName))
                {
                    return new ResponseFile
                    {
                        errorCode = 101,
                        errorMessage = "파일이 존재하지 않습니다.",
                        dispFileName = req.dispFileName,
                    };
                }

                var task = Task.Run(() =>
                {
                    string fileExt = Path.GetExtension(reqFileName).ToLower();
                    string? newFileExt = ContainerService.GetSupportedFileType(reqFileName);
                    if (newFileExt == null)
                    {
                        return new ResponseFile
                        {
                            errorCode = 102,
                            errorMessage = "지원하지 않는 파일형식 입니다.",
                            dispFileName = req.dispFileName,
                        };
                    }
                    string dispFileName = Path.GetFileNameWithoutExtension(req.realFileName) + newFileExt;
                    string actualFileName = Path.Combine(ContainerService.aipConfig.TargetFileDir, dispFileName);
                    string comment = req.comment.IsNullOrWhiteSpace() ? "DelLabel" : req.comment;
                    SetFileInfo result = ContainerService.aipFileManager.DeleteLabel(reqFileName, actualFileName, req.email, comment, true);
                    return new ResponseFile
                    {
                        errorCode = result.errorNo,
                        errorMessage = result.errorMsg,
                        dispFileName = dispFileName,
                        outputFileName = Path.GetFileName(actualFileName),

                        FileOwner = result.fileOwner,
                        FileExt = fileExt,
                        FileSize = result.fileSize,
                        FileLabelGuid = result.lableGuid,
                        FileProtectionGuid = result.templateGuid,

                        NewFileName = dispFileName,
                        NewFileOwner = result.newFileOwner,
                        NewFileExt = newFileExt,
                        NewFileSize = result.newFileSize,
                        NewFileLabelGuid = result.newFileLabelGuid,
                        NewFileProtectionGuid = result.newFileTemplateGuid,

                    };
                });
                ResponseFile result = await task;
                return result;
            }
            catch (Exception)
            {
                throw;
            }
        }

    }
}
