/*
 * 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.any;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.console.panels.AnyDirectoryPanel;
import org.apache.syncope.client.console.panels.ListViewPanel;
import org.apache.syncope.client.console.panels.ListViewPanel.ListViewReload;
import org.apache.syncope.client.console.panels.search.AnyObjectSearchPanel;
import org.apache.syncope.client.console.panels.search.AnyObjectSelectionDirectoryPanel;
import org.apache.syncope.client.console.panels.search.AnySelectionDirectoryPanel;
import org.apache.syncope.client.console.panels.search.SearchClausePanel;
import org.apache.syncope.client.console.panels.search.SearchUtils;
import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
import org.apache.syncope.client.console.rest.AnyTypeRestClient;
import org.apache.syncope.client.console.rest.RelationshipTypeRestClient;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
import org.apache.syncope.client.console.wizards.WizardMgtPanel;
import org.apache.syncope.client.lib.SyncopeClient;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
import org.apache.syncope.client.ui.commons.ajax.markup.html.LabelInfo;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
import org.apache.syncope.client.ui.commons.wizards.any.UserWrapper;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.AnyTypeTO;
import org.apache.syncope.common.lib.to.EntityTO;
import org.apache.syncope.common.lib.to.GroupableRelatableTO;
import org.apache.syncope.common.lib.to.RelationshipTO;
import org.apache.syncope.common.lib.types.AnyEntitlement;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.wicket.Component;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.extensions.wizard.IWizard;
import org.apache.wicket.extensions.wizard.WizardModel.ICondition;
import org.apache.wicket.extensions.wizard.WizardStep;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.model.util.ListModel;

public class Relationships extends WizardStep implements ICondition {

    private static final long serialVersionUID = 855618618337931784L;

    protected final AnyTO anyTO;

    protected final Specification specification;

    protected final PageReference pageRef;

    public Relationships(final AnyWrapper<?> modelObject, final PageReference pageRef) {
        super();
        add(new Label("title", new ResourceModel("any.relationships")));

        if (modelObject instanceof UserWrapper
                && UserWrapper.class.cast(modelObject).getPreviousUserTO() != null
                && !ListUtils.isEqualList(
                        UserWrapper.class.cast(modelObject).getInnerObject().getRelationships(),
                        UserWrapper.class.cast(modelObject).getPreviousUserTO().getRelationships())) {
            add(new LabelInfo("changed", StringUtils.EMPTY));
        } else {
            add(new Label("changed", StringUtils.EMPTY));
        }

        this.anyTO = modelObject.getInnerObject();
        this.specification = new Specification();
        this.pageRef = pageRef;

        // ------------------------
        // Existing relationships
        // ------------------------
        add(getViewFragment().setRenderBodyOnly(true));
        // ------------------------ 
    }

    @Override
    public Component getHeader(final String id, final Component parent, final IWizard wizard) {
        return super.getHeader(id, parent, wizard).setVisible(false);
    }

    protected Fragment getViewFragment() {
        Map<String, List<RelationshipTO>> relationships = new HashMap<>();
        addRelationship(relationships, getCurrentRelationships().toArray(RelationshipTO[]::new));

        Fragment viewFragment = new Fragment("relationships", "viewFragment", this);
        viewFragment.setOutputMarkupId(true);

        viewFragment.add(new Accordion("relationships", relationships.keySet().stream().
                map(relationship -> new AbstractTab(new ResourceModel("relationship", relationship)) {

            private static final long serialVersionUID = 1037272333056449378L;

            @Override
            public Panel getPanel(final String panelId) {
                return new ListViewPanel.Builder<>(RelationshipTO.class, pageRef).
                        setItems(relationships.get(relationship)).
                        includes("otherEndType", "otherEndKey", "otherEndName").
                        addAction(new ActionLink<>() {

                            private static final long serialVersionUID = -6847033126124401556L;

                            @Override
                            public void onClick(final AjaxRequestTarget target, final RelationshipTO modelObject) {
                                removeRelationships(relationships, modelObject);
                                send(Relationships.this, Broadcast.DEPTH, new ListViewReload<>(target));
                            }
                        }, ActionType.DELETE, AnyEntitlement.UPDATE.getFor(anyTO.getType()), true).
                        build(panelId);
            }
        }).collect(Collectors.toList())) {

            private static final long serialVersionUID = 1037272333056449379L;

            @Override
            public void renderHead(final IHeaderResponse response) {
                super.renderHead(response);
                if (relationships.isEmpty()) {
                    response.render(OnDomReadyHeaderItem.forScript(String.format(
                            "$('#emptyPlaceholder').append(\"%s\")", getString("relationships.empty.list"))));
                }
            }
        });

        ActionsPanel<RelationshipTO> panel = new ActionsPanel<>("actions", null);
        viewFragment.add(panel);

        panel.add(new ActionLink<>() {

            private static final long serialVersionUID = 3257738274365467945L;

            @Override
            public void onClick(final AjaxRequestTarget target, final RelationshipTO ignore) {
                Fragment addFragment = new Fragment("relationships", "addFragment", Relationships.this);
                addOrReplace(addFragment);
                addFragment.add(specification.setRenderBodyOnly(true));
                target.add(Relationships.this);
            }
        }, ActionType.CREATE, AnyEntitlement.UPDATE.getFor(anyTO.getType())).hideLabel();

        return viewFragment;
    }

    protected List<RelationshipTO> getCurrentRelationships() {
        return anyTO instanceof GroupableRelatableTO
                ? GroupableRelatableTO.class.cast(anyTO).getRelationships()
                : List.of();
    }

    protected void addRelationship(
            final Map<String, List<RelationshipTO>> relationships,
            final RelationshipTO... rels) {

        for (RelationshipTO relationship : rels) {
            List<RelationshipTO> listrels;
            if (relationships.containsKey(relationship.getType())) {
                listrels = relationships.get(relationship.getType());
            } else {
                listrels = new ArrayList<>();
                relationships.put(relationship.getType(), listrels);
            }
            listrels.add(relationship);
        }
    }

    protected void addNewRelationships(final RelationshipTO... rels) {
        getCurrentRelationships().addAll(List.of(rels));
    }

    protected void removeRelationships(
            final Map<String, List<RelationshipTO>> relationships, final RelationshipTO... rels) {

        List<RelationshipTO> currentRels = getCurrentRelationships();
        for (RelationshipTO relationship : rels) {
            currentRels.remove(relationship);
            if (relationships.containsKey(relationship.getType())) {
                List<RelationshipTO> rellist = relationships.get(relationship.getType());
                rellist.remove(relationship);
                if (rellist.isEmpty()) {
                    relationships.remove(relationship.getType());
                }
            }
        }
    }

    @Override
    public boolean evaluate() {
        // [SYNCOPE-1171] - skip current step when the are no relationships types in Syncope
        return !RelationshipTypeRestClient.list().isEmpty();
    }

    public class Specification extends Panel {

        private static final long serialVersionUID = 6199050589175839467L;

        protected final RelationshipTO rel;

        protected final AjaxDropDownChoicePanel<String> type;

        protected final AjaxDropDownChoicePanel<AnyTypeTO> otherType;

        protected final WebMarkupContainer container;

        protected final Fragment emptyFragment;

        protected final Fragment fragment;

        protected AnyObjectSearchPanel anyObjectSearchPanel;

        protected WizardMgtPanel<AnyWrapper<AnyObjectTO>> anyObjectDirectoryPanel;

        public Specification() {
            super("specification");
            rel = new RelationshipTO();

            List<String> availableRels = RelationshipTypeRestClient.list().stream().
                    map(EntityTO::getKey).collect(Collectors.toList());

            type = new AjaxDropDownChoicePanel<>("type", "type", new PropertyModel<>(rel, "type"));
            type.setChoices(availableRels);
            add(type.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true).setRenderBodyOnly(true));

            List<AnyTypeTO> availableTypes = AnyTypeRestClient.listAnyTypes().stream().
                    filter(anyType -> anyType.getKind() != AnyTypeKind.GROUP
                    && anyType.getKind() != AnyTypeKind.USER).collect(Collectors.toList());

            otherType = new AjaxDropDownChoicePanel<>("otherType", "otherType", new PropertyModel<>(rel, "otherType") {

                private static final long serialVersionUID = -5861057041758169508L;

                @Override
                public AnyTypeTO getObject() {
                    for (AnyTypeTO obj : availableTypes) {
                        if (obj.getKey().equals(rel.getOtherEndType())) {
                            return obj;
                        }
                    }
                    return null;
                }

                @Override
                public void setObject(final AnyTypeTO object) {
                    rel.setOtherEndType(Optional.ofNullable(object).map(AnyTypeTO::getKey).orElse(null));
                }
            }, false);
            otherType.setChoices(availableTypes);
            otherType.setChoiceRenderer(new IChoiceRenderer<>() {

                private static final long serialVersionUID = -734743540442190178L;

                @Override
                public Object getDisplayValue(final AnyTypeTO object) {
                    return object.getKey();
                }

                @Override
                public String getIdValue(final AnyTypeTO object, final int index) {
                    return object.getKey();
                }

                @Override
                public AnyTypeTO getObject(final String id, final IModel<? extends List<? extends AnyTypeTO>> choices) {
                    return choices.getObject().stream().
                            filter(anyTypeTO -> id.equals(anyTypeTO.getKey())).findAny().orElse(null);
                }
            });
            // enable "otherType" dropdown only if "type" option is selected - SYNCOPE-1140
            otherType.setEnabled(false);
            add(otherType.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));

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

            emptyFragment = new Fragment("searchPanel", "emptyFragment", this);
            container.add(emptyFragment.setRenderBodyOnly(true));

            fragment = new Fragment("searchPanel", "searchFragment", Specification.this);

            type.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {

                private static final long serialVersionUID = -1107858522700306810L;

                @Override
                protected void onUpdate(final AjaxRequestTarget target) {
                    container.addOrReplace(emptyFragment.setRenderBodyOnly(true));
                    otherType.setModelObject(null);
                    // enable "otherType" dropdown only if "type" option is selected - SYNCOPE-1140
                    otherType.setEnabled(type.getModelObject() != null && !type.getModelObject().isEmpty());
                    target.add(otherType);
                    target.add(container);
                }
            });

            otherType.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {

                private static final long serialVersionUID = -1107858522700306810L;

                @Override
                protected void onUpdate(final AjaxRequestTarget target) {
                    AnyTypeTO anyType = otherType.getModelObject();
                    if (anyType == null) {
                        container.addOrReplace(emptyFragment.setRenderBodyOnly(true));
                    } else {
                        setupFragment(anyType);
                        container.addOrReplace(fragment.setRenderBodyOnly(true));
                    }
                    target.add(container);
                }
            });
        }

        protected void setupFragment(final AnyTypeTO anyType) {
            anyObjectSearchPanel = new AnyObjectSearchPanel.Builder(
                    anyType.getKey(),
                    new ListModel<>(new ArrayList<>())).
                    enableSearch(Specification.this).
                    build("searchPanel");
            fragment.addOrReplace(anyObjectSearchPanel.setRenderBodyOnly(true));

            anyObjectDirectoryPanel = new AnyObjectSelectionDirectoryPanel.Builder(
                    AnyTypeClassRestClient.list(anyType.getClasses()),
                    anyType.getKey(),
                    pageRef).
                    setFiql(SyncopeClient.getAnyObjectSearchConditionBuilder(anyType.getKey()).
                            is(Constants.KEY_FIELD_NAME).notNullValue().query()).
                    setWizardInModal(true).build("searchResultPanel");
            fragment.addOrReplace(anyObjectDirectoryPanel.setRenderBodyOnly(true));
        }

        @Override
        public void onEvent(final IEvent<?> event) {
            if (event.getPayload() instanceof SearchClausePanel.SearchEvent) {
                AjaxRequestTarget target =
                        SearchClausePanel.SearchEvent.class.cast(event.getPayload()).getTarget();
                String fiql = SearchUtils.buildFIQL(anyObjectSearchPanel.getModel().getObject(),
                        SyncopeClient.getAnyObjectSearchConditionBuilder(anyObjectSearchPanel.getBackObjectType()));
                AnyDirectoryPanel.class.cast(Specification.this.anyObjectDirectoryPanel).search(fiql, target);
            } else if (event.getPayload() instanceof AnySelectionDirectoryPanel.ItemSelection) {
                AjaxRequestTarget target =
                        AnySelectionDirectoryPanel.ItemSelection.class.cast(event.getPayload()).getTarget();

                AnyTO right = AnySelectionDirectoryPanel.ItemSelection.class.cast(event.getPayload()).getSelection();
                rel.setOtherEndKey(right.getKey());

                Relationships.this.addNewRelationships(rel);

                Relationships.this.addOrReplace(getViewFragment().setRenderBodyOnly(true));
                target.add(Relationships.this);
            } else {
                super.onEvent(event);
            }
        }
    }
}
