import * as _angular_core from '@angular/core';
import { AfterViewInit, InjectionToken, Type } from '@angular/core';
import { LookupMatrixFieldConfig, LookupOptionItemConfig, LookupMatrixCellConfig, SchedulePredecessorFieldRuntimeContext, EntityListFieldRuntimeContext } from '@masterteam/components';
import { ControlValueAccessor, Validators, NgControl } from '@angular/forms';
import { HttpContext } from '@angular/common/http';
import { ColumnDef, TableAction } from '@masterteam/components/table';
import { EntityData } from '@masterteam/components/entities';

declare class LookupMatrixField implements AfterViewInit {
    readonly config: _angular_core.InputSignal<LookupMatrixFieldConfig>;
    private readonly controlContainer;
    private readonly destroyRef;
    private readonly transloco;
    private readonly valueVersion;
    private subscribedControl;
    readonly hasYAxis: _angular_core.Signal<boolean>;
    readonly xOptions: _angular_core.Signal<LookupOptionItemConfig[]>;
    readonly yOptions: _angular_core.Signal<LookupOptionItemConfig[]>;
    readonly hasMatrix: _angular_core.Signal<boolean>;
    readonly cellMap: _angular_core.Signal<Map<string, LookupMatrixCellConfig>>;
    readonly selectedXOption: _angular_core.Signal<LookupOptionItemConfig | null>;
    readonly selectedYOption: _angular_core.Signal<LookupOptionItemConfig | null>;
    readonly activeCell: _angular_core.Signal<LookupMatrixCellConfig | null>;
    readonly selectionSummary: _angular_core.Signal<string>;
    readonly pendingMessage: _angular_core.Signal<string>;
    readonly missingResultMessage: _angular_core.Signal<string>;
    ngAfterViewInit(): void;
    getCell(xLookupItemId: number | string, yLookupItemId?: number | string): LookupMatrixCellConfig | null;
    getSwatchColor(color?: string | null): string | null;
    private getControlValue;
    private ensureControlSubscription;
    private resolveSelectedOption;
    private optionMatchesValue;
    private cellKey;
    private resolveColor;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<LookupMatrixField, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<LookupMatrixField, "mt-lookup-matrix-field", never, { "config": { "alias": "config"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
}

/**
 * One source level inside connection configuration.
 * Comes from `field.propertyMetadata.configuration.sourceLevels[]`
 *
 * A source can be either a **level** (has `levelId`/`levelKey`) or a
 * **module** (has `moduleId`/`moduleKey`). Exactly one pair will be present.
 */
interface ConnectionSourceLevel {
    /** Present for level-type sources */
    levelId?: number;
    /** Present for level-type sources */
    levelKey?: string;
    /** Present for module-type sources */
    moduleId?: number;
    /** Present for module-type sources */
    moduleKey?: string;
    name: {
        en?: string;
        ar?: string;
        [k: string]: string | undefined;
    };
    connectionId: number;
    isOptional: boolean;
    allowManyToMany: boolean;
    supportWeights: boolean;
    optionsQuery: {
        path: string;
        method?: string;
        query?: Record<string, unknown>;
    };
}
/**
 * Full connection configuration from `field.propertyMetadata.configuration`.
 * This is passed as a single input to the component.
 */
interface SchemaConnectionConfig {
    targetLevelId: number;
    sourceLevelId?: number;
    propertyKey?: string;
    valueMode?: string;
    sourceLevels: ConnectionSourceLevel[];
    payloadTemplate?: {
        levelId: number;
        sources: any[];
    };
    sourceItemShape?: Record<string, string>;
}
/** One selected source in the connection payload */
interface ConnectionSource {
    sourceLevelId: number;
    sourceLevelDataId: number;
}
/** The value shape for a connection field */
interface ConnectionPayload {
    levelId: number;
    sources: ConnectionSource[];
}
/**
 * Internal state tracked per source level dropdown.
 */
interface SourceLevelState {
    source: ConnectionSourceLevel;
    options: any[];
    loading: boolean;
}
declare class SchemaConnectionField implements ControlValueAccessor {
    readonly label: _angular_core.InputSignal<string>;
    readonly placeholder: _angular_core.InputSignal<string>;
    readonly readonly: _angular_core.InputSignal<boolean>;
    readonly required: _angular_core.InputSignal<boolean>;
    readonly filter: _angular_core.InputSignal<boolean>;
    /**
     * Full connection configuration object from the API.
     * Includes `targetLevelId`, `sourceLevels[]`, `payloadTemplate`, etc.
     */
    readonly configuration: _angular_core.InputSignal<SchemaConnectionConfig>;
    /**
     * Optional HttpContext for API requests (e.g. to set base URL behavior).
     */
    readonly context: _angular_core.InputSignal<HttpContext | undefined>;
    /** The full ConnectionPayload value */
    value: _angular_core.WritableSignal<ConnectionPayload | null>;
    disabled: _angular_core.WritableSignal<boolean>;
    /** Per-source-level state: options + loading */
    sourceLevelStates: _angular_core.WritableSignal<SourceLevelState[]>;
    /** Mutable selections per source level: sourceLevelId -> selected value */
    selections: Record<number, any>;
    requiredValidator: typeof Validators.required;
    onTouched: () => void;
    onModelChange: (value: ConnectionPayload | null) => void;
    ngControl: NgControl | null;
    private http;
    private destroyRef;
    /**
     * Source levels from configuration.
     */
    readonly sourceLevels: _angular_core.Signal<ConnectionSourceLevel[]>;
    /**
     * Percentage width for each dropdown, evenly divided.
     */
    readonly dropdownWidth: _angular_core.Signal<string>;
    constructor();
    /**
     * Returns a stable numeric ID for a source regardless of whether it is a
     * level (`levelId`) or a module (`moduleId`). Used as the key in `selections`
     * and `sourceLevelStates`.
     */
    protected getSourceId(source: ConnectionSourceLevel): number;
    /**
     * Builds the `contextKey` for the `fetch/query` request based on source type.
     */
    private getContextKey;
    private loadOptions;
    private updateSourceState;
    /**
     * Single handler — no params. Reads all selections, builds the combined payload.
     */
    syncValue(): void;
    private distributeToSelections;
    writeValue(value: ConnectionPayload | string | null): void;
    registerOnChange(fn: (value: ConnectionPayload | null) => void): void;
    registerOnTouched(fn: any): void;
    setDisabledState(disabled: boolean): void;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<SchemaConnectionField, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<SchemaConnectionField, "mt-schema-connection-field", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "configuration": { "alias": "configuration"; "required": true; "isSignal": true; }; "context": { "alias": "context"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
}

type PredecessorType = 0 | 1 | 2 | 3;
interface SchedulePredecessorValue {
    predecessorId: number | string;
    type: PredecessorType;
    lagDays: number;
}
interface SchedulePredecessorRow extends SchedulePredecessorValue {
    key: string;
}
interface SelectOption {
    label: string;
    value: number | string;
}
declare class SchedulePredecessorField implements ControlValueAccessor {
    private readonly predecessorCellTpl;
    private readonly typeCellTpl;
    private readonly lagCellTpl;
    readonly label: _angular_core.InputSignal<string>;
    readonly placeholder: _angular_core.InputSignal<string>;
    readonly readonly: _angular_core.InputSignal<boolean>;
    readonly required: _angular_core.InputSignal<boolean>;
    readonly configuration: _angular_core.InputSignal<unknown>;
    readonly runtimeContext: _angular_core.InputSignal<SchedulePredecessorFieldRuntimeContext | null>;
    readonly loading: _angular_core.WritableSignal<boolean>;
    readonly taskOptions: _angular_core.WritableSignal<SelectOption[]>;
    readonly rows: _angular_core.WritableSignal<SchedulePredecessorRow[]>;
    readonly disabled: _angular_core.WritableSignal<boolean>;
    readonly typeOptions: _angular_core.Signal<SelectOption[]>;
    readonly availableTaskOptions: _angular_core.Signal<SelectOption[]>;
    readonly canAddRow: _angular_core.Signal<boolean>;
    readonly addTooltip: _angular_core.Signal<string | undefined>;
    readonly pageSize: _angular_core.Signal<number>;
    readonly columns: _angular_core.WritableSignal<ColumnDef[]>;
    readonly rowActions: _angular_core.Signal<TableAction[]>;
    requiredValidator: typeof Validators.required;
    onTouched: () => void;
    onModelChange: (value: string | null) => void;
    ngControl: NgControl | null;
    private readonly http;
    private readonly transloco;
    private readonly destroyRef;
    private readonly activeLang;
    private rowKey;
    readonly texts: _angular_core.Signal<{
        noAvailable: string;
        predecessor: string;
        type: string;
        lagDays: string;
        delete: string;
    }>;
    constructor();
    addRow(): void;
    removeRow(key: string): void;
    updateRow(key: string, patch: Partial<SchedulePredecessorRow>): void;
    writeValue(value: unknown): void;
    registerOnChange(fn: (value: string | null) => void): void;
    registerOnTouched(fn: () => void): void;
    setDisabledState(disabled: boolean): void;
    private syncRows;
    private loadTaskOptions;
    private mapTaskOptions;
    private resolveRootRecords;
    private flattenRecords;
    private nextRowKey;
    private parseCompactValue;
    private formatCompactValue;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<SchedulePredecessorField, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<SchedulePredecessorField, "mt-schedule-predecessor-field", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "configuration": { "alias": "configuration"; "required": false; "isSignal": true; }; "runtimeContext": { "alias": "runtimeContext"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
}

interface EntityListColumnDef extends ColumnDef {
    key: string;
    label: string;
    type: 'entity';
    viewType?: string;
    order?: number;
    visible?: boolean;
    configuration?: Record<string, unknown> | null;
    /** Underlying catalog property key (e.g. "task_name") used to look up
     *  form values keyed by property key when a new row is added locally. */
    propertyKey?: string;
}
type EntityListRow = Record<string, unknown | EntityData>;
/** Stored EntityList property value (round-tripped through the form). */
interface EntityListStoredValue {
    entityIds?: number[];
    createdIds?: number[];
    updatedIds?: number[];
    deletedIds?: number[];
    snapshot?: unknown;
    rows?: unknown[];
}
declare class EntityListField implements ControlValueAccessor {
    readonly label: _angular_core.InputSignal<string>;
    readonly readonly: _angular_core.InputSignal<boolean>;
    readonly required: _angular_core.InputSignal<boolean>;
    /** EntityList property id (kept for back-compat; unused by fetch/query). */
    readonly propertyId: _angular_core.InputSignal<number | null>;
    /** Property configuration (sourceType, moduleId, access, readFields, etc). */
    readonly configuration: _angular_core.InputSignal<Record<string, unknown> | null>;
    /** Runtime ids needed to call the read endpoint. */
    readonly runtimeContext: _angular_core.InputSignal<EntityListFieldRuntimeContext | null>;
    /** Optional HttpContext (kept for back-compat). */
    readonly context: _angular_core.InputSignal<HttpContext | undefined>;
    private readonly storedValue;
    protected readonly columns: _angular_core.WritableSignal<EntityListColumnDef[]>;
    protected readonly rows: _angular_core.WritableSignal<EntityListRow[]>;
    protected readonly loading: _angular_core.WritableSignal<boolean>;
    protected readonly errorMessage: _angular_core.WritableSignal<string | null>;
    protected readonly disabled: _angular_core.WritableSignal<boolean>;
    protected requiredValidator: typeof Validators.required;
    ngControl: NgControl | null;
    protected readonly levelId: _angular_core.Signal<string | number | null>;
    protected readonly levelDataId: _angular_core.Signal<string | number | null>;
    protected readonly moduleId: _angular_core.Signal<string | number | null>;
    protected readonly readFields: _angular_core.Signal<string[]>;
    protected readonly canRead: _angular_core.Signal<boolean>;
    protected readonly canWrite: _angular_core.Signal<boolean>;
    protected readonly writeFields: _angular_core.Signal<string[]>;
    /** Locally-added rows (Write mode). Persisted via CVA value. */
    protected readonly localRows: _angular_core.WritableSignal<EntityListRow[]>;
    private localRowSeq;
    protected readonly displayRows: _angular_core.Signal<EntityListRow[]>;
    protected readonly hasRows: _angular_core.Signal<boolean>;
    protected readonly hasRequiredContext: _angular_core.Signal<boolean>;
    protected onTouched: () => void;
    protected onModelChange: (value: EntityListStoredValue | null) => void;
    private readonly http;
    private readonly destroyRef;
    private readonly modal;
    private readonly transloco;
    /**
     * Optional rich add-row dialog (provided by `@masterteam/forms` via
     * `provideEntityListAddForm()`). When available, used instead of the local
     * minimal dialog so the popup renders `mt-client-form` filtered by
     * `writeFields`.
     */
    private readonly addDialogComponent;
    constructor();
    writeValue(value: EntityListStoredValue | null): void;
    registerOnChange(fn: (value: EntityListStoredValue | null) => void): void;
    registerOnTouched(fn: () => void): void;
    setDisabledState(isDisabled: boolean): void;
    /** Row actions shown in Write mode — edit and delete (local-only). */
    protected readonly writeRowActions: _angular_core.Signal<TableAction[]>;
    protected openAddDialog(): void;
    protected openEditDialog(row: EntityListRow): void;
    protected deleteLocalRow(row: EntityListRow): void;
    private buildRowFromValues;
    private emitLocalValue;
    private fetchRows;
    private applyResponse;
    private toEntityData;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<EntityListField, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<EntityListField, "mt-entity-list-field", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "propertyId": { "alias": "propertyId"; "required": false; "isSignal": true; }; "configuration": { "alias": "configuration"; "required": false; "isSignal": true; }; "runtimeContext": { "alias": "runtimeContext"; "required": false; "isSignal": true; }; "context": { "alias": "context"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
}

/** Inputs the EntityList add-row dialog will receive via ModalService inputValues. */
interface EntityListAddDialogInputs {
    moduleId: number | string | null;
    levelId: number | string | null;
    levelDataId: number | string | null;
    /** Property keys that should be editable in the dialog. */
    writeFields: string[];
    /** Pre-populated form values (keyed by property key) for the Edit flow. */
    initialValues?: Record<string, unknown>;
}
/**
 * Token used by `mt-entity-list-field` (Write mode) to open the rich add-row
 * dialog backed by `@masterteam/forms`'s `mt-client-form`. Apps that want this
 * behavior should call `provideEntityListAddForm()` from
 * `@masterteam/forms/entity-list-add-form` in their app providers. When the
 * token is not registered, the field falls back to a minimal text-only popup.
 */
declare const ENTITY_LIST_ADD_DIALOG_COMPONENT: InjectionToken<Type<unknown>>;

export { ENTITY_LIST_ADD_DIALOG_COMPONENT, EntityListField, LookupMatrixField, SchedulePredecessorField, SchemaConnectionField };
export type { ConnectionPayload, ConnectionSource, ConnectionSourceLevel, EntityListAddDialogInputs, SchemaConnectionConfig, SourceLevelState };
