/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.syncope.client.console.wizards;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksTogglePanel;
import org.apache.syncope.client.console.wizards.any.ResultPage;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
import org.apache.syncope.client.ui.commons.panels.NotificationPanel;
import org.apache.syncope.client.ui.commons.panels.WizardModalPanel;
import org.apache.syncope.client.ui.commons.wizards.AbstractWizardMgtPanel;
import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
import org.apache.syncope.client.ui.commons.wizards.ModalPanelBuilder;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.StringResourceModel;

public abstract class WizardMgtPanel<T extends Serializable> extends AbstractWizardMgtPanel<T> {

    private static final long serialVersionUID = -4152438633429194882L;

    private boolean readOnly = false;

    private final String actualId;

    private final WebMarkupContainer container;

    protected final Fragment initialFragment;

    protected final boolean wizardInModal;

    private boolean containerAutoRefresh = true;

    protected PageReference pageRef;

    protected final AjaxLink<?> addAjaxLink;

    protected Label utilityIcon;

    protected AjaxLink<?> utilityAjaxLink;

    protected ModalPanelBuilder<T> newItemPanelBuilder;

    protected NotificationPanel notificationPanel;

    protected boolean footerVisibility = false;

    protected boolean showResultPage = false;

    private final List<Component> outerObjects = new ArrayList<>();

    protected final BaseModal<T> modal = new BaseModal<>(Constants.OUTER) {

        private static final long serialVersionUID = 389935548143327858L;

        @Override
        protected void onConfigure() {
            super.onConfigure();
            setFooterVisible(footerVisibility);
        }
    };

    protected WizardMgtPanel(final String id) {
        this(id, false);
    }

    protected WizardMgtPanel(final String id, final boolean wizardInModal) {
        super(id);
        setOutputMarkupId(true);

        this.actualId = wizardInModal ? BaseModal.CONTENT_ID : WIZARD_ID;
        this.wizardInModal = wizardInModal;

        outerObjects.add(modal);

        container = new WebMarkupContainer("container");
        container.setOutputMarkupPlaceholderTag(true).setOutputMarkupId(true);
        add(container);

        initialFragment = new Fragment("content", "default", this);
        container.addOrReplace(initialFragment);

        addAjaxLink = new AjaxLink<T>("add") {

            private static final long serialVersionUID = -7978723352517770644L;

            @Override
            public void onClick(final AjaxRequestTarget target) {
                send(WizardMgtPanel.this, Broadcast.BREADTH,
                        new ActionLinksTogglePanel.ActionLinkToggleCloseEventPayload(target));
                send(WizardMgtPanel.this, Broadcast.EXACT,
                        new AjaxWizard.NewItemActionEvent<>(null, target));
            }
        };

        addAjaxLink.setEnabled(false);
        addAjaxLink.setVisible(false);
        initialFragment.addOrReplace(addAjaxLink);

        utilityAjaxLink = new AjaxLink<T>("utility") {

            private static final long serialVersionUID = -7978723352517770644L;

            @Override
            public void onClick(final AjaxRequestTarget target) {
                send(WizardMgtPanel.this, Broadcast.EXACT, new ExitEvent(target));
            }
        };

        utilityAjaxLink.setEnabled(false);
        utilityAjaxLink.setVisible(false);
        initialFragment.addOrReplace(utilityAjaxLink);

        utilityIcon = new Label("utilityIcon");
        utilityAjaxLink.add(utilityIcon);

        add(new ListView<>("outerObjectsRepeater", outerObjects) {

            private static final long serialVersionUID = -9180479401817023838L;

            @Override
            protected void populateItem(final ListItem<Component> item) {
                item.add(item.getModelObject());
            }
        });
    }

    public String getActualId() {
        return actualId;
    }

