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<FileStorageSettingsModel> 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<string> 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<string> 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 { }
    }
}