import * as _angular_core from '@angular/core';
import { InjectionToken, EventEmitter, ChangeDetectorRef, ElementRef } from '@angular/core';
import { CdkDragDrop } from '@angular/cdk/drag-drop';
import { FormGroup } from '@angular/forms';
import { SdLabelDefDirective } from '@sdcorejs/angular/forms/directives';
import { SdFormControl } from '@sdcorejs/angular/forms/models';
import { SdModal } from '@sdcorejs/angular/components/modal';

/**
 * Contract cấu hình cho cơ chế upload file của sd-angular.
 *
 * Cách dùng phổ biến:
 * - Portal có thể provide cấu hình mặc định ở tầng global.
 * - Mỗi module có thể provide thêm cấu hình riêng (thường với `multi: true`).
 * - Khi có nhiều cấu hình cùng lúc, dùng `key` để chọn đúng provider.
 *
 * Luồng xử lý:
 * 1) `upload`: upload file mới, trả về danh sách id/key.
 * 2) `details`: lấy metadata để render danh sách file từ id/key.
 * 3) `download` (optional): tải file theo id/key.
 */
interface ISdUploadFileConfiguration<TArgs = any> {
    /**
     * Định danh cấu hình upload.
     * Bắt buộc khi app có nhiều provider upload để tránh mapping nhầm.
     */
    key?: string;
    /** Upload file và trả về danh sách id/key dùng cho lưu trữ. */
    upload: SdUploadFileFuncUpload<TArgs>;
    /** Nhận danh sách id/key và trả về dữ liệu hiển thị file trong UI. */
    details: SdUploadFileFuncDetails<TArgs>;
    /** Tùy chọn: tải file về theo id/key. */
    download?: SdUploadFileFuncDownload<TArgs>;
}
/**
 * Token DI cho upload configuration.
 * Khuyến nghị provide dạng `multi: true` để hỗ trợ nhiều nguồn upload trong cùng app/module.
 */
declare const SD_UPLOAD_FILE_CONFIGURATION: InjectionToken<ISdUploadFileConfiguration<any>>;
/** Hàm upload file và trả về danh sách id/key tương ứng. */
type SdUploadFileFuncUpload<TArgs> = (files: File[], args?: TArgs) => Promise<string[]>;
/** Hàm lấy thông tin file phục vụ hiển thị từ danh sách id/key. */
type SdUploadFileFuncDetails<TArgs> = (idOrKey: (string | number)[], args?: TArgs) => Promise<SdUploadFileDetail[]>;
/** Hàm tải file theo id/key. */
type SdUploadFileFuncDownload<TArgs> = (idOrKey: string | number, args?: TArgs) => Promise<void>;
interface SdUploadFileDetail {
    /** Định danh file được backend trả về sau upload. */
    idOrKey: string;
    /** URL truy cập file (CDN hoặc direct URL). */
    cdn: string;
    /** Tên hiển thị file. */
    name?: string;
    /** Đuôi file: png, jpg, pdf... */
    extension?: string;
    /** Dung lượng file tính theo MB (nếu backend có trả về). */
    size?: number;
}

interface PreviewFile {
    idOrKey?: string | number;
    file?: File | null;
    src?: string | null;
    previewSrc: string | ArrayBuffer | null;
    isPreviewImage: boolean;
    fileName?: string | null;
    fileSize?: number | null;
    extension?: string | null;
    isImgError?: boolean;
}

declare class PreviewComponent {
    #private;
    private cd;
    modal: SdModal;
    download: EventEmitter<PreviewFile>;
    close: EventEmitter<void>;
    title: string;
    thumbnailPosition: 'right' | 'left' | 'bottom' | 'top';
    activeIndex: number;
    previewFiles: PreviewFile[];
    constructor(cd: ChangeDetectorRef);
    open: (previewFiles: PreviewFile[] | undefined | null, index?: number) => Promise<void>;
    onClickThumbnailImage: (index: number) => void;
    updateCurrentImage: (direction: 1 | -1) => void;
    onClose: () => void;
    onDownload: (previewFile: PreviewFile) => void;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<PreviewComponent, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<PreviewComponent, "preview", never, {}, { "download": "download"; "close": "close"; }, never, never, true, never>;
}

