/*
 * 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.ui.commons.markup.html.form;

import java.util.List;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.ajax.markup.html.IndicatorAjaxSubmitLink;
import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
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.IModel;
import org.apache.wicket.model.ResourceModel;
import org.springframework.util.CollectionUtils;

public abstract class AbstractMultiPanel<INNER> extends AbstractFieldPanel<List<INNER>> {

    private static final long serialVersionUID = -6322397761456513324L;

    private final ListView<INNER> view;

    private final WebMarkupContainer container;

    private final Form<?> form;

    public AbstractMultiPanel(
            final String id,
            final String name,
            final IModel<List<INNER>> model) {

        super(id, name, model);

        // -----------------------
        // Object container definition
        // -----------------------
        container = new WebMarkupContainer("multiValueContainer");
        container.setOutputMarkupId(true);
        add(container);

        form = new Form<>("innerForm");
        form.setDefaultButton(null);
        container.add(form);
        // -----------------------

        view = new InnerView("view", name, model);

        if (CollectionUtils.isEmpty(model.getObject())) {
            form.addOrReplace(getNoDataFragment(model, name));
        } else {
            form.addOrReplace(getDataFragment());
        }
    }

    // SYNCOPE-1476
    public AbstractMultiPanel<INNER> setFormAsMultipart(final boolean multipart) {
        form.setMultiPart(multipart);
        return this;
    }

    private Fragment getNoDataFragment(final IModel<List<INNER>> model, final String label) {
        Fragment fragment = new Fragment("content", "noDataFragment", AbstractMultiPanel.this);
        fragment.add(new Label("field-label", new ResourceModel(label, label)));
        fragment.add(getPlusFragment(model));
        return fragment;
    }

    private Fragment getDataFragment() {
        Fragment contentFragment = new Fragment("content", "dataFragment", AbstractMultiPanel.this);
        contentFragment.add(view.setOutputMarkupId(true));
        return contentFragment;
    }

    private Fragment getPlusFragment(final IModel<List<INNER>> model) {
        IndicatorAjaxSubmitLink plus = new IndicatorAjaxSubmitLink("add") {

            private static final long serialVersionUID = -7978723352517770644L;

            @Override
            protected void onSubmit(final AjaxRequestTarget target) {
                //Add current component
                model.getObject().add(newModelObject());

                if (model.getObject().size() == 1) {
                    form.addOrReplace(getDataFragment());
                }

                target.add(container);
            }

            @Override
            protected void onError(final AjaxRequestTarget target) {
                sendError(getString(Constants.OPERATION_ERROR));
                super.onError(target);
                ((BaseWebPage) getPage()).getNotificationPanel().refresh(target);
            }

        };

        Fragment fragment = new Fragment("panelPlus", "fragmentPlus", AbstractMultiPanel.this);
        fragment.addOrReplace(plus);
        fragment.setRenderBodyOnly(true);

        return fragment;
    }

    public ListView<INNER> getView() {
        return view;
    }

    @Override
    public AbstractMultiPanel<INNER> setModelObject(final List<INNER> object) {
        view.setModelObject(object);
        return this;
    }

    protected abstract INNER newModelObject();

    protected abstract void sendError(String message);

    private final class InnerView extends ListView<INNER> {

        private static final long serialVersionUID = -9180479401817023838L;

        private final String label;

        private final IModel<List<INNER>> model;

        private InnerView(final String id, final String label, final IModel<List<INNER>> model) {
            super(id, model);
            this.label = label;
            this.model = model;
        }

        @Override
        protected void populateItem(final ListItem<INNER> item) {
            Panel panel = getItemPanel(item);

            item.add(panel.setRenderBodyOnly(true));

            IndicatorAjaxSubmitLink minus = new IndicatorAjaxSubmitLink("drop") {

                private static final long serialVersionUID = -7978723352517770644L;

                @Override
                protected void onSubmit(final AjaxRequestTarget target) {
                    //Drop current component
                    model.getObject().remove(item.getModelObject());
                    clearInput(panel);

                    if (model.getObject().isEmpty()) {
                        form.addOrReplace(getNoDataFragment(model, label));
                    }

                    target.add(container);
                }

                @Override
                protected void onError(final AjaxRequestTarget target) {
                    onSubmit(target);
                }
            };

            item.add(minus);

            Fragment fragment = item.getIndex() == model.getObject().size() - 1
                    ? getPlusFragment(model)
                    : new Fragment("panelPlus", "emptyFragment", AbstractMultiPanel.this);

            item.add(fragment.setRenderBodyOnly(true));
        }
    }

    protected abstract Panel getItemPanel(ListItem<INNER> item);

    protected void clearInput(final Panel panel) {
        // do nothing by default
    }

    @Override
    public AbstractFieldPanel<List<INNER>> setReadOnly(final boolean readOnly) {
        container.setEnabled(!readOnly);
        return this;
    }

    public AbstractFieldPanel<List<INNER>> setFormReadOnly(final boolean readOnly) {
        form.setEnabled(!readOnly);
        return this;
    }
}
