import { Directive, TemplateRef, Input, Injectable, QueryList, Component, ContentChildren, Pipe, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { SdTranslateModule } from '@sd-angular/core/translate';
import { SdCommonModule } from '@sd-angular/core/common';
import { __awaiter, __classPrivateFieldGet } from 'tslib';
import { BehaviorSubject, Subscription } from 'rxjs';
import { startWith } from 'rxjs/operators';
import { v4 } from 'uuid';
import { DeviceDetectorService } from 'ngx-device-detector';
import hash from 'object-hash';
import { SdSettingService } from '@sd-angular/core/setting';
import { SdFormModule } from '@sd-angular/core/form';
import { MatButtonModule } from '@angular/material/button';

class SdFilterDefDirective {
    constructor(templateRef) {
        this.templateRef = templateRef;
    }
    set _defaultShowing(val) {
        this.defaultShowing = (val === '') || val;
    }
}
SdFilterDefDirective.decorators = [
    { type: Directive, args: [{
                selector: '[sdFilterDef]'
            },] }
];
SdFilterDefDirective.ctorParameters = () => [
    { type: TemplateRef }
];
SdFilterDefDirective.propDecorators = {
    sdFilterDef: [{ type: Input }],
    _defaultShowing: [{ type: Input, args: ['defaultShowing',] }]
};

var _prefix;
class SdFilterService {
    constructor(settingService) {
        this.settingService = settingService;
        _prefix.set(this, '61d22e8e-eee8-4aad-8e1c-044a532fea91');
        this.get = (key) => __awaiter(this, void 0, void 0, function* () {
            var _a;
            if (!key) {
                return {
                    selectedQuickFilter: null,
                    quickFilters: [],
                    filter: {}
                };
            }
            const { get } = this.settingService.create({
                prefix: __classPrivateFieldGet(this, _prefix),
                key
            });
            const configuration = yield get();
            return {
                selectedQuickFilter: (_a = configuration === null || configuration === void 0 ? void 0 : configuration.selectedQuickFilter) !== null && _a !== void 0 ? _a : null,
                quickFilters: (configuration === null || configuration === void 0 ? void 0 : configuration.quickFilters) || [],
                filter: (configuration === null || configuration === void 0 ? void 0 : configuration.filter) || {}
            };
        });
        this.set = (key, configuration) => __awaiter(this, void 0, void 0, function* () {
            var _b;
            configuration = {
                selectedQuickFilter: (_b = configuration === null || configuration === void 0 ? void 0 : configuration.selectedQuickFilter) !== null && _b !== void 0 ? _b : null,
                quickFilters: (configuration === null || configuration === void 0 ? void 0 : configuration.quickFilters) || [],
                filter: (configuration === null || configuration === void 0 ? void 0 : configuration.filter) || {}
            };
            if (!key) {
                return configuration;
            }
            const { set } = this.settingService.create({
                prefix: __classPrivateFieldGet(this, _prefix),
                key
            });
            key = hash({
                prefix: __classPrivateFieldGet(this, _prefix),
                key
            });
            yield set(configuration);
            return configuration;
        });
    }
}
_prefix = new WeakMap();
SdFilterService.decorators = [
    { type: Injectable }
];
SdFilterService.ctorParameters = () => [
    { type: SdSettingService }
];

var _prefix$1, _filterOptionChanges, _subscription, _format, _firstLoad;
class SdFilter {
    constructor(deviceService, settingService, filterService) {
        this.deviceService = deviceService;
        this.settingService = settingService;
        this.filterService = filterService;
        _prefix$1.set(this, '61d22e8e-eee8-4aad-8e1c-044a532fea91');
        _filterOptionChanges.set(this, new BehaviorSubject(null));
        _subscription.set(this, new Subscription());
        this.sdFilterDefs = new QueryList();
        this.isMobileOrTablet = false;
        this.filterChanges = new BehaviorSubject({});
        this.onFilter = (filter) => {
            this.filterChanges.next({
                filter: Object.assign({}, this.information.filter),
                filterDef: Object.assign({}, this.information.filterDef),
            });
            this.setting.set(this.information);
        };
        this.onClear = () => {
            this.information.filter = {};
            this.information.filterDef = {};
            this.onFilter();
        };
        _format.set(this, (filters, information) => {
            var _a, _b, _c, _d, _e;
            for (const filter of filters) {
                if (filter.type === 'daterange') {
                    information.filter[filter.field] = {
                        from: (_b = (_a = information.filter[filter.field]) === null || _a === void 0 ? void 0 : _a.from) !== null && _b !== void 0 ? _b : undefined,
                        to: (_d = (_c = information.filter[filter.field]) === null || _c === void 0 ? void 0 : _c.to) !== null && _d !== void 0 ? _d : undefined
                    };
                }
                else {
                    information.filter[filter.field] = (_e = information.filter[filter.field]) !== null && _e !== void 0 ? _e : undefined;
                }
            }
        });
        _firstLoad.set(this, (filters, information) => {
            var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
            if (information.selectedQuickFilter && information.quickFilters.some(e => e.code === information.selectedQuickFilter)) {
                const selected = information.quickFilters.find(e => e.code === information.selectedQuickFilter);
                information.filter = Object.assign({}, selected.filter);
                information.filterDef = Object.assign({}, selected.filterDef);
                __classPrivateFieldGet(this, _format).call(this, filters, information);
            }
            else {
                for (const filter of filters) {
                    if (filter.type === 'daterange') {
                        information.filter[filter.field] = {
                            from: (_d = (_b = (_a = information.filter[filter.field]) === null || _a === void 0 ? void 0 : _a.from) !== null && _b !== void 0 ? _b : (_c = filter.default) === null || _c === void 0 ? void 0 : _c.from) !== null && _d !== void 0 ? _d : undefined,
                            to: (_h = (_f = (_e = information.filter[filter.field]) === null || _e === void 0 ? void 0 : _e.to) !== null && _f !== void 0 ? _f : (_g = filter.default) === null || _g === void 0 ? void 0 : _g.to) !== null && _h !== void 0 ? _h : undefined
                        };
                    }
                    else {
                        information.filter[filter.field] = (_k = (_j = information.filter[filter.field]) !== null && _j !== void 0 ? _j : filter.default) !== null && _k !== void 0 ? _k : undefined;
                    }
                }
            }
        });
        this.setFilter = (args) => {
            const { filter, filterDef } = args;
            this.information = Object.assign(Object.assign({}, this.information), { filter: Object.assign({}, filter), filterDef: Object.assign({}, filterDef) });
        };
        this.isMobileOrTablet = !this.deviceService.isDesktop();
    }
    set _filterOption(option) {
        console.log(option);
        if (option) {
            this.filterOption = option;
            __classPrivateFieldGet(this, _filterOptionChanges).next(option);
        }
    }
    ngOnInit() {
        // if (!this.#key) {
        //   this.setting = this.settingService.create<SdFilterInformation>(uuid.v4(), {
        //     type: 'session',
        //     default: {
        //       filter: {},
        //       visible: {},
        //       quickFilters: [],
        //       selectedQuickFilter: null
        //     }
        //   });
        // } else {
        //   this.setting = this.settingService.create<SdFilterInformation>(this.#key, {
        //     default: {
        //       filter: {},
        //       visible: {},
        //       quickFilters: [],
        //       selectedQuickFilter: null
        //     }
        //   });
        // }
    }
    ngAfterViewInit() {
        __classPrivateFieldGet(this, _subscription).add(__classPrivateFieldGet(this, _filterOptionChanges).pipe(startWith(this.filterOption)).subscribe((filterOption) => {
            var _a, _b;
            console.log(filterOption);
            if (!filterOption) {
                return;
            }
            const defaultInformation = {
                filter: {},
                visible: {},
                quickFilters: ((_a = filterOption === null || filterOption === void 0 ? void 0 : filterOption.quickFilter) === null || _a === void 0 ? void 0 : _a.defaults) || [],
                selectedQuickFilter: (_b = filterOption === null || filterOption === void 0 ? void 0 : filterOption.quickFilter) === null || _b === void 0 ? void 0 : _b.selectedDefault
            };
            if (!filterOption.key) {
                this.setting = this.settingService.create(v4(), {
                    type: 'session',
                    default: defaultInformation
                });
            }
            else {
                this.setting = this.settingService.create({
                    prefix: __classPrivateFieldGet(this, _prefix$1),
                    key: filterOption.key
                }, {
                    default: defaultInformation
                });
            }
            this.information = this.setting.get();
            console.log(this.information);
            __classPrivateFieldGet(this, _subscription).add(this.setting.observer.subscribe(filterInformation => {
                this.information = filterInformation;
                __classPrivateFieldGet(this, _format).call(this, filterOption === null || filterOption === void 0 ? void 0 : filterOption.filters, this.information);
            }));
        }));
    }
    ngOnDestroy() {
        __classPrivateFieldGet(this, _subscription).unsubscribe();
    }
}
_prefix$1 = new WeakMap(), _filterOptionChanges = new WeakMap(), _subscription = new WeakMap(), _format = new WeakMap(), _firstLoad = new WeakMap();
SdFilter.decorators = [
    { type: Component, args: [{
                selector: 'sd-filter',
                template: "<div *ngIf=\"information\" class=\"c-container\">\r\n  <div class=\"c-header\">\r\n    <div class=\"d-flex align-items-center\">\r\n      <button class=\"mx-2\" aria-hidden=\"true\" mat-icon-button>\r\n        <mat-icon class=\"c-icon\">filter_alt</mat-icon>\r\n      </button>\r\n      <span>Hi\u1EC3n th\u1ECB</span>\r\n    </div>\r\n    <div class=\"d-flex align-items-center\">\r\n      <button class=\"mx-2\" aria-hidden=\"true\" mat-icon-button>\r\n        <mat-icon class=\"c-icon\">add</mat-icon>\r\n      </button>\r\n      <button class=\"mx-2\" aria-hidden=\"true\" mat-icon-button>\r\n        <mat-icon class=\"c-icon\">settings</mat-icon>\r\n      </button>\r\n      <button class=\"mx-2\" aria-hidden=\"true\" mat-icon-button>\r\n        <mat-icon class=\"c-icon\">download</mat-icon>\r\n      </button>\r\n      <button class=\"mx-2\" aria-hidden=\"true\" mat-icon-button>\r\n        <mat-icon class=\"c-icon\">close</mat-icon>\r\n      </button>\r\n    </div>\r\n  </div>\r\n  <div class=\"c-body row mx-0\">\r\n    <ng-container *ngFor=\"let item of filterOption?.filters\">\r\n      <div *ngIf=\"information.visible[item.field] !== false\" class=\"col-lg-2 col-md-3 col-sm-6 px-8\">\r\n        <sd-input *ngIf=\"item.type === 'string'\" [label]=\"item.title\" type=\"text\"\r\n          [(model)]=\"information.filter[item.field]\" (keyupEnter)=\"onFilter(item)\">\r\n        </sd-input>\r\n        <sd-input-number *ngIf=\"item.type === 'number'\" [label]=\"item.title\" [(model)]=\"information.filter[item.field]\"\r\n          (keyupEnter)=\"onFilter(item)\">\r\n        </sd-input-number>\r\n        <sd-select *ngIf=\"item.type === 'bool'\" [label]=\"item.title\" [items]=\"[{value:true,display:item.option?.displayOnTrue || 'True' },\r\n          {value:false,display:item.option?.displayOnFalse || 'False' }]\" valueField=\"value\" displayField=\"display\"\r\n          [(model)]=\"information.filter[item.field]\" (sdChange)=\"onFilter(item)\">\r\n        </sd-select>\r\n        <ng-container *ngIf=\"item.type === 'values-local'\">\r\n          <sd-select *ngIf=\"item.option?.selection === 'MULTIPLE'\" [label]=\"item.title\"\r\n            [items]=\"item | sdValuesLocal | async\" [valueField]=\"item.option.valueField\"\r\n            [displayField]=\"item.option.displayField\" [(model)]=\"information.filter[item.field]\"\r\n            (sdChange)=\"onFilter(item)\" [selectAll]=\"item.option.selectAll\" multiple=\"true\">\r\n          </sd-select>\r\n          <sd-autocomplete *ngIf=\"item.option?.selection === 'AUTOCOMPLETE'\" [label]=\"item.title\"\r\n            [items]=\"item | sdValuesLocal | async\" [valueField]=\"item.option.valueField\"\r\n            [displayField]=\"item.option.displayField\" [(model)]=\"information.filter[item.field]\"\r\n            (sdChange)=\"onFilter(item)\">\r\n          </sd-autocomplete>\r\n          <sd-select *ngIf=\"item.option?.selection === 'MULTIPLEAUTOCOMPLETE'\" [label]=\"item.title\"\r\n            [items]=\"item | sdValuesLocal | async\" [valueField]=\"item.option.valueField\"\r\n            [displayField]=\"item.option.displayField\" [(model)]=\"information.filter[item.field]\"\r\n            (sdChange)=\"onFilter(item)\" filtered multiple>\r\n          </sd-select>\r\n          <sd-select *ngIf=\"!item.option?.selection\" [label]=\"item.title\" [items]=\"item | sdValuesLocal | async\"\r\n            [valueField]=\"item.option.valueField\" [displayField]=\"item.option.displayField\"\r\n            [(model)]=\"information.filter[item.field]\" (sdChange)=\"onFilter(item)\">\r\n          </sd-select>\r\n        </ng-container>\r\n        <ng-container *ngIf=\"item.type === 'values-server'\">\r\n          <sd-select *ngIf=\"item.option?.selection === 'MULTIPLE'\" [label]=\"item.title\"\r\n            [items]=\"item | sdValuesLocal | async\" [valueField]=\"item.option.valueField\"\r\n            [displayField]=\"item.option.displayField\" [(model)]=\"information.filter[item.field]\"\r\n            (sdChange)=\"onFilter(item)\" filtered multiple>\r\n          </sd-select>\r\n          <sd-autocomplete *ngIf=\"!item.option?.selection\" [label]=\"item.title\" [items]=\"item | sdValuesLocal | async\"\r\n            [valueField]=\"item.option.valueField\" [displayField]=\"item.option.displayField\"\r\n            [(model)]=\"information.filter[item.field]\" (sdChange)=\"onFilter(item)\">\r\n          </sd-autocomplete>\r\n        </ng-container>\r\n        <sd-date-time *ngIf=\"item.type ==='date' || item.type ==='datetime'\" [label]=\"item.title\"\r\n          [(model)]=\"information.filter[item.field]\" [type]=\"item.type\" [min]=\"item?.option?.min\"\r\n          [max]=\"item?.option?.max\" (sdChange)=\"onFilter(item)\">\r\n        </sd-date-time>\r\n        <sd-date-range *ngIf=\"item.type ==='daterange'\" [label]=\"item.title\"\r\n          [(from)]=\"information.filter[item.field].from\" [(to)]=\"information.filter[item.field].to\"\r\n          [min]=\"item?.option?.min\" [max]=\"item?.option?.max\" (sdChange)=\"onFilter(item)\">\r\n        </sd-date-range>\r\n      </div>\r\n    </ng-container>\r\n  </div>\r\n</div>\r\n<!-- <sd-popup-filter [columns]=\"columns\" [externalFilters]=\"externalFilters\" (changeFilter)=\"onChangeFilter($event)\"\r\n    (clearFilter)=\"onReset()\" [filterDefs]=\"filterDefs\">\r\n  </sd-popup-filter> -->",
                styles: [".c-container .c-header{align-items:center;display:flex;height:48px;justify-content:space-between;padding:0 20px}.c-container mat-icon.c-icon{color:rgba(0,0,0,.54)!important}.c-container button:focus{outline:none}:host ::ng-deep .mat-form-field-wrapper{padding-bottom:0}"]
            },] }
];
SdFilter.ctorParameters = () => [
    { type: DeviceDetectorService },
    { type: SdSettingService },
    { type: SdFilterService }
];
SdFilter.propDecorators = {
    _filterOption: [{ type: Input, args: ['option',] }],
    sdFilterDefs: [{ type: ContentChildren, args: [SdFilterDefDirective,] }]
};

class SdValuesLocalPipe {
    constructor() {
        this.transform = (filterValues) => __awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c;
            if (typeof ((_a = filterValues === null || filterValues === void 0 ? void 0 : filterValues.option) === null || _a === void 0 ? void 0 : _a.items) === 'function') {
                return yield ((_b = filterValues === null || filterValues === void 0 ? void 0 : filterValues.option) === null || _b === void 0 ? void 0 : _b.items());
            }
            return ((_c = filterValues === null || filterValues === void 0 ? void 0 : filterValues.option) === null || _c === void 0 ? void 0 : _c.items) || [];
        });
    }
}
SdValuesLocalPipe.decorators = [
    { type: Pipe, args: [{
                name: 'sdValuesLocal'
            },] }
];

