import { type DataRecord, Dictionary as SchemasDictionary, DictionaryValidationError, DictionaryValidationRecordErrorDetails, Schema, TestResult } from '@overture-stack/lectern-client';
import { type Submission, SubmissionData, type SubmissionDeleteData, type SubmissionInsertData, type SubmissionUpdateData, type SubmittedData } from '@overture-stack/lyric-data-model/models';
import type { SchemaChildNode } from './dictionarySchemaRelations.js';
import { type DataRecordReference, type EditSubmittedDataReference, type NewSubmittedDataReference, type SubmissionActionType, type SubmissionResponse, type SubmissionStatus, type SubmissionSummaryRepository, type SubmissionSummaryResponse, SubmittedDataReference } from './types.js';
declare const statusesAllowedToClose: readonly ["OPEN", "VALID", "INVALID"];
type StatusesAllowedToClose = typeof statusesAllowedToClose extends Array<infer T> ? T : never;
/** Determines if a Submission can be closed based on it's current status
 * @param {SubmissionStatus} status Status of a Submission
 * @returns {boolean}
 */
export declare const canTransitionToClosed: (status: SubmissionStatus) => status is StatusesAllowedToClose;
/**
 * Checks if object is a Submission or a SubmittedData
 * @param {SubmittedDataReference | NewSubmittedDataReference | EditSubmittedDataReference} toBeDetermined
 * @returns {boolean}
 */
export declare const determineIfIsSubmission: (reference: SubmittedDataReference | NewSubmittedDataReference | EditSubmittedDataReference) => reference is NewSubmittedDataReference | EditSubmittedDataReference;
/**
 * Creates a Record type of DataRecord[] grouped by Entity names
 * @param {Record<string, DataRecordReference[]>} mergeDataRecordsByEntityName
 * @returns {Record<string, DataRecord[]>}
 */
export declare const extractSchemaDataFromMergedDataRecords: (mergeDataRecordsByEntityName: Record<string, DataRecordReference[]>) => Record<string, DataRecord[]>;
/**
 * Finds and returns a list of invalid records based on a provided schema name.
 *
 * This function checks if the validation results are marked as invalid, and if so,
 * filters the validation errors to return those related to a specific schema name.
 *
 * @param results - The validation results containing details of validation errors.
 * @param entityName - The name of the schema to filter the invalid records by.
 *
 * @returns An array of invalid records for the specified schema, or an empty array if none are found.
 */
export declare const findInvalidRecordErrorsBySchemaName: (results: TestResult<DictionaryValidationError[]>, entityName: string) => import("@overture-stack/lectern-client").SchemaRecordError<DictionaryValidationRecordErrorDetails>[];
/**
 * Generalized function to filter out conflicting records between two data sets based on `systemId`.
 *
 * This function can be used to either filter updates from deletes or deletes from updates, depending on the provided parameters.
 * It removes records from the `sourceData` that have a matching `systemId` in the `conflictData`.
 *
 * @param sourceData - A record of the primary data (e.g., updates or deletes) to be filtered, grouped by entity name.
 * @param conflictData - A record of data that might conflict (e.g., deletes or updates), grouped by entity name.
 * @param entitySelector - A function to select the `systemId` from the source records.
 * @param conflictSelector - A function to select the `systemId` from the conflict records.
 * @returns A record of filtered source data, excluding records that conflict based on `systemId`.
 */
export declare const filterRecordsByConflicts: <SourceData, ConflictData>(sourceData: Record<string, SourceData[]>, conflictData: Record<string, ConflictData[]>, entitySelector: (item: SourceData) => string, conflictSelector: (item: ConflictData) => string) => Record<string, SourceData[]>;
/**
 * Filters updates from the provided `submissionUpdateData` based on conflicts found in the `submissionDeleteData`.
 * Conflicts are determined by matching the `systemId` of the items in both records.
 *
 * @param submissionUpdateData - A record containing arrays of `SubmissionUpdateData` to be filtered.
 * @param submissionDeleteData - A record containing arrays of `SubmissionDeleteData` that defines the conflicts.
 * @returns A filtered record of `SubmissionUpdateData[]` where no items conflict with those in `submissionDeleteData`.
 */
