import {
    IFileInfoModel,
    IFileImageDimensions,
    IGenerateKeyOptions,
    IBaseService,
    AsDomainType,
    ImageFilterName,
} from 'common/server';
import type { ReadStream } from 'fs';

export type IFileImageFilter = Partial<{
    [key in ImageFilterName]?: string;
}>;

export interface IUploadFile {
    createReadStream: () => ReadStream;
    filename: string;
    mimetype: string;
}

export interface IFileInfoServiceInput {
    file: Promise<IUploadFile>;
    ref: string;
    refType: string;
    createdBy: string;
}

export interface IFileInfoUploadedInput
    extends Omit<IFileInfoModel, 'id' | 'createdAt' | 'updatedAt' | 'createdBy' | 'extension'> {
    name: string;
    url: string;
    createdBy: string;
}

export interface IFileInfoService extends IBaseService<IFileInfoModel> {
    /**
     * Creates a signed URL for file upload
     *
     * @param {IGenerateKeyOptions} options - Options for generating the upload key
     * @returns {Promise<string>} The signed URL for file upload
     */
    uploadByUrl(options: IGenerateKeyOptions): Promise<string>;

    /**
     * Deletes a file by its URL
     *
     * @param {string} url - The URL of the file to delete
     * @returns {Promise<boolean>} Success status of deletion
     */
    deleteByUrl(url: string): Promise<boolean>;

    /**
     * Creates a file info record for an already uploaded file
     *
     * @param {IFileInfoUploadedInput} data - File information for uploaded file
     * @returns {Promise<AsDomainType<IFileInfoModel>>} The created file info record
     */
    createUploadedFile(data: IFileInfoUploadedInput): Promise<AsDomainType<IFileInfoModel>>;

    /**
     * Retrieves file information by URL
     *
     * @param {string} url - The URL of the file
     * @returns {Promise<AsDomainType<IFileInfoModel>>} The file information
     */
    getByUrl(url: string): Promise<AsDomainType<IFileInfoModel>>;

    /**
     * Generates a resized image URL
     *
     * @param {string} url - The original image URL
     * @param {IFileImageDimensions} dimension - The desired dimensions
     * @returns {string} The resized image URL
     */
    getResizedImage(url: string, dimension: IFileImageDimensions): string;

    /**
     * Generates a WebP image URL with filters
     *
     * @param {string} url - The original image URL
     * @param {IFileImageFilter} filters - Image filters to apply
     * @returns {string} The processed image URL
     */
    getWebpImage(url: string, filters: IFileImageFilter): string;

    /**
     * Generates a thumbnail image URL
     *
     * @param {string} url - The original image URL
     * @returns {string} The thumbnail image URL
     */
    getThumbnailImage(url: string): string;

    /**
     * Generates a default sized image URL
     *
     * @param {string} url - The original image URL
     * @returns {string} The default sized image URL
     */
    getDefaultImage(url: string): string;

    /**
     * Generates a preview image URL
     *
     * @param {string} url - The original image URL
     * @returns {string} The preview image URL
     */
    getPreviewImage(url: string): string;

    /**
     * Creates a pre-signed download URL for S3 files
     *
     * @param {string} s3KeyOrUrl - Either an S3 key or full S3 URL
     * @param {number} expiresIn - URL expiration time in seconds (default: 300 = 5 minutes)
     * @param {string} bucketName - Optional bucket name
     * @returns {Promise<string>} Pre-signed URL for downloading the file
     */
    createDownloadSignedUrl(s3KeyOrUrl: string, expiresIn?: number, bucketName?: string): Promise<string>;
}