declare class SdUploadFile<TArgs = any> {
    #private;
    readonly id: string;
    readonly formControl: SdFormControl;
    /** Hiển thị message "vui lòng upload": không disabled + đã touched + còn lỗi required. */
    readonly showRequiredError: _angular_core.Signal<boolean>;
    readonly previewFiles: _angular_core.WritableSignal<PreviewFile[]>;
    readonly selectedFile: _angular_core.WritableSignal<PreviewFile | null | undefined>;
    readonly previewFileComponent: _angular_core.Signal<PreviewComponent | undefined>;
    readonly dropElements: _angular_core.Signal<readonly ElementRef<any>[]>;
    readonly sdLabelDef: _angular_core.Signal<SdLabelDefDirective | undefined>;
    readonly autoIdInput: _angular_core.InputSignal<string | null | undefined>;
    readonly autoId: _angular_core.Signal<string | undefined>;
    readonly removeAutoId: (index: number) => string | undefined;
    readonly dataDisabled: _angular_core.Signal<"true" | "false">;
    readonly dataEmpty: _angular_core.Signal<"true" | "false">;
    readonly dataCount: _angular_core.Signal<string>;
    readonly args: _angular_core.InputSignal<TArgs | undefined>;
    readonly label: _angular_core.InputSignal<string | undefined>;
    readonly key: _angular_core.InputSignal<string | undefined>;
    readonly description: _angular_core.InputSignal<string | undefined>;
    readonly previewWidth: _angular_core.InputSignal<string>;
    readonly previewHeight: _angular_core.InputSignal<string>;
    readonly align: _angular_core.InputSignal<"left" | "center">;
    readonly uploadInput: _angular_core.InputSignal<SdUploadFileFuncUpload<any> | undefined>;
    readonly details: _angular_core.InputSignal<SdUploadFileFuncDetails<any> | undefined>;
    readonly downloadInput: _angular_core.InputSignal<SdUploadFileFuncDownload<any> | undefined>;
    readonly imageValidator: _angular_core.InputSignal<((image: HTMLImageElement) => string) | undefined>;
    readonly maxSize: _angular_core.InputSignal<number | undefined>;
    readonly maxWidth: _angular_core.InputSignal<number | undefined>;
    readonly maxHeight: _angular_core.InputSignal<number | undefined>;
    readonly scaleToPixel: _angular_core.InputSignal<number | undefined>;
    form: _angular_core.InputSignalWithTransform<FormGroup<any> | undefined, any>;
    readonly nameInput: _angular_core.InputSignalWithTransform<string, string | undefined>;
    readonly required: _angular_core.InputSignalWithTransform<boolean, boolean | "" | null | undefined>;
    readonly type: _angular_core.InputSignalWithTransform<"image" | "document" | "file", "image" | "document" | "file" | null | undefined>;
    readonly helperText: _angular_core.InputSignal<string | undefined>;
    readonly max: _angular_core.InputSignalWithTransform<number, number | null | undefined>;
    readonly maxOfImage: _angular_core.InputSignalWithTransform<number, number | null | undefined>;
    readonly extensions: _angular_core.InputSignalWithTransform<string[], string[] | null | undefined>;
    readonly disabled: _angular_core.InputSignalWithTransform<boolean, boolean | "" | null | undefined>;
    readonly generatedDescription: _angular_core.Signal<string | undefined>;
    readonly loaded: _angular_core.OutputEmitterRef<PreviewFile[]>;
    readonly filesChanged: _angular_core.OutputEmitterRef<(string | File)[]>;
    readonly model: _angular_core.ModelSignal<(string | number)[]>;
    constructor();
    onUpload: () => void;
    onRemove: (file: PreviewFile) => void;
    onDrop: (event: CdkDragDrop<string[]>) => void;
    onImgError: (previewFile: PreviewFile) => void;
    onSelect: (file: PreviewFile) => void;
    /**
     * Lấy danh sách các File từ previewFiles (chưa upload).
     */
    getFiles: () => Promise<File[]>;
    /**
     * Thực hiện upload các file và gán giá trị, output trả ra mảng idOrKeys.
     * HÀM NÀY BẮT BUỘC PHẢI GỌI TRƯỚC KHI GỌI VỀ SERVER.
     */
    upload: () => Promise<void>;
    /**
     * Mở popup preview ảnh.
     */
    preview: () => Promise<void>;
    /**
     * Tải xuống một tệp tin dựa trên đối tượng PreviewFile.
     *
     * Ưu tiên:
     * 1. Nếu consumer CÓ implement hàm download (input `download` hoặc configuration) VÀ file có
     *    `idOrKey` (file đã lưu trên server) → LUÔN gọi hàm download. KHÔNG mở `src` (URL lấy từ detail).
     *    Dùng cho trường hợp tải file qua API có xác thực thay vì truy cập trực tiếp URL.
     * 2. Ngược lại (không có hàm download, hoặc file local chưa upload nên chưa có `idOrKey`) →
     *    tải trực tiếp từ `file` (blob) hoặc `src` (URL).
     *
     * @param previewFile Đối tượng PreviewFile chứa thông tin tệp tin.
     */
    onDownload: (previewFile: PreviewFile) => void;
    isLastVisibleOverlay(fileIndex: number): boolean;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdUploadFile<any>, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdUploadFile<any>, "sd-upload-file", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "args": { "alias": "args"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "key": { "alias": "key"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "previewWidth": { "alias": "previewWidth"; "required": false; "isSignal": true; }; "previewHeight": { "alias": "previewHeight"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "uploadInput": { "alias": "upload"; "required": false; "isSignal": true; }; "details": { "alias": "details"; "required": false; "isSignal": true; }; "downloadInput": { "alias": "download"; "required": false; "isSignal": true; }; "imageValidator": { "alias": "imageValidator"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "maxWidth": { "alias": "maxWidth"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "scaleToPixel": { "alias": "scaleToPixel"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "nameInput": { "alias": "name"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "maxOfImage": { "alias": "maxOfImage"; "required": false; "isSignal": true; }; "extensions": { "alias": "extensions"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "model": { "alias": "model"; "required": false; "isSignal": true; }; }, { "loaded": "loaded"; "filesChanged": "filesChanged"; "model": "modelChange"; }, ["sdLabelDef"], never, true, never>;
}

export { SD_UPLOAD_FILE_CONFIGURATION, SdUploadFile };
export type { ISdUploadFileConfiguration, SdUploadFileDetail, SdUploadFileFuncDetails, SdUploadFileFuncDownload, SdUploadFileFuncUpload };