export declare const filterUpdatesFromDeletes: (submissionUpdateData: Record<string, SubmissionUpdateData[]>, submissionDeleteData: Record<string, SubmissionDeleteData[]>) => Record<string, SubmissionUpdateData[]>;
/**
 * Filters deletes from the provided `submissionDeleteData` based on conflicts found in the `submissionUpdateData`.
 * Conflicts are determined by matching the `systemId` of the items in both records.
 *
 * @param submissionDeleteData - A record containing arrays of `SubmissionDeleteData` to be filtered.
 * @param submissionUpdateData - A record containing arrays of `SubmissionUpdateData` that defines the conflicts.
 * @returns A filtered record of `SubmissionDeleteData[]` where no items conflict with those in `submissionUpdateData`.
 */
export declare const filterDeletesFromUpdates: (submissionDeleteData: Record<string, SubmissionDeleteData[]>, submissionUpdateData: Record<string, SubmissionUpdateData[]>) => Record<string, SubmissionDeleteData[]>;
/**
 * Returns a filter to query the database used to find dependents records when the update record involves changes of an primary ID field
 *
 * @param schemaRelations An array of `SchemaChildNode` representing the schema relations for the entity. Each node contains information about parent-child relationships.
 * @param updateRecord The update record containing old and new data. The function checks the `old` data to identify fields involved in the relationship.
 * @returns
 */
export declare const filterRelationsForPrimaryIdUpdate: (schemaRelations: SchemaChildNode[], updateRecord: SubmissionUpdateData) => {
    entityName: string;
    dataField: string;
    dataValue: string | undefined;
}[];
/**
 * Returns only the schema errors corresponding to the Active Submission.
 * Schema errors are grouped by Entity name.
 * @param {object} input
 * @param {TestResult<DictionaryValidationError[]>} input.resultValidation
 * @param {Record<string, DataRecordReference[]>} input.dataValidated
 * @returns {Record<string, Record<string, DictionaryValidationRecordErrorDetails[]>>}
 */
export declare const groupSchemaErrorsByEntity: (input: {
    resultValidation: TestResult<DictionaryValidationError[]>;
    dataValidated: Record<string, DataRecordReference[]>;
}) => Record<string, Record<string, DictionaryValidationRecordErrorDetails[]>>;
/**
 * This function extracts the Schema Data from the Active Submission
 * and maps it to it's original reference Id
 * The result mapping is used to perform the cross schema validation
 * @param {number} activeSubmissionId
 * @param {Record<string, SubmissionInsertData>} activeSubmissionInsertDataEntities
 * @returns {Record<string, DataRecordReference[]>}
 */
export declare const mapInsertDataToRecordReferences: (activeSubmissionId: number, activeSubmissionInsertDataEntities: Record<string, SubmissionInsertData>) => Record<string, DataRecordReference[]>;
/**
 * This function takes a collection of dependent data grouped by entity name, applies a filter to each entity,
 * and creates a mapping of `SubmissionUpdateData` based on the specified filter and new data values.
 *
 * @param params
 * @param param.dependentData A record where each key is an entity name and each value is an array of `SubmittedData` objects.
 * @param param.filterEntity An array of filter criteria where each entry contains an `entityName`, `dataField`, and `dataValue` to filter.
 * @param param.newDataRecord A record containing new data values to be applied to the filtered entities.
 * @returns
 */
export declare const mapGroupedUpdateSubmissionData: ({ dependentData, filterEntity, newDataRecord, }: {
    dependentData: Record<string, SubmittedData[]>;
    filterEntity: {
        entityName: string;
        dataField: string;
        dataValue: string | undefined;
    }[];
    newDataRecord: DataRecord;
}) => Record<string, SubmissionUpdateData[]>;
/**
 * Combines **Active Submission** and the **Submitted Data** recevied as arguments.
 * Then, the Schema Data is extracted and mapped with its internal reference ID.
 * The returned Object is a collection of the raw Schema Data with it's reference ID grouped by entity name.
 * @param {Submission} originalSubmission The Active Submission to be merged
 * @param {Object} submissionData
 * @param {Record<string, SubmissionInsertData>} submissionData.insertData Collection of Data records of the Active Submission
 * @param {Record<string, SubmissionUpdateData[]>} submissionData.updateData Collection of Data records of the Active Submission
 * @param {Record<string, SubmissionDeleteData[]>} submissionData.deleteData Collection of Data records of the Active Submission
 * @param {number} submissionData.id ID of the Active Submission
 * @param {SubmittedData[]} submittedData An array of Submitted Data
 * @returns {Record<string, DataRecordReference[]>}
 */
