import StructureFactory, {StructureConfig, StructureImplConfig} from "../StructureFactory";
import Form from "./Form";
import Structure from "../Structure";
import SubmitStrategyFactory, {SubmitStrategyConfig} from "./SubmitStrategies/SubmitStrategyFactory";

export default class FormFactory {
    protected submitStrategyFactory: SubmitStrategyFactory = new SubmitStrategyFactory().setDefaults();

    public createForm(config:StructureConfig, params: Partial<Structure>): Form{
        const impl = config.impl;
        if (!isFormConfig(impl)) throw new Error("Invalid config");

        const formParams: Partial<Form> = params as Partial<Form>;
        formParams.name = impl.name;
        formParams.writeDefaultData = impl.writeDefaultData;
        formParams.displayDefaultNotice = impl.displayDefaultNotice;
        formParams.isDefaultText = impl.isDefaultText;
        formParams.isChangedText = impl.isChangedText;
        formParams.resetButtonText = impl.resetButtonText;
        formParams.forceDivElement = impl.forceDivElement;
        formParams.useHiddenFieldForJson = impl.useHiddenFieldForJson;

        const form = new Form(formParams);

        form.submitStrategy = this.submitStrategyFactory.createSubmitStrategy(impl.submitBehaviour, form);

        return form;
    }

    public addToStructureFactory(factory: StructureFactory){
        factory.registerConstructor("form", (config, params) => {
            if (!isFormConfig(config.impl)) return null;
            return this.createForm(config, params);
        });
    }
}

function isFormConfig(config: StructureImplConfig): config is FormConfig{
    return config.type === "form";
}

interface FormConfig extends StructureImplConfig{
    name: string,
    submitBehaviour: SubmitStrategyConfig,
    writeDefaultData: boolean,
    displayDefaultNotice: boolean,
    isDefaultText: string,
    isChangedText: string,
    resetButtonText: string,
    forceDivElement: boolean,
    useHiddenFieldForJson: boolean
}