import { ZodSchema } from 'zod';
import * as pdf_lib from 'pdf-lib';
import { PDFDocument, AFRelationship, AttachmentOptions } from 'pdf-lib';
import * as fast_xml_parser from 'fast-xml-parser';

type LiteralString = "" | (string & Record<never, never>);
type PickRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
type UnionToIntersection$1<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;

type PDFAMetadata = {
    author?: string;
    creator?: string;
    producer?: string;
    createDate?: Date;
    modifyDate?: Date;
    language?: string;
    subject?: string;
    title?: string;
    keywords?: string[];
    facturX: {
        documentType: "INVOICE" | "ORDER";
        documentFileName: string;
        version: string;
        conformanceLevel: string;
    };
};

type ParseSchemaOptions = {
    groupIndices?: GroupIndices;
};
type GroupIndices = Record<string, number>;

type ZugferdPlugin = (ctx: ZugferdContext) => {
    [key: string]: unknown;
};

type ZugferdOptions = {
    profile: ProfileContext;
    strict?: boolean;
    plugins?: ZugferdPlugin[];
};

declare const createDocumentFactory: <O extends ZugferdOptions>(ctx: BaseZugferdContext, options: O) => (data: InferSchema<O["profile"]>) => {
    toObj: () => any;
    toXML: () => Promise<string>;
    embedInPdf: (pdf: PDFDocument | string | Uint8Array | ArrayBuffer, opts?: {
        metadata?: Omit<PDFAMetadata, "facturX">;
        additionalFiles?: Array<{
            content: string | ArrayBuffer | Uint8Array;
            filename: string;
            relationship?: keyof typeof AFRelationship;
        } & Omit<AttachmentOptions, "afRelationship">>;
    }) => Promise<Uint8Array<ArrayBufferLike>>;
};

declare const validateDocumentFactory: (ctx: BaseZugferdContext) => ProfileValidateHandler;

type BaseZugferdContext = {
    options: ZugferdOptions;
} & InternalTools;
type ZugferdContext = BaseZugferdContext & {
    document: {
        create: ReturnType<typeof createDocumentFactory<ZugferdOptions>>;
        validate: ReturnType<typeof validateDocumentFactory>;
    };
};
type InternalTools = ReturnType<typeof getInternalTools>;
declare const getInternalTools: (_options: ZugferdOptions) => {
    parseSchema: <S extends Schema>(data: InferRawSchema<S>, def: S, options: ParseSchemaOptions, parentGroupIndices?: {
        [x: string]: number;
    }, fullData?: any) => any;
    mergeSchemas: (profile: Profile) => Schema;
    xml: {
        format: (doc: any, options?: Omit<fast_xml_parser.XmlBuilderOptions, "attributeNamePrefix" | "attributesGroupName" | "textNodeName">) => string;
    };
    pdf: {
        addMetadata: (pdfDoc: pdf_lib.PDFDocument, metadata: PickRequired<PDFAMetadata, "createDate" | "modifyDate"> & {
            now: Date;
        }) => pdf_lib.PDFDocument;
        addTrailerInfoId: (pdfDoc: pdf_lib.PDFDocument, trailerInfoId: string) => pdf_lib.PDFDocument;
        fixLinkAnnotations: (pdfDoc: pdf_lib.PDFDocument) => pdf_lib.PDFDocument;
        addStructTreeRoot: (pdfDoc: pdf_lib.PDFDocument) => pdf_lib.PDFDocument;
        addMarkInfo: (pdfDoc: pdf_lib.PDFDocument) => pdf_lib.PDFDocument;
        addICC: (pdfDoc: pdf_lib.PDFDocument) => pdf_lib.PDFDocument;
        getAttachments: (pdfDoc: pdf_lib.PDFDocument) => {
            name: string;
            data: Uint8Array<ArrayBufferLike>;
        }[];
    };
};