export declare const mergeAndReferenceEntityData: ({ originalSubmission, submissionData, submittedData, }: {
    originalSubmission: Submission;
    submissionData: SubmissionData;
    submittedData: SubmittedData[];
}) => Record<string, DataRecordReference[]>;
/**
 * Merges multiple `Record<string, SubmissionInsertData>` objects into a single object.
 * If there are duplicate keys between the objects, the `records` arrays of `SubmissionInsertData`
 * are concatenated for the matching keys, ensuring no duplicates.
 *
 * @param objects An array of objects where each object is a `Record<string, SubmissionInsertData>`.
 * Each key represents the entityName, and the value is an object of type `SubmissionInsertData`.
 *
 * @returns A new `Record<string, SubmissionInsertData>` where:
 * - If a key is unique across all objects, its value is directly included.
 * - If a key appears in multiple objects, the `records` arrays are concatenated for that key, avoiding duplicates.
 */
export declare const mergeInsertsRecords: (...objects: Record<string, SubmissionInsertData>[]) => Record<string, SubmissionInsertData>;
/**
 * Merges multiple `Record<string, SubmissionDeleteData[]>` objects into a single object.
 * For each key, the `SubmissionDeleteData[]` arrays are concatenated, ensuring no duplicate
 * `SubmissionDeleteData` objects based on the `systemId` field.
 *
 * @param objects Multiple `Record<string, SubmissionDeleteData[]>` objects to be merged.
 * Each key represents an identifier, and the value is an array of `SubmissionDeleteData`.
 *
 * @returns
 */
export declare const mergeDeleteRecords: (...objects: Record<string, SubmissionDeleteData[]>[]) => Record<string, SubmissionDeleteData[]>;
/**
 * Merge Active Submission data with incoming TSV file data processed
 *
 * @param objects
 * @returns An arbitrary number of arrays of Record<string, SubmissionUpdateData[]>
 */
export declare const mergeUpdatesBySystemId: (...objects: Record<string, SubmissionUpdateData[]>[]) => Record<string, SubmissionUpdateData[]>;
/**
 * Utility to parse a raw Submission to a Response type
 * @param {SubmissionSummaryRepository} submission
 * @returns {SubmissionResponse}
 */
export declare const parseSubmissionResponse: (submission: SubmissionSummaryRepository) => SubmissionResponse;
/**
 * Utility to parse a raw Submission to a Summary of the Submission
 * @param {SubmissionSummaryRepository} submission
 * @returns {SubmissionSummaryResponse}
 */
export declare const parseSubmissionSummaryResponse: (submission: SubmissionSummaryRepository) => SubmissionSummaryResponse;
export declare const pluralizeSchemaName: (schemaName: string) => string;
export declare const removeItemsFromSubmission: (submissionData: SubmissionData, filter: {
    actionType: SubmissionActionType;
    entityName: string;
    index: number | null;
}) => SubmissionData;
/**
 * Processes the `foundDependentUpdates` array and segregates the updates based on
 * whether they involve ID fields (dependent fields) or non-ID fields.
 *
 * @param foundDependentUpdates - Array of updates to be processed.
 * @param filesDataProcessed - Record where the key is a string (representing an entity name) and
 * each value is an array of `SubmissionUpdateData`. These are the processed data files to match against.
 * @returns An object containing two records:
 * - `idFieldChangeRecord`: A record of updates involving ID fields.
 * - `nonIdFieldChangeRecord`: A record of updates involving non-ID fields.
 */
export declare const segregateFieldChangeRecords: (submissionUpdateRecords: Record<string, SubmissionUpdateData[]>, dictionaryRelations: Record<string, SchemaChildNode[]>) => {
    idFieldChangeRecord: Record<string, SubmissionUpdateData[]>;
    nonIdFieldChangeRecord: Record<string, SubmissionUpdateData[]>;
};
/**
 * Validate a full set of Schema Data using a Dictionary
 * @param {SchemasDictionary & {id: number }} dictionary
 * @param {Record<string, DataRecord[]>} schemasData
 * @returns  A TestResult object representing the outcome of a test applied to some data.
 * If a test is valid, no additional data is added to the result. If it is invalid, then the
 * reason (or array of reasons) for why the test failed should be given.
 */
export declare const validateSchemas: (dictionary: SchemasDictionary & {
    id: number;
}, schemasData: Record<string, DataRecord[]>) => TestResult<DictionaryValidationError[]>;
export declare const parseToSchema: (schema: Schema) => (record: Record<string, string>) => DataRecord;
export {};
