import { EventEmitter, Component, ChangeDetectorRef, Input, Output, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DeviceDetectorModule } from 'ngx-device-detector';
import { SdNotifyService, SdNotifyModule } from '@sd-angular/core/notify';
import { SdTranslateService, SdTranslateModule } from '@sd-angular/core/translate';
import { MatIconModule } from '@angular/material/icon';
import { __awaiter, __classPrivateFieldGet, __classPrivateFieldSet } from 'tslib';
import { v4 } from 'uuid';
import $ from 'jquery';
import { Subscription, Subject } from 'rxjs';
import { startWith } from 'rxjs/operators';
import { FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatChipsModule } from '@angular/material/chips';

var _model, _subscription, _modelChanges, _updateValidator, _validate, _uploadFile, _validator;
class SdInputUploadFiletStateMatcher {
    constructor(formControl) {
        this.formControl = formControl;
    }
    isErrorState(control, form) {
        var _a, _b, _c;
        const isSubmitted = form && form.submitted;
        return !!(((_a = this.formControl) === null || _a === void 0 ? void 0 : _a.invalid) && (((_b = this.formControl) === null || _b === void 0 ? void 0 : _b.dirty) || ((_c = this.formControl) === null || _c === void 0 ? void 0 : _c.touched) || isSubmitted));
    }
}
class SdInputUploadFile {
    constructor(ref, notifyService, translateService) {
        this.ref = ref;
        this.notifyService = notifyService;
        this.translateService = translateService;
        this.id = `I${v4()}`;
        this.previewFiles = [];
        this.type = 'file';
        this.extensions = [];
        this.min = 0;
        this.max = 1;
        _model.set(this, void 0);
        this.disableErrorMessage = false;
        this.isRequired = false;
        this.modelChange = new EventEmitter();
        this.sdChange = new EventEmitter();
        this.inputControl = new FormControl();
        this.formControl = new FormControl();
        this.matcher = new SdInputUploadFiletStateMatcher(this.formControl);
        _subscription.set(this, new Subscription());
        _modelChanges.set(this, new Subject());
        _updateValidator.set(this, () => {
            this.formControl.clearValidators();
            this.formControl.clearAsyncValidators();
            const validators = [];
            const asyncValidators = [];
            if (this.isRequired) {
                validators.push(Validators.required);
            }
            if (this.inlineError) {
                validators.push(this.customInlineErrorValidator());
            }
            this.formControl.setValidators(validators);
            this.formControl.setAsyncValidators(asyncValidators);
            this.formControl.updateValueAndValidity();
        }
        // Hàm tạo Validators tùy chỉnh cho inlineError
        );
        _validate.set(this, (file) => __awaiter(this, void 0, void 0, function* () {
            var _a;
            if (this.type === 'image') {
                if (file.type.split('/')[0] !== 'image') {
                    return `[${file.name}] ${this.translateService.translate('Uploaded file is not an image')}`;
                }
            }
            if ((_a = this.extensions) === null || _a === void 0 ? void 0 : _a.length) {
                const lastDot = file.name.lastIndexOf('.');
                const extension = file.name.substring(lastDot + 1);
                if (!this.extensions.some(e => e.toUpperCase() === extension.toUpperCase())) {
                    return `[${file.name}] ${this.translateService.translate('Uploaded file is not match extension')} ${this.extensions.join(', ')}`;
                }
            }
            if (this.maxSize) {
                if (this.maxSize * 1024 * 1024 < file.size) {
                    return `[${file.name}] ${this.translateService.translate('Max file size')} ${this.maxSize} Mbs`;
                }
            }
            if (this.type === 'image' && (this.maxWidth || this.maxHeight)) {
                const message = yield new Promise(resolve => {
                    const URL = window.URL || window.webkitURL;
                    const img = new Image();
                    img.onload = () => {
                        if (this.maxWidth && img.width > this.maxWidth) {
                            resolve(`[${file.name}] ${this.translateService.translate('Max image width')} ${this.maxWidth}px`);
                        }
                        if (this.maxHeight && img.height > this.maxHeight) {
                            resolve(`[${file.name}] ${this.translateService.translate('Max image height')} ${this.maxHeight}px`);
                        }
                        resolve(null);
                    };
                    img.src = URL.createObjectURL(file);
                });
                if (message) {
                    return message;
                }
            }
            return null;
        }));
        this.onUpload = () => {
            if ($(`#${this.id}`).length) {
                $('body').children(`#${this.id}`).remove();
            }
            if (this.max === 1) {
                $('body').append(`<input id="${this.id}" style="display: none" type="file" />`);
            }
            else {
                $('body').append(`<input id="${this.id}" style="display: none" type="file" multiple />`);
            }
            $(`#${this.id}`).on('change', (evt) => __awaiter(this, void 0, void 0, function* () {
                yield __classPrivateFieldGet(this, _uploadFile).call(this, evt.target);
                $('body').children(`#${this.id}`).remove();
            }));
            $(`#${this.id}`).trigger('click');
        };
        _uploadFile.set(this, (target) => __awaiter(this, void 0, void 0, function* () {
            if (!target.files.length) {
                return;
            }
            const originFiles = target.files;
            const files = [];
            if (originFiles.length + this.previewFiles.length > this.max) {
                this.notifyService.notify.warning(`${this.translateService.translate('Max number of files')} ${this.max}`);
                return;
            }
            for (let i = 0; i < originFiles.length; i++) {
                let file = originFiles.item(i);
                const message = yield __classPrivateFieldGet(this, _validate).call(this, file);
                if (message) {
                    this.notifyService.notify.warning(message);
                    return;
                }
                files.push(file);
            }
            for (const file of files) {
                const lastDot = file.name.lastIndexOf('.');
                const extension = file.name.substring(lastDot + 1);
                this.previewFiles.push({
                    file,
                    src: null,
                    fileName: file.name,
                    extension
                });
            }
            this.formControl.setValue(this.previewFiles);
            this.sdChange.emit(this.previewFiles);
            this.ref.detectChanges();
        }));
        this.onRemove = (previewFile) => {
            const idx = this.previewFiles.indexOf(previewFile);
            this.previewFiles.splice(idx, 1);
            this.formControl.setValue(this.previewFiles, {
                emitEvent: false
            });
            this.formControl.setValue(this.previewFiles);
            this.sdChange.emit(this.previewFiles);
        };
        _validator.set(this, (c) => {
            const value = c.value || null;
            if (this.min > 0) {
                const previewFiles = this.formControl.value || [];
                if (previewFiles.length < this.min) {
                    return {
                        min: `${this.translateService.translate('Please select at least')} ${this.min}`
                    };
                }
            }
            if (this.max > 0) {
                const previewFiles = this.formControl.value || [];
                if (previewFiles.length > this.max) {
                    return {
                        max: `${this.translateService.translate('Please select at most')} ${this.max}`
                    };
                }
            }
            return null;
        });
    }
    // Optional
    set disabled(val) {
        val = (val === '') || val;
        if (val) {
            this.formControl.disable();
        }
        else {
            this.formControl.enable();
        }
    }
    set model(model) {
        if (this.previewFiles !== model && Array.isArray(model)) {
            __classPrivateFieldSet(this, _model, model);
            __classPrivateFieldGet(this, _modelChanges).next(__classPrivateFieldGet(this, _model));
        }
    }
    set _disableErrorMessage(val) {
        this.disableErrorMessage = (val === '') || val;
    }
    set _inlineError(val) {
        this.inlineError = val;
        __classPrivateFieldGet(this, _updateValidator).call(this);
    }
    set required(val) {
        this.isRequired = (val === '') || val;
        __classPrivateFieldGet(this, _updateValidator).call(this);
    }
    ngOnInit() {
        this.formControl.setValidators([__classPrivateFieldGet(this, _validator)]);
        this.inputControl.disable();
    }
    // Hàm tạo Validators tùy chỉnh cho inlineError
    customInlineErrorValidator() {
        return (control) => {
            return { inlineError: true };
        };
    }
    ngAfterViewInit() {
        __classPrivateFieldGet(this, _subscription).add(__classPrivateFieldGet(this, _modelChanges).pipe(startWith(__classPrivateFieldGet(this, _model))).subscribe((previewFiles) => {
            if (Array.isArray(previewFiles)) {
                this.previewFiles = [];
                previewFiles.forEach(previewFile => {
                    if (typeof (previewFile) === 'string') {
                        this.previewFiles.push({
                            file: null,
                            src: previewFile
                        });
                    }
                    else {
                        this.previewFiles.push(previewFile);
                    }
                });
                this.formControl.setValue(this.previewFiles);
                this.modelChange.emit(this.previewFiles);
            }
        }));
    }
    ngOnDestroy() {
        __classPrivateFieldGet(this, _subscription).unsubscribe();
    }
}
_model = new WeakMap(), _subscription = new WeakMap(), _modelChanges = new WeakMap(), _updateValidator = new WeakMap(), _validate = new WeakMap(), _uploadFile = new WeakMap(), _validator = new WeakMap();
SdInputUploadFile.decorators = [
    { type: Component, args: [{
                selector: 'sd-input-upload-file',
                template: "<mat-form-field class=\"sd-md\" appearance=\"outline\">\r\n  <mat-label *ngIf=\"label\">{{label}}</mat-label>\r\n  <mat-chip-list [formControl]=\"formControl\" #chipList>\r\n    <ng-container *ngFor=\"let item of previewFiles\">\r\n      <mat-chip *ngIf=\"item\" [removable]=\"!formControl.disabled\" (removed)=\"onRemove(item)\"\r\n        [removable]=\"formControl.disabled\">\r\n        <span>{{item.fileName || item.src}}</span>\r\n        <mat-icon matChipRemove *ngIf=\"!formControl.disabled\">cancel</mat-icon>\r\n      </mat-chip>\r\n    </ng-container>\r\n    <input [formControl]=\"inputControl\" [placeholder]=\"placeholder || label\" [matChipInputFor]=\"chipList\"\r\n      autocomplete=\"off\" [errorStateMatcher]=\"matcher\" matInput>\r\n    <mat-icon class=\"pointer sd-suffix-icon\" (click)=\"onUpload()\" matSuffix>file_upload\r\n    </mat-icon>\r\n  </mat-chip-list>\r\n  <mat-error *ngIf=\"formControl.errors?.required\">\r\n    <ng-container *ngIf=\"!disableErrorMessage\">{{ \"This field is required\" | sdTranslate }}</ng-container>\r\n  </mat-error>\r\n  <mat-error *ngIf=\"formControl?.errors?.min\">\r\n    {{formControl?.errors?.min}}\r\n  </mat-error>\r\n  <mat-error *ngIf=\"formControl?.errors?.max\">\r\n    {{formControl?.errors?.max}}\r\n  </mat-error>\r\n  <mat-error *ngIf=\"formControl.errors?.inlineError\">\r\n    <ng-container *ngIf=\"!disableErrorMessage\">{{inlineError}}</ng-container>\r\n  </mat-error>\r\n</mat-form-field>",
                styles: [":host{display:block;padding-top:5px}"]
            },] }
];
SdInputUploadFile.ctorParameters = () => [
    { type: ChangeDetectorRef },
    { type: SdNotifyService },
    { type: SdTranslateService }
];
SdInputUploadFile.propDecorators = {
    label: [{ type: Input }],
    placeholder: [{ type: Input }],
    type: [{ type: Input }],
    extensions: [{ type: Input }],
    min: [{ type: Input }],
    max: [{ type: Input }],
    maxSize: [{ type: Input }],
    maxWidth: [{ type: Input }],
    maxHeight: [{ type: Input }],
    disabled: [{ type: Input }],
    model: [{ type: Input }],
    _disableErrorMessage: [{ type: Input, args: ['disableErrorMessage',] }],
    _inlineError: [{ type: Input, args: ['inlineError',] }],
    required: [{ type: Input }],
    modelChange: [{ type: Output }],
    sdChange: [{ type: Output }]
};

class SdInputUploadFileModule {
}
SdInputUploadFileModule.decorators = [
    { type: NgModule, args: [{
                imports: [
                    CommonModule,
                    DeviceDetectorModule.forRoot(),
                    MatFormFieldModule,
                    MatInputModule,
                    MatChipsModule,
                    MatIconModule,
                    FormsModule,
                    ReactiveFormsModule,
                    SdNotifyModule,
                    SdTranslateModule
                ],
                declarations: [
                    SdInputUploadFile
                ],
                exports: [
                    SdInputUploadFile
                ],
                providers: []
            },] }
];

/*
 * Public API Surface of superdev-angular-core
 */

/**
 * Generated bundle index. Do not edit.
 */

export { SdInputUploadFile, SdInputUploadFileModule };
//# sourceMappingURL=sd-angular-core-input-upload-file.js.map
