import { canonicalWorkbookAddress, canonicalWorkbookRangeRef } from './workbook-range-records.js';
import { chartKey, imageKey, shapeKey, definedNameKey, normalizeWorkbookObjectName, pivotKey, } from './workbook-metadata-types.js';
import { cloneMergeRangeRecord, mergeRangeKey } from './workbook-merge-records.js';
export function cloneDefinedNameRecord(record) {
    return {
        name: record.name,
        ...(record.scopeSheetName !== undefined ? { scopeSheetName: record.scopeSheetName } : {}),
        value: cloneDefinedNameValue(record.value),
    };
}
export function cloneDefinedNameValue(value) {
    if (value === null || typeof value !== 'object') {
        return value;
    }
    switch (value.kind) {
        case 'scalar':
            return { kind: 'scalar', value: value.value };
        case 'cell-ref':
            return { kind: 'cell-ref', sheetName: value.sheetName, address: value.address };
        case 'range-ref':
            return {
                kind: 'range-ref',
                sheetName: value.sheetName,
                startAddress: value.startAddress,
                endAddress: value.endAddress,
            };
        case 'structured-ref':
            return {
                kind: 'structured-ref',
                tableName: value.tableName,
                columnName: value.columnName,
            };
        case 'formula':
            return { kind: 'formula', formula: value.formula };
        default:
            return value;
    }
}
export function clonePropertyRecord(record) {
    return structuredClone(record);
}
export function cloneWorkbookProtectionRecord(record) {
    return structuredClone(record);
}
export function cloneMacroPayloadRecord(record) {
    return structuredClone(record);
}
export function cloneTableRecord(record) {
    return structuredClone(record);
}
export function cloneFilterRecord(record) {
    return structuredClone(record);
}
export function cloneSortKeyRecord(record) {
    return { ...record };
}
export function cloneSortRecord(record) {
    return structuredClone(record);
}
function cloneValidationListSource(source) {
    switch (source.kind) {
        case 'named-range':
            return { kind: 'named-range', name: source.name };
        case 'cell-ref':
            return {
                kind: 'cell-ref',
                sheetName: source.sheetName,
                address: canonicalWorkbookAddress(source.sheetName, source.address),
            };
        case 'range-ref':
            return {
                kind: 'range-ref',
                ...canonicalWorkbookRangeRef({
                    sheetName: source.sheetName,
                    startAddress: source.startAddress,
                    endAddress: source.endAddress,
                }),
            };
        case 'structured-ref':
            return {
                kind: 'structured-ref',
                tableName: source.tableName,
                columnName: source.columnName,
            };
        case 'formula':
            return { kind: 'formula', formula: source.formula };
    }
}
export function cloneDataValidationRule(rule) {
    switch (rule.kind) {
        case 'list': {
            const cloned = {
                kind: 'list',
            };
            if (rule.values) {
                cloned.values = [...rule.values];
            }
            if (rule.source) {
                cloned.source = cloneValidationListSource(rule.source);
            }
            return cloned;
        }
        case 'checkbox': {
            const cloned = {
                kind: 'checkbox',
            };
            if (rule.checkedValue !== undefined) {
                cloned.checkedValue = rule.checkedValue;
            }
            if (rule.uncheckedValue !== undefined) {
                cloned.uncheckedValue = rule.uncheckedValue;
            }
            return cloned;
        }
        case 'any':
            return { kind: 'any' };
        case 'whole':
        case 'decimal':
        case 'date':
        case 'time':
        case 'textLength':
            return {
                kind: rule.kind,
                operator: rule.operator,
                values: [...rule.values],
            };
    }
}
export function cloneDataValidationRecord(record) {
    const cloned = {
        range: { ...record.range },
        rule: cloneDataValidationRule(record.rule),
    };
    if (record.allowBlank !== undefined) {
        cloned.allowBlank = record.allowBlank;
    }
    if (record.showDropdown !== undefined) {
        cloned.showDropdown = record.showDropdown;
    }
    if (record.promptTitle !== undefined) {
        cloned.promptTitle = record.promptTitle;
    }
    if (record.promptMessage !== undefined) {
        cloned.promptMessage = record.promptMessage;
    }
    if (record.errorStyle !== undefined) {
        cloned.errorStyle = record.errorStyle;
    }
    if (record.errorTitle !== undefined) {
        cloned.errorTitle = record.errorTitle;
    }
    if (record.errorMessage !== undefined) {
        cloned.errorMessage = record.errorMessage;
    }
    return cloned;
}
export function cloneConditionalFormatRule(rule) {
    switch (rule.kind) {
        case 'cellIs':
            return {
                kind: 'cellIs',
                operator: rule.operator,
                values: [...rule.values],
            };
        case 'textContains': {
            const cloned = {
                kind: 'textContains',
                text: rule.text,
            };
            if (rule.caseSensitive !== undefined) {
                cloned.caseSensitive = rule.caseSensitive;
            }
            return cloned;
        }
        case 'formula':
            return { kind: 'formula', formula: rule.formula };
        case 'blanks':
            return { kind: 'blanks' };
        case 'notBlanks':
            return { kind: 'notBlanks' };
    }
}
export function cloneConditionalFormatRecord(record) {
    return structuredClone(record);
}
export function cloneConditionalFormatArtifactsRecord(record) {
    return structuredClone(record);
}
export function cloneDrawingArtifactsRecord(record) {
    return {
        parts: record.parts.map(clonePreservedPackagePart),
        ...(record.contentTypeDefaults !== undefined ? { contentTypeDefaults: structuredClone(record.contentTypeDefaults) } : {}),
        ...(record.contentTypeOverrides !== undefined ? { contentTypeOverrides: structuredClone(record.contentTypeOverrides) } : {}),
    };
}
export function cloneExternalLinkArtifactsRecord(record) {
    return structuredClone(record);
}
export function cloneThreadedCommentArtifactsRecord(record) {
    return structuredClone(record);
}
export function cloneSheetDrawingArtifactsRecord(record) {
    return structuredClone(record);
}
export function cloneSheetThreadedCommentArtifactsRecord(record) {
    return structuredClone(record);
}
export function cloneSheetLegacyCommentVmlRecord(record) {
    return structuredClone(record);
}
function clonePreservedPackagePart(part) {
    return {
        path: part.path,
        storage: 'base64',
        dataBase64: part.dataBase64,
        byteLength: part.byteLength,
    };
}
export function cloneSheetProtectionRecord(record) {
    return structuredClone(record);
}
export function cloneRangeProtectionRecord(record) {
    return structuredClone(record);
}
export function cloneCommentEntryRecord(record) {
    return structuredClone(record);
}
export function cloneCommentThreadRecord(record) {
    const cloned = {
        threadId: record.threadId,
        sheetName: record.sheetName,
        address: canonicalWorkbookAddress(record.sheetName, record.address),
        comments: record.comments.map(cloneCommentEntryRecord),
    };
    if (record.resolved !== undefined) {
        cloned.resolved = record.resolved;
    }
    if (record.resolvedByUserId !== undefined) {
        cloned.resolvedByUserId = record.resolvedByUserId;
    }
    if (record.resolvedAtUnixMs !== undefined) {
        cloned.resolvedAtUnixMs = record.resolvedAtUnixMs;
    }
    return cloned;
}
export function cloneNoteRecord(record) {
    return {
        sheetName: record.sheetName,
        address: canonicalWorkbookAddress(record.sheetName, record.address),
        text: record.text,
    };
}
export function cloneHyperlinkRecord(record) {
    return {
        sheetName: record.sheetName,
        address: canonicalWorkbookAddress(record.sheetName, record.address),
        target: record.target,
        ...(record.tooltip !== undefined ? { tooltip: record.tooltip } : {}),
        ...(record.display !== undefined ? { display: record.display } : {}),
    };
}
export function conditionalFormatKey(id) {
    const normalized = id.trim();
    if (normalized.length === 0) {
        throw new Error('Conditional format id must be non-empty');
    }
    return normalized;
}
export function rangeProtectionKey(id) {
    const normalized = id.trim();
    if (normalized.length === 0) {
        throw new Error('Range protection id must be non-empty');
    }
    return normalized;
}
export function clonePivotRecord(record) {
    return structuredClone(record);
}
export function cloneChartRecord(record) {
    return structuredClone(record);
}
export function cloneImageRecord(record) {
    const cloned = {
        id: record.id,
        sheetName: record.sheetName,
        address: canonicalWorkbookAddress(record.sheetName, record.address),
        sourceUrl: record.sourceUrl,
        rows: record.rows,
        cols: record.cols,
    };
    if (record.altText !== undefined) {
        cloned.altText = record.altText;
    }
    return cloned;
}
export function cloneShapeRecord(record) {
    const cloned = {
        id: record.id,
        sheetName: record.sheetName,
        address: canonicalWorkbookAddress(record.sheetName, record.address),
        shapeType: record.shapeType,
        rows: record.rows,
        cols: record.cols,
    };
    if (record.text !== undefined) {
        cloned.text = record.text;
    }
    if (record.fillColor !== undefined) {
        cloned.fillColor = record.fillColor;
    }
    if (record.strokeColor !== undefined) {
        cloned.strokeColor = record.strokeColor;
    }
    return cloned;
}
export function cloneSpillRecord(record) {
    return structuredClone(record);
}
export { cloneMergeRangeRecord, mergeRangeKey };
function axisMetadataKey(sheetName, start, count) {
    return `${sheetName}:${start}:${count}`;
}
export function filterKey(sheetName, range) {
    const normalized = canonicalWorkbookRangeRef(range);
    return `${sheetName}:${normalized.startAddress}:${normalized.endAddress}`;
}
export function sortKey(sheetName, range) {
    const normalized = canonicalWorkbookRangeRef(range);
    return `${sheetName}:${normalized.startAddress}:${normalized.endAddress}`;
}
export function dataValidationKey(sheetName, range) {
    const normalized = canonicalWorkbookRangeRef(range);
    return `${sheetName}:${normalized.startAddress}:${normalized.endAddress}`;
}
export function commentThreadKey(sheetName, address) {
    return `${sheetName}!${canonicalWorkbookAddress(sheetName, address)}`;
}
export function noteKey(sheetName, address) {
    return `${sheetName}!${canonicalWorkbookAddress(sheetName, address)}`;
}
export function hyperlinkKey(sheetName, address) {
    return `${sheetName}!${canonicalWorkbookAddress(sheetName, address)}`;
}
export function tableKey(name) {
    return normalizeWorkbookObjectName(name, 'Tables');
}
export function spillKey(sheetName, address) {
    return `${sheetName}!${canonicalWorkbookAddress(sheetName, address)}`;
}
export function deleteRecordsBySheet(bucket, sheetName, readSheetName) {
    for (const [key, record] of bucket.entries()) {
        if (readSheetName(record) === sheetName) {
            bucket.delete(key);
        }
    }
}
export function rekeyRecords(bucket, rewrite) {
    if (bucket.size === 0) {
        return;
    }
    const rewritten = [...bucket.values()].map((record) => rewrite(record));
    bucket.clear();
    rewritten.forEach((record) => {
        bucket.set(recordKey(record), record);
    });
}
function recordKey(record) {
    if (isFreezePaneRecord(record)) {
        return record.sheetName;
    }
    if (isMergeRangeRecord(record)) {
        return mergeRangeKey(record);
    }
    if (isAxisMetadataRecord(record)) {
        return axisMetadataKey(record.sheetName, record.start, record.count);
    }
    if (isSheetProtectionRecord(record)) {
        return record.sheetName;
    }
    if (isFilterRecord(record)) {
        return filterKey(record.sheetName, record.range);
    }
    if (isSortRecord(record)) {
        return sortKey(record.sheetName, record.range);
    }
    if (isConditionalFormatRecord(record)) {
        return conditionalFormatKey(record.id);
    }
    if (isConditionalFormatArtifactsRecord(record)) {
        return record.sheetName;
    }
    if (isRangeProtectionRecord(record)) {
        return rangeProtectionKey(record.id);
    }
    if (isDataValidationRecord(record)) {
        return dataValidationKey(record.range.sheetName, record.range);
    }
    if (isCommentThreadRecord(record)) {
        return commentThreadKey(record.sheetName, record.address);
    }
    if (isNoteRecord(record)) {
        return noteKey(record.sheetName, record.address);
    }
    if (isHyperlinkRecord(record)) {
        return hyperlinkKey(record.sheetName, record.address);
    }
    if (isDefinedNameRecord(record)) {
        return definedNameKey(record.name, record.scopeSheetName);
    }
    if (isTableRecord(record)) {
        return tableKey(record.name);
    }
    if (isSpillRecord(record)) {
        return spillKey(record.sheetName, record.address);
    }
    if (isPivotRecord(record)) {
        return pivotKey(record.sheetName, record.address);
    }
    if (isChartRecord(record)) {
        return chartKey(record.id);
    }
    if (isImageRecord(record)) {
        return imageKey(record.id);
    }
    if (isShapeRecord(record)) {
        return shapeKey(record.id);
    }
    throw new Error('Unsupported workbook metadata record');
}
function isFreezePaneRecord(record) {
    return (typeof record === 'object' && record !== null && 'sheetName' in record && 'rows' in record && 'cols' in record && !('address' in record));
}
function isMergeRangeRecord(record) {
    return (typeof record === 'object' &&
        record !== null &&
        'sheetName' in record &&
        'startAddress' in record &&
        'endAddress' in record &&
        !('range' in record) &&
        !('name' in record) &&
        !('columnNames' in record));
}
function isAxisMetadataRecord(record) {
    return (typeof record === 'object' &&
        record !== null &&
        'sheetName' in record &&
        'start' in record &&
        'count' in record &&
        'size' in record &&
        'hidden' in record);
}
function isFilterRecord(record) {
    return typeof record === 'object' && record !== null && 'sheetName' in record && 'range' in record && !('keys' in record);
}
function isDefinedNameRecord(record) {
    return typeof record === 'object' && record !== null && 'name' in record && 'value' in record && !('sheetName' in record);
}
function isSheetProtectionRecord(record) {
    return (typeof record === 'object' &&
        record !== null &&
        'sheetName' in record &&
        !('rows' in record) &&
        !('cols' in record) &&
        !('range' in record) &&
        !('startAddress' in record) &&
        !('address' in record) &&
        !('start' in record));
}
function isSortRecord(record) {
    return typeof record === 'object' && record !== null && 'sheetName' in record && 'range' in record && 'keys' in record;
}
function isDataValidationRecord(record) {
    return (typeof record === 'object' &&
        record !== null &&
        'range' in record &&
        'rule' in record &&
        !('keys' in record) &&
        !('id' in record && 'style' in record));
}
function isCommentThreadRecord(record) {
    return typeof record === 'object' && record !== null && 'threadId' in record && 'comments' in record;
}
function isConditionalFormatRecord(record) {
    return typeof record === 'object' && record !== null && 'id' in record && 'range' in record && 'rule' in record && 'style' in record;
}
function isConditionalFormatArtifactsRecord(record) {
    return typeof record === 'object' && record !== null && 'sheetName' in record && 'xml' in record && !('range' in record);
}
function isRangeProtectionRecord(record) {
    return typeof record === 'object' && record !== null && 'id' in record && 'range' in record && !('rule' in record) && !('style' in record);
}
function isNoteRecord(record) {
    return typeof record === 'object' && record !== null && 'address' in record && 'text' in record && !('comments' in record);
}
function isHyperlinkRecord(record) {
    return typeof record === 'object' && record !== null && 'address' in record && 'target' in record;
}
function isTableRecord(record) {
    return typeof record === 'object' && record !== null && 'name' in record && 'columnNames' in record;
}
function isSpillRecord(record) {
    return (typeof record === 'object' &&
        record !== null &&
        'sheetName' in record &&
        'address' in record &&
        'rows' in record &&
        'cols' in record &&
        !('source' in record) &&
        !('id' in record) &&
        !('sourceUrl' in record) &&
        !('shapeType' in record));
}
function isPivotRecord(record) {
    return (typeof record === 'object' &&
        record !== null &&
        'sheetName' in record &&
        'values' in record &&
        !('id' in record) &&
        !('chartType' in record));
}
function isChartRecord(record) {
    return (typeof record === 'object' &&
        record !== null &&
        'id' in record &&
        'chartType' in record &&
        'sheetName' in record &&
        'address' in record &&
        'source' in record);
}
function isImageRecord(record) {
    return (typeof record === 'object' && record !== null && 'id' in record && 'sheetName' in record && 'address' in record && 'sourceUrl' in record);
}
function isShapeRecord(record) {
    return (typeof record === 'object' && record !== null && 'id' in record && 'sheetName' in record && 'address' in record && 'shapeType' in record);
}
//# sourceMappingURL=workbook-metadata-records.js.map