import { IgniteElement } from "../ignite-html/ignite-element.js";
import { IgniteProperty } from "../ignite-html/ignite-html.js";
import { IgniteTemplate, div, h2, h5, button } from "../ignite-html/ignite-template.js";

class YesNoDialog extends IgniteElement {
    constructor() {
        super();
    }

    get properties() {
        return {
            loading: false,
            title: null,
            description: null,
            yesButton: "Yes",
            yesButtonClass: "btn-primary",
            yesCallback: null,
            noButton: "No",
            noButtonClass: "btn-secondary",
            noCallback: null,
            spinnerClass: "text-secondary",
            modalElement: null,
            modal: null,
            autoOpen: false
        };
    }

    render() {
        return this.template.child(
            new div().class("modal").ref(this.modalElement).child(
                new div().class("modal-dialog modal-dialog-centered").child(
                    new div().class("modal-content").child(
                        new div().class("modal-body d-flex flex-column align-items-center").child(
                            //Title
                            new h2().class("text-primary text-center mb-3").child(this.title),

                            new h5().show(this.description, description => description != null && description != undefined).class("text-center mb-4").child(this.description),

                            //Yes and No button
                            new div().class("d-flex flex-row gap-3 w-100").child(
                                new button()
                                    .disabled(this.loading)
                                    .class("btn btn-lg flex-1 rounded-pill d-flex flex-row align-items-center justify-content-center")
                                    .class(this.yesButtonClass)
                                    .child(
                                        new div().show(this.loading).class("spinner-border me-2").class(this.spinnerClass),

                                        this.yesButton
                                    )
                                    .onClick(() => this.yes()),

                                new button()
                                    .disabled(this.loading)
                                    .class("btn btn-lg rounded-pill flex-1")
                                    .class(this.noButtonClass)
                                    .child(this.noButton)
                                    .onClick(() => this.no())
                            )
                        )
                    )
                )
            )
        )
    }

    afterRender() {
        this.modal = new bootstrap.Modal(this.modalElement, { backdrop: "static" });
    }

    ready() {
        if (this.autoOpen) {
            this.open();
        }
    }

    async yes() {
        this.loading = true;

        if (this.yesCallback) {
            await this.yesCallback(this);
        }

        this.loading = false;

        this.close();
    }

    async no() {
        this.loading = true;

        if (this.noCallback) {
            await this.noCallback(this);
        }

        this.loading  =false;
        
        this.close();
    }

    open() {
        this.modal.show();
    }

    close() {
        this.modal.hide();
    }
}

customElements.define("bt-yes-no-dialog", YesNoDialog);

class Template extends IgniteTemplate {
    constructor(...children) {
        super("bt-yes-no-dialog", children);
    }

    /**
     * Creates and opens a new Yes No dialog with a title, description, yesCallback, noCallback.
     * @param {String|IgniteProperty} title 
     * @param {String|IgniteProperty} description 
     * @param {Function(YesNoDialog)} yesCallback 
     * @param {Function(YesNoDialog)} noCallback 
     */
    static open(title, description, yesCallback = null, noCallback = null) {
        var dialog = new Template();
        dialog.property("autoOpen", true);
        dialog.property("title", title);
        dialog.property("description", description);
        dialog.property("yesCallback", async (instance) => {
            if (yesCallback) {
                await yesCallback(instance);
            }

            dialog.deconstruct();
        });
        dialog.property("noCallback", async (instance) => {
            if (noCallback) {
                await noCallback(instance);
            }

            dialog.deconstruct();
        });

        dialog.construct(window.document.body, null);
    }
}

export {
    Template as YesNoDialog
}