import { AXDataSource, AXComponent } from '@acorex/cdk/common';
import { AXButtonComponent, AXButtonModule } from '@acorex/components/button';
import { AXButtonGroupComponent, AXButtonGroupItemComponent, AXButtonGroupModule } from '@acorex/components/button-group';
import { AXDateTimeBoxComponent, AXDateTimeBoxModule } from '@acorex/components/datetime-box';
import { AXDecoratorIconComponent, AXDecoratorClearButtonComponent, AXDecoratorModule } from '@acorex/components/decorators';
import { AXNumberBoxComponent, AXNumberBoxModule } from '@acorex/components/number-box';
import { AXSelectBoxComponent, AXSelectBoxModule } from '@acorex/components/select-box';
import { AXTextBoxComponent, AXTextBoxModule } from '@acorex/components/text-box';
import { NgTemplateOutlet, CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { input, model, output, viewChild, signal, effect, ChangeDetectionStrategy, ViewEncapsulation, Component, NgModule } from '@angular/core';

class AXQueryBuilderComponent {
    constructor() {
        this.columnData = input.required(...(ngDevMode ? [{ debugName: "columnData" }] : []));
        this.queryData = model.required(...(ngDevMode ? [{ debugName: "queryData" }] : []));
        this.onValueChanged = output();
        this.selectBoxRef = viewChild('reRender', ...(ngDevMode ? [{ debugName: "selectBoxRef" }] : []));
        this.selectedItem = signal(null, ...(ngDevMode ? [{ debugName: "selectedItem" }] : []));
        this.ds = new AXDataSource({
            load: async (e) => {
                return {
                    items: this.operators[this.selectedItem().type].slice(e.skip, (e.skip ?? 0) + (e.take ?? 0)),
                    total: this.operators[this.selectedItem().type].length,
                };
            },
            key: 'id',
            pageSize: 20,
        });
        this.operators = {
            string: [
                'Starts With',
                'Does Not Start With',
                'Ends With',
                'Does Not End With',
                'Contains',
                'Does Not Contain',
                'Equal',
                'Not Equal',
                'In',
                'Not In',
                'Is Empty',
                'Is Not Empty',
                'Is Null',
                'Is Not Null',
            ],
            boolean: ['Equal', 'Not Equal'],
            number: [
                'Equal',
                'Greater Than Or Equal',
                'Greater Than',
                'Between',
                'Less Than',
                'Not Between',
                'Less Than Or Equal',
                'Not Equal',
                'In',
                'Not In',
                'Is Null',
                'Is Not Null',
            ],
            date: [
                'Equal',
                'Greater Than',
                'Greater Than Or Equal',
                'Less Than',
                'Less Than Or Equal',
                'Not Equal',
                'Between',
                'Not Between',
            ],
        };
        this.#eff = effect(() => {
            this.onValueChanged.emit(this.queryData());
        }, ...(ngDevMode ? [{ debugName: "#eff" }] : []));
    }
    #eff;
    conditionHandler(e, i) {
        this.queryData.update((prev) => {
            const copy = [...prev];
            const find = this.recursiveFind(copy, (item) => item.id === i.id, 'rules');
            find.condition = e.data;
            return copy;
        });
    }
    columnDataHandler(e, i) {
        this.selectedItem.set(i);
        const selectedItem = e.component.selectedItems[0];
        this.queryData.update((prev) => {
            const copy = [...prev];
            const find = this.recursiveFind(copy, (item) => item.id === i.id, 'rules');
            find.label = selectedItem.label;
            find.field = selectedItem.field;
            find.type = selectedItem.type;
            if (selectedItem.values)
                find.inputValues = selectedItem.values;
            return copy;
        });
        this.selectBoxRef().refresh();
        this.selectBoxRef().reset();
    }
    operatorDataHandler(e, i) {
        this.queryData.update((prev) => {
            const copy = [...prev];
            const find = this.recursiveFind(copy, (item) => item.id === i.id, 'rules');
            find.operator = e.value;
            return copy;
        });
    }
    recursiveFind(array, predicate, nestedKey) {
        for (const item of array) {
            if (predicate(item)) {
                return item;
            }
            if (Array.isArray(item[nestedKey])) {
                const found = this.recursiveFind(item[nestedKey], predicate, nestedKey);
                if (found) {
                    return found;
                }
            }
        }
        return null;
    }
    recursiveRemove(array, predicate, nestedKey) {
        return array
            .filter((item) => !predicate(item))
            .map((item) => ({
            ...item,
            [nestedKey]: Array.isArray(item[nestedKey])
                ? this.recursiveRemove(item[nestedKey], predicate, nestedKey)
                : item[nestedKey],
        }));
    }
    addRulesHandler(i) {
        this.queryData.update((prev) => {
            const copy = [...prev];
            const find = this.recursiveFind(copy, (item) => item.id === i.id, 'rules');
            find.rules.push({
                id: Math.random(),
            });
            return copy;
        });
    }
    addGroupHandler(i) {
        this.queryData.update((prev) => {
            const copy = [...prev];
            const find = this.recursiveFind(copy, (item) => item.id === i.id, 'rules');
            find.rules.push({
                id: Math.random(),
                condition: 'and',
                rules: [{ id: Math.random() }],
            });
            return copy;
        });
    }
    booleanValueHandler(e, i) {
        this.queryData.update((prev) => {
            const copy = [...prev];
            const find = this.recursiveFind(copy, (item) => item.id === i.id, 'rules');
            find.value = e.target.value;
            return copy;
        });
    }
    stringValueHandler(e, i) {
        this.queryData.update((prev) => {
            const copy = [...prev];
            const find = this.recursiveFind(copy, (item) => item.id === i.id, 'rules');
            find.value = e.value;
            return copy;
        });
    }
    numberValueHandler(e, i) {
        this.queryData.update((prev) => {
            const copy = [...prev];
            const find = this.recursiveFind(copy, (item) => item.id === i.id, 'rules');
            find.value = e.value;
            return copy;
        });
    }
    dateValueHandler(e, i) {
        this.queryData.update((prev) => {
            const copy = [...prev];
            const find = this.recursiveFind(copy, (item) => item.id === i.id, 'rules');
            find.value = e.value;
            return copy;
        });
    }
    removeGroupHandler(i) {
        this.queryData.update((prev) => {
            const copy = [...prev];
            const filter = this.recursiveRemove(copy, (item) => item.id === i.id, 'rules');
            return filter;
        });
    }
    removeRulesHandler(i) {
        this.queryData.update((prev) => {
            const copy = [...prev];
            const filter = this.recursiveRemove(copy, (item) => item.id === i.id, 'rules');
            return filter;
        });
    }
    trackById(_, item) {
        return item.id;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXQueryBuilderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.3", type: AXQueryBuilderComponent, isStandalone: true, selector: "ax-query-builder", inputs: { columnData: { classPropertyName: "columnData", publicName: "columnData", isSignal: true, isRequired: true, transformFunction: null }, queryData: { classPropertyName: "queryData", publicName: "queryData", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { queryData: "queryDataChange", onValueChanged: "onValueChanged" }, providers: [{ provide: AXComponent, useExisting: AXQueryBuilderComponent }], viewQueries: [{ propertyName: "selectBoxRef", first: true, predicate: ["reRender"], descendants: true, isSignal: true }], ngImport: i0, template: "@for (item of queryData(); track trackById(i, item); let i = $index) {\n  <ng-container [ngTemplateOutletContext]=\"{ $implicit: item, index: i }\" [ngTemplateOutlet]=\"query\"> </ng-container>\n}\n\n<ng-template #query let-item let-index=\"index\">\n  @if (item.condition) {\n    <div class=\"ax-recursive-container\">\n      <div class=\"ax-add-condition-container\">\n        <ax-button-group\n          selection=\"single\"\n          (selectedButtonChange)=\"conditionHandler($event, item)\"\n          color=\"primary\"\n          class=\"ax-sm\"\n        >\n          <ax-button-group-item data=\"and\" [selected]=\"item.condition === 'and'\" text=\"And\"> </ax-button-group-item>\n          <ax-button-group-item data=\"or\" [selected]=\"item.condition === 'or'\" text=\"Or\"> </ax-button-group-item>\n        </ax-button-group>\n        <ax-button\n          (onClick)=\"addRulesHandler(item)\"\n          class=\"ax-sm\"\n          color=\"primary\"\n          look=\"blank\"\n          text=\"Add Rules\"\n        ></ax-button>\n        <ax-button\n          (onClick)=\"addGroupHandler(item)\"\n          class=\"ax-sm\"\n          color=\"primary\"\n          look=\"blank\"\n          text=\"Add Group\"\n        ></ax-button>\n        @if (index !== 0) {\n          <ax-button look=\"blank\" (onClick)=\"removeGroupHandler(item)\" class=\"ax-sm\" color=\"danger\">\n            <ax-icon icon=\"ax-icon ax-icon-trash\"></ax-icon>\n          </ax-button>\n        }\n      </div>\n\n      @for (child of item.rules; track trackById($index, child)) {\n        <ng-container [ngTemplateOutletContext]=\"{ $implicit: child }\" [ngTemplateOutlet]=\"query\"> </ng-container>\n      }\n    </div>\n  } @else {\n    <div class=\"ax-rules-container\">\n      <div class=\"ax-input-rules-container\">\n        <ax-select-box\n          (onValueChanged)=\"columnDataHandler($event, item)\"\n          valueField=\"field\"\n          textField=\"label\"\n          [dataSource]=\"columnData()\"\n          placeholder=\"Select Field\"\n        >\n        </ax-select-box>\n\n        <ax-select-box\n          #reRender\n          [disabled]=\"!item.field\"\n          name=\"selectBoxOperator\"\n          (onValueChanged)=\"operatorDataHandler($event, item)\"\n          [dataSource]=\"ds\"\n          placeholder=\"Select Operator\"\n        >\n        </ax-select-box>\n\n        @switch (item.type) {\n          @case ('boolean') {\n            <div class=\"ax-boolean-value-input-container\">\n              @for (boolean of item.inputValues; track $index) {\n                <label>{{ boolean }}</label>\n                <input name=\"same\" [value]=\"boolean\" (input)=\"booleanValueHandler($event, item)\" type=\"radio\" />\n              }\n            </div>\n          }\n          @case ('string') {\n            <ax-text-box (onValueChanged)=\"stringValueHandler($event, item)\">\n              <ax-clear-button></ax-clear-button>\n            </ax-text-box>\n          }\n          @case ('number') {\n            <ax-number-box (onValueChanged)=\"numberValueHandler($event, item)\"></ax-number-box>\n          }\n          @case ('date') {\n            <ax-datetime-box format=\"yyyy/MM/dd\" (onValueChanged)=\"dateValueHandler($event, item)\">\n              <ax-clear-button></ax-clear-button>\n            </ax-datetime-box>\n          }\n        }\n      </div>\n      <ax-button (onClick)=\"removeRulesHandler(item)\" look=\"blank\" class=\"ax-md\" color=\"danger\">\n        <ax-icon icon=\"ax-icon ax-icon-trash\"></ax-icon>\n      </ax-button>\n    </div>\n  }\n</ng-template>\n", styles: ["ax-query-builder{border:1px solid rgba(var(--ax-sys-color-border-lightest-surface));border-radius:var(--ax-sys-border-radius);padding:1rem;width:100%;display:block}ax-query-builder .ax-add-condition-container{display:flex;gap:.5rem;margin-block:.5rem}ax-query-builder .ax-recursive-container{border-inline-start:1px solid rgba(var(--ax-sys-color-border-lightest-surface));padding-inline-start:1rem}ax-query-builder .ax-rules-container{display:flex;align-items:center;margin-block:.5rem}ax-query-builder .ax-rules-container .ax-input-rules-container{display:flex;align-items:center;gap:.5rem;width:100%}ax-query-builder .ax-rules-container:not(:last-child){margin-bottom:.5rem}ax-query-builder .ax-boolean-value-input-container{display:flex;gap:.5rem;align-items:center}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AXButtonGroupComponent, selector: "ax-button-group", inputs: ["disabled", "color", "look", "fitParent", "selection"], outputs: ["onBlur", "onFocus", "lookChange", "colorChange", "disabledChange", "onClick", "selectionChange", "selectedButtonChange"] }, { kind: "component", type: AXButtonGroupItemComponent, selector: "ax-button-group-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "component", type: AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "maskPattern", "customTokens", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "onMaskChanged"] }, { kind: "component", type: AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: AXNumberBoxComponent, selector: "ax-number-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "minValue", "maxValue", "showSpinButtons", "thousandsSeparator", "decimals", "changeOnScroll", "step"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "thousandsSeparatorChange"] }, { kind: "component", type: AXDateTimeBoxComponent, selector: "ax-datetime-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "depth", "id", "type", "look", "holidayDates", "allowTyping", "picker", "calendar", "weekend", "weekdays", "format"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "onOpened", "onClosed", "readonlyChange", "disabledChange", "formatChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXQueryBuilderComponent, decorators: [{
            type: Component,
            args: [{ selector: 'ax-query-builder', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
                        NgTemplateOutlet,
                        AXButtonGroupComponent,
                        AXButtonGroupItemComponent,
                        AXButtonComponent,
                        AXDecoratorIconComponent,
                        AXSelectBoxComponent,
                        AXTextBoxComponent,
                        AXDecoratorClearButtonComponent,
                        AXNumberBoxComponent,
                        AXDateTimeBoxComponent,
                    ], providers: [{ provide: AXComponent, useExisting: AXQueryBuilderComponent }], template: "@for (item of queryData(); track trackById(i, item); let i = $index) {\n  <ng-container [ngTemplateOutletContext]=\"{ $implicit: item, index: i }\" [ngTemplateOutlet]=\"query\"> </ng-container>\n}\n\n<ng-template #query let-item let-index=\"index\">\n  @if (item.condition) {\n    <div class=\"ax-recursive-container\">\n      <div class=\"ax-add-condition-container\">\n        <ax-button-group\n          selection=\"single\"\n          (selectedButtonChange)=\"conditionHandler($event, item)\"\n          color=\"primary\"\n          class=\"ax-sm\"\n        >\n          <ax-button-group-item data=\"and\" [selected]=\"item.condition === 'and'\" text=\"And\"> </ax-button-group-item>\n          <ax-button-group-item data=\"or\" [selected]=\"item.condition === 'or'\" text=\"Or\"> </ax-button-group-item>\n        </ax-button-group>\n        <ax-button\n          (onClick)=\"addRulesHandler(item)\"\n          class=\"ax-sm\"\n          color=\"primary\"\n          look=\"blank\"\n          text=\"Add Rules\"\n        ></ax-button>\n        <ax-button\n          (onClick)=\"addGroupHandler(item)\"\n          class=\"ax-sm\"\n          color=\"primary\"\n          look=\"blank\"\n          text=\"Add Group\"\n        ></ax-button>\n        @if (index !== 0) {\n          <ax-button look=\"blank\" (onClick)=\"removeGroupHandler(item)\" class=\"ax-sm\" color=\"danger\">\n            <ax-icon icon=\"ax-icon ax-icon-trash\"></ax-icon>\n          </ax-button>\n        }\n      </div>\n\n      @for (child of item.rules; track trackById($index, child)) {\n        <ng-container [ngTemplateOutletContext]=\"{ $implicit: child }\" [ngTemplateOutlet]=\"query\"> </ng-container>\n      }\n    </div>\n  } @else {\n    <div class=\"ax-rules-container\">\n      <div class=\"ax-input-rules-container\">\n        <ax-select-box\n          (onValueChanged)=\"columnDataHandler($event, item)\"\n          valueField=\"field\"\n          textField=\"label\"\n          [dataSource]=\"columnData()\"\n          placeholder=\"Select Field\"\n        >\n        </ax-select-box>\n\n        <ax-select-box\n          #reRender\n          [disabled]=\"!item.field\"\n          name=\"selectBoxOperator\"\n          (onValueChanged)=\"operatorDataHandler($event, item)\"\n          [dataSource]=\"ds\"\n          placeholder=\"Select Operator\"\n        >\n        </ax-select-box>\n\n        @switch (item.type) {\n          @case ('boolean') {\n            <div class=\"ax-boolean-value-input-container\">\n              @for (boolean of item.inputValues; track $index) {\n                <label>{{ boolean }}</label>\n                <input name=\"same\" [value]=\"boolean\" (input)=\"booleanValueHandler($event, item)\" type=\"radio\" />\n              }\n            </div>\n          }\n          @case ('string') {\n            <ax-text-box (onValueChanged)=\"stringValueHandler($event, item)\">\n              <ax-clear-button></ax-clear-button>\n            </ax-text-box>\n          }\n          @case ('number') {\n            <ax-number-box (onValueChanged)=\"numberValueHandler($event, item)\"></ax-number-box>\n          }\n          @case ('date') {\n            <ax-datetime-box format=\"yyyy/MM/dd\" (onValueChanged)=\"dateValueHandler($event, item)\">\n              <ax-clear-button></ax-clear-button>\n            </ax-datetime-box>\n          }\n        }\n      </div>\n      <ax-button (onClick)=\"removeRulesHandler(item)\" look=\"blank\" class=\"ax-md\" color=\"danger\">\n        <ax-icon icon=\"ax-icon ax-icon-trash\"></ax-icon>\n      </ax-button>\n    </div>\n  }\n</ng-template>\n", styles: ["ax-query-builder{border:1px solid rgba(var(--ax-sys-color-border-lightest-surface));border-radius:var(--ax-sys-border-radius);padding:1rem;width:100%;display:block}ax-query-builder .ax-add-condition-container{display:flex;gap:.5rem;margin-block:.5rem}ax-query-builder .ax-recursive-container{border-inline-start:1px solid rgba(var(--ax-sys-color-border-lightest-surface));padding-inline-start:1rem}ax-query-builder .ax-rules-container{display:flex;align-items:center;margin-block:.5rem}ax-query-builder .ax-rules-container .ax-input-rules-container{display:flex;align-items:center;gap:.5rem;width:100%}ax-query-builder .ax-rules-container:not(:last-child){margin-bottom:.5rem}ax-query-builder .ax-boolean-value-input-container{display:flex;gap:.5rem;align-items:center}\n"] }]
        }] });

const COMPONENT = [AXQueryBuilderComponent];
const MODULES = [
    AXButtonGroupModule,
    AXDecoratorModule,
    AXSelectBoxModule,
    AXButtonModule,
    AXTextBoxModule,
    AXNumberBoxModule,
    AXDateTimeBoxModule,
    CommonModule,
];
class AXQueryBuilderModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXQueryBuilderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.3", ngImport: i0, type: AXQueryBuilderModule, imports: [AXButtonGroupModule,
            AXDecoratorModule,
            AXSelectBoxModule,
            AXButtonModule,
            AXTextBoxModule,
            AXNumberBoxModule,
            AXDateTimeBoxModule,
            CommonModule, AXQueryBuilderComponent], exports: [AXQueryBuilderComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXQueryBuilderModule, imports: [MODULES, COMPONENT] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXQueryBuilderModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [...MODULES, ...COMPONENT],
                    exports: [...COMPONENT],
                    providers: [],
                }]
        }] });

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

export { AXQueryBuilderComponent, AXQueryBuilderModule };
//# sourceMappingURL=acorex-components-query-builder.mjs.map