class SdValuesServerPipe {
    constructor() {
        this.transform = (filterValues) => {
            var _a, _b, _c;
            if (typeof ((_a = filterValues === null || filterValues === void 0 ? void 0 : filterValues.option) === null || _a === void 0 ? void 0 : _a.items) === 'function') {
                return (_b = filterValues === null || filterValues === void 0 ? void 0 : filterValues.option) === null || _b === void 0 ? void 0 : _b.items;
            }
            return ((_c = filterValues === null || filterValues === void 0 ? void 0 : filterValues.option) === null || _c === void 0 ? void 0 : _c.items) || [];
        };
    }
}
SdValuesServerPipe.decorators = [
    { type: Pipe, args: [{
                name: 'sdValuesServer'
            },] }
];

class SdFilterModule {
}
SdFilterModule.decorators = [
    { type: NgModule, args: [{
                imports: [
                    CommonModule,
                    MatFormFieldModule,
                    MatInputModule,
                    MatIconModule,
                    MatTooltipModule,
                    MatButtonModule,
                    SdTranslateModule,
                    SdCommonModule,
                    SdFormModule
                ],
                declarations: [
                    SdFilter,
                    SdFilterDefDirective,
                    SdValuesLocalPipe,
                    SdValuesServerPipe
                ],
                providers: [
                    SdFilterService
                ],
                exports: [
                    SdCommonModule,
                    SdFilterDefDirective,
                    SdFilter
                ]
            },] }
];

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

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

export { SdFilter, SdFilterDefDirective, SdFilterModule, SdFilterService as ɵa, SdValuesLocalPipe as ɵb, SdValuesServerPipe as ɵc };
//# sourceMappingURL=sd-angular-core-filter.js.map