    @Override
    @SuppressWarnings("unchecked")
    public void onEvent(final IEvent<?> event) {
        if (event.getPayload() instanceof ExitEvent) {
            AjaxRequestTarget target = ExitEvent.class.cast(event.getPayload()).getTarget();
            // default behaviour: change it catching the event if needed
            modal.close(target);
        } else if (event.getPayload() instanceof AjaxWizard.NewItemEvent) {
            AjaxWizard.NewItemEvent<T> newItemEvent = AjaxWizard.NewItemEvent.class.cast(event.getPayload());
            Optional<AjaxRequestTarget> target = newItemEvent.getTarget();
            T item = newItemEvent.getItem();

            boolean modalPanelAvailable = newItemEvent.getModalPanel() != null || newItemPanelBuilder != null;

            if (event.getPayload() instanceof AjaxWizard.NewItemActionEvent && modalPanelAvailable) {
                WizardModalPanel<?> modalPanel;
                if (newItemEvent.getModalPanel() == null && newItemPanelBuilder != null) {
                    newItemPanelBuilder.setItem(item);

                    modalPanel = newItemPanelBuilder.build(
                            actualId,
                            ((AjaxWizard.NewItemActionEvent<T>) newItemEvent).getIndex(),
                            item != null
                                    ? isReadOnly()
                                            ? AjaxWizard.Mode.READONLY
                                            : AjaxWizard.Mode.EDIT
                                    : AjaxWizard.Mode.CREATE);
                } else {
                    modalPanel = newItemEvent.getModalPanel();
                }

                if (wizardInModal) {
                    IModel<T> model = new CompoundPropertyModel<>(item);
                    modal.setFormModel(model);

                    target.ifPresent(t -> t.add(modal.setContent(modalPanel)));

                    modal.header(new StringResourceModel(
                            String.format("any.%s", newItemEvent.getEventDescription()),
                            this,
                            new Model<>(modalPanel.getItem())));
                    modal.show(true);
                } else {
                    Fragment fragment = new Fragment("content", "wizard", WizardMgtPanel.this);

                    fragment.add(new Label("title", newItemEvent.getResourceModel() == null
                            ? Model.of(StringUtils.EMPTY) : newItemEvent.getResourceModel()));

                    fragment.add(Component.class.cast(modalPanel));
                    container.addOrReplace(fragment);
                }
                target.ifPresent(this::customActionCallback);
            } else if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
                if (wizardInModal) {
                    target.ifPresent(modal::close);
                } else {
                    container.addOrReplace(initialFragment);
                }
                target.ifPresent(this::customActionOnCancelCallback);
            } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
                SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
                target.ifPresent(ajaxRequestTarget ->
                    ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(ajaxRequestTarget));

                if (wizardInModal && showResultPage) {
                    modal.setContent(new ResultPage<>(
                        item,
                        AjaxWizard.NewItemFinishEvent.class.cast(newItemEvent).getResult()) {

                        private static final long serialVersionUID = -2630573849050255233L;

                        @Override
                        protected void closeAction(final AjaxRequestTarget target) {
                            modal.close(target);
                        }

                        @Override
                        protected Panel customResultBody(final String id, final T item, final Serializable result) {
                            return WizardMgtPanel.this.customResultBody(id, item, result);
                        }
                    });
                    target.ifPresent(t -> t.add(modal.getForm()));
                } else if (wizardInModal) {
                    target.ifPresent(modal::close);
                } else {
                    container.addOrReplace(initialFragment);
                }
                target.ifPresent(this::customActionOnFinishCallback);
            }

