import * as pdfDoc from '@peculiar/pdf-doc';
import { FormComponentType } from '@peculiar/pdf-doc';

/**
 * Type representing a constructor for an IComponent instance.
 */
type IComponentConstructor<T extends pdfDoc.IComponent> = new (target: any, doc: pdfDoc.PDFDocument) => T;
/**
 * Interface representing the JSON object for a form component.
 */
interface JsonComponent {
    name: string;
}
/**
 * Interface representing the JSON object for a PDF form.
 */
interface JsonForm {
    form: Record<string, JsonComponent>;
}
/**
 * Interface representing the update data for a form component.
 */
interface JsonComponentUpdate {
    type: FormComponentType[keyof FormComponentType];
    name: string;
}
/**
 * Interface representing the update data for a check box form component.
 */
interface JsonCheckBoxUpdate extends JsonComponentUpdate {
    type: "check_box";
    checked: boolean;
}
/**
 * Interface representing the update data for a radio button form component.
 */
interface JsonRadioButtonUpdate extends JsonComponentUpdate {
    type: "radio_button";
    checked: boolean;
}
/**
 * Interface representing the update data for a radio button group form component.
 */
interface JsonRadioButtonGroupUpdate extends JsonComponentUpdate {
    type: "radio_button_group";
    selected: string;
}
/**
 * Interface representing the update data for a combo box form component.
 */
interface JsonComboBoxUpdate extends JsonComponentUpdate {
    type: "combo_box";
    selected: string[];
}
/**
 * Interface representing the update data for a text editor form component.
 */
interface JsonTextEditorUpdate extends JsonComponentUpdate {
    type: "text_editor";
    text: string;
}
/**
 * Union type for all possible types of form component updates.
 */
type JsonUpdateMixed = JsonCheckBoxUpdate | JsonRadioButtonGroupUpdate | JsonRadioButtonUpdate | JsonComboBoxUpdate | JsonTextEditorUpdate;

/**
 * Abstract class representing a ComponentConverter for an IComponent type.
 */
declare abstract class ComponentConverter<T extends pdfDoc.IComponent> {
    /**
     * The constructor function for the associated IComponent type.
     */
    type: pdfDoc.IComponentConstructor<T>;
    /**
     * The string value of the FormComponentType for the associated IComponent type.
     */
    abstract typeJSON: string;
    constructor(type: pdfDoc.IComponentConstructor<T>);
    /**
     * Exports a component to a JSON object.
     * @param component - The component to export.
     * @returns The JSON object representing the component.
     */
    abstract export(component: T): JsonComponent;
    /**
     * Sets the value of a component based on update data.
     * @param component - The component to update.
     * @param data - The update data for the component.
     */
    abstract setValue(component: T, data: JsonComponentUpdate): void;
}

/**
 * The ComponentConverterFactory is a factory that creates ComponentConverter instances for IComponent types.
 * It contains a map of ComponentConverter instances, keyed by their associated IComponent type.
 *
 * @remarks
 * To create a new ComponentConverter instance, call the register method with a new instance of the converter.
 */
declare class ComponentConverterFactory {
    /**
     * A map of ComponentConverter instances, keyed by their associated IComponent type.
     */
    protected items: Map<IComponentConstructor<pdfDoc.IComponent>, ComponentConverter<pdfDoc.IComponent>>;
    constructor(...converters: ComponentConverter<pdfDoc.IComponent>[]);
    /**
     * Registers a new ComponentConverter instance for a given IComponent type.
     *
     * @param converter - The ComponentConverter instance to register.
     */
    register(converter: ComponentConverter<pdfDoc.IComponent>): void;
    /**
     * Finds a ComponentConverter instance for a given IComponent type.
     *
     * @typeparam T - The IComponent type to find a converter for.
     * @param type - The constructor function for the IComponent type to find a converter for.
     * @returns The ComponentConverter instance for the given IComponent type, or null if not found.
     */
    find<T extends pdfDoc.IComponent>(type: IComponentConstructor<T>): ComponentConverter<T> | null;
    /**
     * Gets a ComponentConverter instance for a given IComponent type.
     *
     * @typeparam T - The IComponent type to get a converter for.
     * @param type - The constructor function for the IComponent type to get a converter for.
     * @returns The ComponentConverter instance for the given IComponent type.
     * @throws If no converter is found for the given IComponent type.
     */
    get<T extends pdfDoc.IComponent>(type: IComponentConstructor<T>): ComponentConverter<T>;
}

/**
 * Abstract class representing a ComponentConverter for a FormComponentGroup type.
 * @typeparam T - The FormComponentGroup type to convert.
 */
declare abstract class FieldConverter<T extends pdfDoc.FormComponentGroup> extends ComponentConverter<T> {
    export(component: T): JsonComponent;
    /**
     *
     * @param component Called to add additional data to the JSON object representing the form component.
     * @param component - The form component to export.
     * @param json - The JSON object representing the form component.
     */
    protected abstract onExport(component: T, json: Record<string, unknown>): void;
}

