import SubmitStrategy from "../SubmitStrategy";
import Form from "../../Form";
import SubmitStrategyFactory, {SubmitStrategyConfig} from "../SubmitStrategyFactory";

export default class PostSubmit implements SubmitStrategy{
    public url: string = "";

    constructor(protected form: Form) {
        form.getFormBuilder().onComponentsCreated.add(() => this.loadSavedData())
        form.onFormChange.add(() => window.addEventListener('beforeunload', this.leaveCheck));
    }

    protected loadSavedData(): void {
        const storageData = sessionStorage.getItem("planaday-form-" + this.form.name);
        if (storageData){
            this.form.getDataNode().value = JSON.parse(storageData);
        }
    }

    protected saveData(): void {
        sessionStorage.setItem("planaday-form-" + this.form.name, JSON.stringify(this.form.getDataNode().value));
    }

    public submit(data: any) {
        this.saveData();
        this.form.getDataNode().value = data;
        let formToSubmit: HTMLElement|null = this.form.getPlacedHtml()[0] ?? null;
        if (!(formToSubmit instanceof HTMLElement)) {
            console.error("Form has not been placed yet, cannot submit with post");
            return;
        }

        while (formToSubmit && formToSubmit.tagName !== "FORM") {
            formToSubmit = formToSubmit.parentElement;
        }

        if (!(formToSubmit instanceof HTMLFormElement)) {
            console.error("Form to submit could not be found");
            return;
        }

        formToSubmit.setAttribute("method", "post");
        formToSubmit.setAttribute("action", this.url)
        window.removeEventListener('beforeunload', this.leaveCheck);
        formToSubmit.submit();
    }

    public leaveCheck(event: any): void{
        event.preventDefault();
        event.returnValue = true;
    }
}

export function addPostSubmitToFactory(factory: SubmitStrategyFactory): void {
    factory.registerConstructor("post", (config, form) => {
        if (!isPostConfig(config)) return null;
        const postSubmit = new PostSubmit(form);
        postSubmit.url = config.url;
        return postSubmit;
    });
}

function isPostConfig(config: SubmitStrategyConfig): config is PostConfig{
    return config.type === "post";
}

interface PostConfig extends SubmitStrategyConfig{
    type: "post";
    url: string;
}