type Profile = {
    id: LiteralString;
    extends?: Profile[];
    schema: Schema;
    xsdPath?: string | (() => Promise<string> | string);
    conformanceLevel: string;
    documentFileName: string;
    mask?: Record<string, any>;
    /**
     * @default 'INVOICE'
     */
    documentType?: "INVOICE" | "ORDER";
    version: string;
};
type ProfileParseHandlerContext<P extends Profile = Profile> = {
    context: BaseZugferdContext;
    data: InferSchema<P>;
};
type ProfileParseHandler<P extends Profile = Profile> = (ctx: {
    context: BaseZugferdContext;
    data: InferSchema<P>;
}) => any;
type ProfileValidateHandler = (data: string | Buffer | {
    file: string;
}) => Promise<boolean>;
type ProfileContext<P extends Profile = Profile> = P & {
    parse: ProfileParseHandler<P>;
    validate: ProfileValidateHandler;
};

type FieldType = "string" | "string[]" | "number" | "number[]" | "date" | "boolean" | "object" | "object[]" | "string | number" | "(string | number)[]" | Array<LiteralString>;
type Primitive = string | number | Date | null | undefined | object;
type SchemaFieldConfig<T extends FieldType = FieldType> = {
    key?: string;
    defaultValue?: Primitive | (() => Primitive);
    validator?: ZodSchema;
    xpath?: string;
    group?: LiteralString;
    description?: string;
    required?: boolean;
    sibling?: T extends "object[]" ? (data: any, groupIndicies: {
        [key: string]: number;
    }) => any : never;
    shape?: T extends "object" | "object[]" ? Schema : never;
    additionalXml?: Record<string, string>;
    transform?: {
        input?: (val: any) => any;
        output?: (val: any) => any;
    };
};
type SchemaField<T extends FieldType = FieldType> = {
    type: T;
} & SchemaFieldConfig<T>;
type Schema = {
    [key: string]: SchemaField;
};
type InferValueType<T extends FieldType> = T extends "string" ? string : T extends "number" ? number : T extends "string | number" ? string | number : T extends "boolean" ? boolean : T extends "date" ? Date | string : T extends "string[]" ? string[] : T extends "number[]" ? number[] : T extends "(string | number)[]" ? (string | number)[] : T extends Array<any> ? T[number] : never;
type UnionToIntersection<U> = (U extends U ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
type InferSchema<P extends Profile> = InferRawSchema<P["schema"]> & (P["extends"] extends Profile[] ? UnionToIntersection<InferSchemaHelper<P["extends"][number]>> : {});
type InferSchemaHelper<E> = E extends Profile ? InferRawSchema<E["schema"]> & (E["extends"] extends Profile[] ? InferSchemaHelper<E["extends"][number]> : {}) : {};
type InferRawSchema<S extends Schema> = {
    [K in keyof S as S[K]["required"] extends false ? K : never]?: S[K]["type"] extends "object" ? S[K]["shape"] extends Schema ? InferRawSchema<S[K]["shape"]> : {} : S[K]["type"] extends "object[]" ? S[K]["shape"] extends Schema ? Array<InferRawSchema<S[K]["shape"]>> : [] : InferValueType<S[K]["type"]>;
} & {
    [K in keyof S as S[K]["required"] extends false ? never : K]: S[K]["type"] extends "object" ? S[K]["shape"] extends Schema ? InferRawSchema<S[K]["shape"]> : {} : S[K]["type"] extends "object[]" ? S[K]["shape"] extends Schema ? Array<InferRawSchema<S[K]["shape"]>> : [] : InferValueType<S[K]["type"]>;
};

export { type BaseZugferdContext as B, type FieldType as F, type InferSchema as I, type LiteralString as L, type Profile as P, type SchemaFieldConfig as S, type UnionToIntersection$1 as U, type ZugferdOptions as Z, type ZugferdContext as a, type ProfileValidateHandler as b, createDocumentFactory as c, type ZugferdPlugin as d, type SchemaField as e, type Schema as f, type InferValueType as g, type InferRawSchema as h, type ProfileParseHandlerContext as i, type ProfileParseHandler as j, type ProfileContext as k, type PickRequired as l };