/**
 * Abstract class representing a ComponentConverter for a FormComponent type.
 * @typeparam T - The FormComponent type to convert.
 */
declare abstract class WidgetConverter<T extends pdfDoc.FormComponent> extends ComponentConverter<T> {
    export(component: T): JsonComponent;
    /**
     * Called to add additional data to the JSON object representing the form component.
     * @param component - The form component to export.
     * @param json - The JSON object representing the form component.
     */
    protected abstract onExport(component: T, json: Record<string, unknown>): void;
}

/**
 * A ComponentConverter for CheckBox form components.
 */
declare class CheckBoxConverter extends WidgetConverter<pdfDoc.CheckBox> {
    typeJSON: pdfDoc.FormComponentType.checkBox;
    constructor();
    protected onExport(component: pdfDoc.CheckBox, json: Record<string, unknown>): void;
    setValue(component: pdfDoc.CheckBox, data: JsonCheckBoxUpdate): void;
}

/**
 * A ComponentConverter for ComboBox form components.
 */
declare class ComboBoxConverter extends WidgetConverter<pdfDoc.ComboBox> {
    typeJSON: pdfDoc.FormComponentType.comboBox;
    constructor();
    protected onExport(component: pdfDoc.ComboBox, json: Record<string, unknown>): void;
    setValue(component: pdfDoc.ComboBox, data: JsonComboBoxUpdate): void;
}

/**
 * A ComponentConverter for RadioButton form components.
 */
declare class RadioButtonConverter extends WidgetConverter<pdfDoc.RadioButton> {
    typeJSON: pdfDoc.FormComponentType.radioButton;
    constructor();
    protected onExport(component: pdfDoc.RadioButton, json: Record<string, unknown>): void;
    setValue(component: pdfDoc.RadioButton, data: JsonRadioButtonUpdate): void;
}

/**
 * A ComponentConverter for RadioButtonGroup form components.
 */
declare class RadioButtonGroupConverter extends FieldConverter<pdfDoc.RadioButtonGroup> {
    typeJSON: pdfDoc.FormComponentType.radioButtonGroup;
    constructor();
    protected onExport(component: pdfDoc.RadioButtonGroup, json: Record<string, unknown>): void;
    setValue(component: pdfDoc.RadioButtonGroup, data: JsonRadioButtonGroupUpdate): void;
}

/**
 * A ComponentConverter for TextEditor form components.
 */
declare class TextEditorConverter extends WidgetConverter<pdfDoc.TextEditor> {
    typeJSON: pdfDoc.FormComponentType.textEditor;
    constructor();
    protected onExport(component: pdfDoc.TextEditor, json: Record<string, unknown>): void;
    setValue(component: pdfDoc.TextEditor, data: JsonTextEditorUpdate): void;
}

/**
 * A utility class for exporting and updating PDF form components.
 */
declare class FormConverter {
    /**
     * The ComponentConverterFactory instance to use for converting PDF form components to JSON.
     */
    registry: ComponentConverterFactory;
    /**
     * Creates a FormConverter instance.
     * @param registry - The ComponentConverterFactory instance to use for converting PDF form components to JSON.
     */
    constructor(registry: ComponentConverterFactory);
    /**
     * Exports all PDF form components in a document to JSON format.
     * @param doc - The PDF document to export the form components from.
     * @returns An object containing JSON representations of all form components in the document.
     */
    export(doc: pdfDoc.PDFDocument): JsonForm;
    /**
     * Exports a single PDF form component to JSON format.
     * @param component - The PDF form component to export.
     * @returns The JSON representation of the specified form component,
     * or null if the component is not supported by the current converter registry.
     */
    protected exportComponent(component: pdfDoc.IComponent): JsonComponent | null;
    /**
     * Sets the value of one or more PDF form components based on provided JSON updates.
     * @param doc - The PDF document containing the form components to update.
     * @param data - An array of JSON updates to apply to the PDF form components.
     */
    setValue(doc: pdfDoc.PDFDocument, data: JsonUpdateMixed[]): void;
}

/**
 * A global instance of FormConverter that uses the ComponentConverter registry.
 */
declare const globalFormConverter: FormConverter;

export { CheckBoxConverter, ComboBoxConverter, ComponentConverter, ComponentConverterFactory, FieldConverter, FormConverter, type IComponentConstructor, type JsonCheckBoxUpdate, type JsonComboBoxUpdate, type JsonComponent, type JsonComponentUpdate, type JsonForm, type JsonRadioButtonGroupUpdate, type JsonRadioButtonUpdate, type JsonTextEditorUpdate, type JsonUpdateMixed, RadioButtonConverter, RadioButtonGroupConverter, TextEditorConverter, WidgetConverter, globalFormConverter };
