namespace CMSMicroservice.Application.Common.FileManager;

/// <summary>
/// سرویس مدیریت فایل — ذخیره روی دیسک، مسیر نسبی در دیتابیس
/// موقع واکشی: خواندن از دیسک و تبدیل به base64 data-URI
/// </summary>
public interface IFileManager
{
    /// <summary>
    /// آپلود یک فایل خام به دیسک
    /// </summary>
    /// <returns>نتیجه آپلود شامل مسیر نسبی فایل</returns>
    /// <exception cref="FileUploadException">در صورت خطای آپلود</exception>
    Task<UploadedFile> UploadAsync(
        string directory,
        byte[] fileBytes,
        string mime,
        string? fileName = null,
        CancellationToken ct = default);

    /// <summary>
    /// آپلود تصویر با بهینه‌سازی خودکار + ساخت بندانگشتی
    /// </summary>
    /// <returns>نتیجه آپلود شامل تصویر اصلی و بندانگشتی (مسیرهای نسبی)</returns>
    /// <exception cref="FileUploadException">در صورت خطای آپلود</exception>
    Task<UploadedImage> UploadImageAsync(
        string directory,
        byte[] fileBytes,
        string mime,
        string? fileName = null,
        CancellationToken ct = default);

    /// <summary>
    /// حذف فایل از دیسک
    /// </summary>
    Task DeleteAsync(long fileId, CancellationToken ct = default);

    /// <summary>
    /// خواندن فایل از دیسک و تبدیل به base64 data-URI
    /// اگر مسیر از قبل data: باشد، همان را برمی‌گرداند
    /// اگر فایل وجود نداشته باشد، رشته خالی برمی‌گرداند
    /// </summary>
    string ResolveImageUrl(string? path);
}

/// <summary>
/// نتیجه آپلود فایل
/// </summary>
/// <param name="Id">شناسه فایل در FMS</param>
/// <param name="Path">مسیر فایل ذخیره‌شده (مثلاً /Images/Products/abc.jpg)</param>
public sealed record UploadedFile(long Id, string Path);

/// <summary>
/// نتیجه آپلود تصویر — شامل تصویر اصلی و بندانگشتی
/// </summary>
/// <param name="Main">تصویر اصلی بهینه‌شده</param>
/// <param name="Thumbnail">تصویر بندانگشتی</param>
public sealed record UploadedImage(UploadedFile Main, UploadedFile Thumbnail);

/// <summary>
/// خطای آپلود فایل
/// </summary>
public class FileUploadException : Exception
{
    public FileUploadException(string message) : base(message) { }
    public FileUploadException(string message, Exception inner) : base(message, inner) { }
}
