import { __decorate } from "tslib";
import { attr, Observable, observable } from '@ni/fast-element';
import { TableColumn } from '../base';
import { Mapping } from '../../mapping/base';
import { resolveKeyWithType } from './models/mapping-key-resolver';
/**
 * Base class for table columns that map values to content
 */
export class TableColumnEnumBase extends TableColumn {
    constructor() {
        super(...arguments);
        /** @internal */
        this.mappingNotifiers = [];
        /** @internal */
        this.mappings = [];
        this.keyType = 'string';
    }
    /**
     * @internal
     *
     * Triggers a request to update the columnConfig when any observable property on
     * a mapping is updated.
     */
    handleChange(source, args) {
        if (source instanceof Mapping && typeof args === 'string') {
            this.updateColumnConfig();
        }
    }
    /**
     * Called when any Mapping related state has changed.
     */
    updateColumnConfig() {
        this.columnInternals.validator.validate(this.mappings, this.keyType);
        this.columnInternals.columnConfig = this.checkValidity()
            ? this.createColumnConfig(this.getMappingConfigs())
            : undefined;
    }
    getMappingConfigs() {
        const mappingConfigs = new Map();
        this.mappings.forEach(mapping => {
            const key = resolveKeyWithType(mapping.key, this.keyType);
            if (key === undefined) {
                throw Error('Key was invalid for type. Validation should have prevented this.');
            }
            const mappingConfig = this.createMappingConfig(mapping);
            mappingConfigs.set(key, mappingConfig);
        });
        return mappingConfigs;
    }
    fieldNameChanged() {
        this.columnInternals.dataRecordFieldNames = [this.fieldName];
        this.columnInternals.operandDataRecordFieldName = this.fieldName;
    }
    mappingsChanged() {
        this.updateColumnConfig();
        this.observeMappings();
    }
    keyTypeChanged() {
        this.updateColumnConfig();
    }
    removeMappingObservers() {
        this.mappingNotifiers.forEach(notifier => {
            notifier.unsubscribe(this);
        });
        this.mappingNotifiers = [];
    }
    observeMappings() {
        this.removeMappingObservers();
        for (const mapping of this.mappings) {
            const notifier = Observable.getNotifier(mapping);
            notifier.subscribe(this);
            this.mappingNotifiers.push(notifier);
        }
    }
}
__decorate([
    observable
], TableColumnEnumBase.prototype, "mappings", void 0);
__decorate([
    attr({ attribute: 'field-name' })
], TableColumnEnumBase.prototype, "fieldName", void 0);
__decorate([
    attr({ attribute: 'key-type' })
], TableColumnEnumBase.prototype, "keyType", void 0);
//# sourceMappingURL=index.js.map