using Microsoft.Extensions.Options; namespace Indotalent.Infrastructure.File; public class FileStorageService { private readonly FileStorageSettingsModel _settings; private readonly IWebHostEnvironment _environment; private readonly string[] _allowedAvatarExtensions = { ".jpg", ".jpeg", ".png" }; private readonly string[] _allowedDocExtensions = { ".pdf", ".xls", ".xlsx", ".doc", ".docx", ".txt" }; public FileStorageService(IOptions options, IWebHostEnvironment environment) { _settings = options.Value; _environment = environment; } public FileStorageSettingsModel GetConfiguration() => _settings; private string GetPhysicalPath(string subFolder) { return Path.Combine(_environment.ContentRootPath, "wwwroot", subFolder); } public async Task SaveAvatarAsync(string userId, byte[] fileData, string extension) { var avatarSettings = _settings.Avatar; if (!avatarSettings.IsUsed) throw new Exception("Avatar storage is disabled."); var ext = extension.ToLower(); if (!_allowedAvatarExtensions.Contains(ext)) throw new Exception("Invalid image type. Only JPG, JPEG, and PNG are allowed."); var folderPath = GetPhysicalPath(avatarSettings.StoragePath); if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } var fileName = $"{Guid.NewGuid()}{ext}"; var filePath = Path.Combine(folderPath, fileName); await System.IO.File.WriteAllBytesAsync(filePath, fileData); return fileName; } public void DeleteOldAvatar(string? fileName) { if (string.IsNullOrEmpty(fileName)) return; try { var folderPath = GetPhysicalPath(_settings.Avatar.StoragePath); var filePath = Path.Combine(folderPath, fileName); if (System.IO.File.Exists(filePath)) { System.IO.File.Delete(filePath); } } catch { } } public async Task SaveFileAsync(byte[] fileData, string extension) { var localSettings = _settings.Local; if (!localSettings.IsUsed) throw new Exception("Local file storage is disabled."); var ext = extension.ToLower(); if (!_allowedDocExtensions.Contains(ext)) throw new Exception($"File type {ext} is not allowed."); var folderPath = GetPhysicalPath(localSettings.StoragePath); if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } var fileName = $"{Guid.NewGuid()}{ext}"; var filePath = Path.Combine(folderPath, fileName); await System.IO.File.WriteAllBytesAsync(filePath, fileData); return fileName; } public void DeleteFile(string? fileName) { if (string.IsNullOrEmpty(fileName)) return; try { var folderPath = GetPhysicalPath(_settings.Local.StoragePath); var filePath = Path.Combine(folderPath, fileName); if (System.IO.File.Exists(filePath)) { System.IO.File.Delete(filePath); } } catch { } } }