            if (containerAutoRefresh) {
                target.ifPresent(t -> t.add(container));
            }
        }
        super.onEvent(event);
    }

    protected final WizardMgtPanel<T> disableContainerAutoRefresh() {
        containerAutoRefresh = false;
        return this;
    }

    /*
     * Override this method to specify your custom result body panel.
     */
    protected Panel customResultBody(final String panelId, final T item, final Serializable result) {
        return new Panel(panelId) {

            private static final long serialVersionUID = 5538299138211283825L;

        };
    }

    /**
     * Show utility button sending ExitEvent payload by default.
     *
     * @return the current instance.
     */
    protected final WizardMgtPanel<T> enableUtilityButton() {
        utilityAjaxLink.setEnabled(true);
        utilityAjaxLink.setVisible(true);
        return this;
    }

    /**
     * Add object inside the main container.
     *
     * @param childs components to be added.
     * @return the current panel instance.
     */
    public MarkupContainer addInnerObject(final Component... childs) {
        return initialFragment.add(childs);
    }

    /**
     * Add or replace object inside the main container.
     *
     * @param childs components to be added.
     * @return the current panel instance.
     */
    public MarkupContainer addOrReplaceInnerObject(final Component... childs) {
        return initialFragment.addOrReplace(childs);
    }

    /**
     * Add object outside the main container.
     * Use this method just to be not influenced by specific inner object css'.
     * Be sure to provide {@code outer} as id.
     *
     * @param childs components to be added.
     * @return the current panel instance.
     */
    public final WizardMgtPanel<T> addOuterObject(final Component... childs) {
        outerObjects.addAll(List.of(childs));
        return this;
    }

    public <B extends ModalPanelBuilder<T>> WizardMgtPanel<T> setPageRef(final PageReference pageRef) {
        this.pageRef = pageRef;
        return this;
    }

    public <B extends ModalPanelBuilder<T>> WizardMgtPanel<T> setShowResultPage(final boolean showResultPage) {
        this.showResultPage = showResultPage;
        return this;
    }

    protected <B extends ModalPanelBuilder<T>> WizardMgtPanel<T> addNewItemPanelBuilder(
            final B panelBuilder, final boolean newItemDefaultButtonEnabled) {

        this.newItemPanelBuilder = panelBuilder;

        if (this.newItemPanelBuilder != null) {
            addAjaxLink.setEnabled(newItemDefaultButtonEnabled);
            addAjaxLink.setVisible(newItemDefaultButtonEnabled);
            this.newItemPanelBuilder.setEventSink(WizardMgtPanel.this);
        }

        return this;
    }

    protected WizardMgtPanel<T> addNotificationPanel(final NotificationPanel notificationPanel) {
        this.notificationPanel = notificationPanel;
        return this;
    }

    public WizardMgtPanel<T> setFooterVisibility(final boolean footerVisibility) {
        this.footerVisibility = footerVisibility;
        return this;
    }

    /**
     * Set window close callback for the given modal.
     *
     * @param modal target modal.
     */
    protected void setWindowClosedReloadCallback(final BaseModal<?> modal) {
        modal.setWindowClosedCallback(target -> modal.show(false));
    }

    /**
     * Custom action to perform on create/edit action callback.
     *
     * @param target Ajax request target.
     */
    protected void customActionCallback(final AjaxRequestTarget target) {
    }

    /**
     * Custom action to perform on close callback on finish event.
     *
     * @param target Ajax request target.
     */
    protected void customActionOnFinishCallback(final AjaxRequestTarget target) {
    }

    /**
     * Custom action to perform on close callback on cancel event.
     *
     * @param target Ajax request target.
     */
    protected void customActionOnCancelCallback(final AjaxRequestTarget target) {
    }

    /**
     * PanelInWizard abstract builder.
     *
     * @param <T> list item reference type.
     */
    public abstract static class Builder<T extends Serializable> implements Serializable {

        private static final long serialVersionUID = 1908836274665387084L;

        protected final PageReference pageRef;

        private ModalPanelBuilder<T> newItemPanelBuilder;

        private boolean newItemDefaultButtonEnabled = true;

        private NotificationPanel notificationPanel;

        private boolean showResultPage = false;

        private boolean wizardInModal = false;

        protected Builder(final PageReference pageRef) {
            this.pageRef = pageRef;
        }

        protected abstract WizardMgtPanel<T> newInstance(String id, boolean wizardInModal);

        /**
         * Builds a list view.
         *
         * @param id component id.
         * @return List view.
         */
        public WizardMgtPanel<T> build(final String id) {
            return newInstance(id, wizardInModal).
                    setPageRef(this.pageRef).
                    setShowResultPage(this.showResultPage).
                    addNewItemPanelBuilder(this.newItemPanelBuilder, this.newItemDefaultButtonEnabled).
                    addNotificationPanel(this.notificationPanel);
        }

        public void setShowResultPage(final boolean showResultPage) {
            this.showResultPage = showResultPage;
        }

        public Builder<T> addNewItemPanelBuilder(final ModalPanelBuilder<T> panelBuilder) {
            this.newItemPanelBuilder = panelBuilder;
            return this;
        }

        /**
         * Adds new item panel builder.
         *
         * @param panelBuilder new item panel builder.
         * @param newItemDefaultButtonEnabled enable default button to adda new item.
         * @return the current builder.
         */
        public Builder<T> addNewItemPanelBuilder(
                final ModalPanelBuilder<T> panelBuilder, final boolean newItemDefaultButtonEnabled) {

            this.newItemDefaultButtonEnabled = newItemDefaultButtonEnabled;
            return addNewItemPanelBuilder(panelBuilder);
        }

        /**
         * Adds new item panel builder and enables default button to adda new item.
         *
         * @param notificationPanel new item panel builder.
         * @return the current builder.
         */
        public Builder<T> addNotificationPanel(final NotificationPanel notificationPanel) {
            this.notificationPanel = notificationPanel;
            return this;
        }

        /**
         * Specifies to open an edit item wizard into a new modal page.
         *
         * @param wizardInModal TRUE to request to open wizard in a new modal.
         * @return the current builder.
         */
        public Builder<T> setWizardInModal(final boolean wizardInModal) {
            this.wizardInModal = wizardInModal;
            return this;
        }
    }

    public static class ExitEvent {

        private final AjaxRequestTarget target;

        public ExitEvent(final AjaxRequestTarget target) {
            this.target = target;
        }

        public AjaxRequestTarget getTarget() {
            return target;
        }
    }

    public boolean isReadOnly() {
        return readOnly;
    }

    public void setReadOnly(final boolean readOnly) {
        this.readOnly = readOnly;
    }
}
