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

import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.layout.AnyLayoutUtils;
import org.apache.syncope.client.console.pages.BasePage;
import org.apache.syncope.client.console.panels.UserRequestFormDirectoryPanel.UserRequestFormProvider;
import org.apache.syncope.client.console.panels.UserRequestsPanel.UserRequestSearchEvent;
import org.apache.syncope.client.console.rest.AnyTypeRestClient;
import org.apache.syncope.client.console.rest.UserRequestRestClient;
import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksTogglePanel;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
import org.apache.syncope.client.console.widgets.UserRequestFormsWidget;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.DirectoryDataProvider;
import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
import org.apache.syncope.common.lib.AnyOperations;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.UserRequestForm;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.FlowableEntitlement;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;

public class UserRequestFormDirectoryPanel
        extends DirectoryPanel<UserRequestForm, UserRequestForm, UserRequestFormProvider, UserRequestRestClient> {

    private static final long serialVersionUID = -7122136682275797903L;

    private static final String PREF_USER_REQUEST_FORM_PAGINATOR_ROWS = "userrequestform.paginator.rows";

    private final BaseModal<UserRequestForm> manageFormModal = new BaseModal<>("outer") {

        private static final long serialVersionUID = 389935548143327858L;

        @Override
        protected void onConfigure() {
            super.onConfigure();
            addSubmitButton();
            size(Modal.Size.Large);
        }
    };

    private String keyword;

    public UserRequestFormDirectoryPanel(final String id, final PageReference pageRef) {
        super(id, pageRef, true);
        disableCheckBoxes();
        setFooterVisibility(false);
        modal.size(Modal.Size.Large);

        addOuterObject(manageFormModal);

        manageFormModal.setWindowClosedCallback(target -> {
            updateResultTable(target);

            Serializable widget = SyncopeConsoleSession.get().getAttribute(UserRequestFormsWidget.class.getName());
            if (widget instanceof UserRequestFormsWidget) {
                ((UserRequestFormsWidget) widget).refreshLatestAlerts(target);
            }

            manageFormModal.show(false);
        });

        restClient = new UserRequestRestClient();

        initResultTable();

        MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, FlowableEntitlement.USER_REQUEST_FORM_SUBMIT);
    }

    @Override
    protected List<IColumn<UserRequestForm, String>> getColumns() {
        List<IColumn<UserRequestForm, String>> columns = new ArrayList<>();

        columns.add(new PropertyColumn<>(
                new ResourceModel("bpmnProcess"), "bpmnProcess", "bpmnProcess"));
        columns.add(new PropertyColumn<>(
                new ResourceModel("key"), "formKey", "formKey"));
        columns.add(new PropertyColumn<>(
                new ResourceModel("username"), "username"));
        columns.add(new DatePropertyColumn<>(
                new ResourceModel("createTime"), "createTime", "createTime"));
        columns.add(new DatePropertyColumn<>(
                new ResourceModel("dueDate"), "dueDate", "dueDate"));
        columns.add(new PropertyColumn<>(
                new ResourceModel("assignee"), "assignee", "assignee"));

        return columns;
    }

    @Override
    protected ActionLinksTogglePanel<UserRequestForm> actionTogglePanel() {
        return new ActionLinksTogglePanel<>(Constants.OUTER, pageRef) {

            private static final long serialVersionUID = -7688359318035249200L;

            @Override
            public void updateHeader(final AjaxRequestTarget target, final Serializable object) {
                if (object instanceof UserRequestForm) {
                    setHeader(target, StringUtils.abbreviate(
                        ((UserRequestForm) object).getUsername(), HEADER_FIRST_ABBREVIATION));
                } else {
                    super.updateHeader(target, object);
                }
            }
        };
    }

    @Override
    public ActionsPanel<UserRequestForm> getActions(final IModel<UserRequestForm> model) {
        final ActionsPanel<UserRequestForm> panel = super.getActions(model);

        panel.add(new ActionLink<>() {

            private static final long serialVersionUID = -3722207913631435501L;

            @Override
            public void onClick(final AjaxRequestTarget target, final UserRequestForm ignore) {
                try {
                    UserRequestRestClient.claimForm(model.getObject().getTaskId());
                    SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
                    target.add(container);
                } catch (Exception e) {
                    SyncopeConsoleSession.get().onException(e);
                }
                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
            }

        }, ActionLink.ActionType.CLAIM, FlowableEntitlement.USER_REQUEST_FORM_CLAIM);

        panel.add(new ActionLink<>() {

            private static final long serialVersionUID = -4496313424398213416L;

            @Override
            public void onClick(final AjaxRequestTarget target, final UserRequestForm ignore) {
                try {
                    UserRequestRestClient.unclaimForm(model.getObject().getTaskId());
                    SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
                    UserRequestFormDirectoryPanel.this.getTogglePanel().close(target);
                    target.add(container);
                } catch (Exception e) {
                    SyncopeConsoleSession.get().onException(e);
                }
                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
            }

            @Override
            protected boolean statusCondition(final UserRequestForm modelObject) {
                return SyncopeConsoleSession.get().getSelfTO().getUsername().
                    equals(model.getObject().getAssignee());
            }

        }, ActionLink.ActionType.UNCLAIM, FlowableEntitlement.USER_REQUEST_FORM_UNCLAIM);

        panel.add(new ActionLink<>() {

            private static final long serialVersionUID = -3722207913631435501L;

            @Override
            public void onClick(final AjaxRequestTarget target, final UserRequestForm ignore) {
                manageFormModal.setFormModel(new CompoundPropertyModel<>(model.getObject()));

                target.add(manageFormModal.setContent(new UserRequestFormModal(manageFormModal, pageRef, model.
                    getObject()) {

                    private static final long serialVersionUID = 5546519445061007248L;

                    @Override
                    public void onSubmit(final AjaxRequestTarget target) {
                        try {
                            super.onSubmit(target);

                            UserRequestFormDirectoryPanel.this.getTogglePanel().close(target);
                        } catch (SyncopeClientException e) {
                            SyncopeConsoleSession.get().onException(e);
                        }
                        ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                    }
                }));

                manageFormModal.header(new Model<>(getString("form.manage", new Model<>(model.getObject()))));
                manageFormModal.show(true);
            }

            @Override
            protected boolean statusCondition(final UserRequestForm modelObject) {
                return SyncopeConsoleSession.get().getSelfTO().getUsername().
                    equals(model.getObject().getAssignee());
            }

        }, ActionLink.ActionType.MANAGE_APPROVAL, FlowableEntitlement.USER_REQUEST_FORM_SUBMIT);

        // SYNCOPE-1200 edit user while in approval state
        panel.add(new ActionLink<>() {

            private static final long serialVersionUID = -3722207913631435501L;

            @Override
            public void onClick(final AjaxRequestTarget target, final UserRequestForm ignore) {
                modal.setFormModel(new CompoundPropertyModel<>(model.getObject()));

                UserRequestForm formTO = model.getObject();
                UserTO newUserTO;
                if (formTO.getUserUR() == null) {
                    newUserTO = formTO.getUserTO();
                    if (newUserTO != null) {
                        // SYNCOPE-1563 do not use the password into formTO.getUserTO()
                        newUserTO.setPassword(null);
                    }
                } else if (formTO.getUserTO() == null) {
                    // make it stronger by handling possible NPE
                    UserTO previousUserTO = new UserTO();
                    previousUserTO.setKey(formTO.getUserUR().getKey());
                    newUserTO = AnyOperations.patch(previousUserTO, formTO.getUserUR());
                } else {
                    formTO.getUserTO().setKey(formTO.getUserUR().getKey());
                    formTO.getUserTO().setPassword(null);
                    newUserTO = AnyOperations.patch(formTO.getUserTO(), formTO.getUserUR());
                }

                AjaxWizard.EditItemActionEvent<UserTO> editItemActionEvent =
                    new AjaxWizard.EditItemActionEvent<>(newUserTO, target);
                editItemActionEvent.forceModalPanel(AnyLayoutUtils.newLayoutInfo(
                    newUserTO,
                    AnyTypeRestClient.read(AnyTypeKind.USER.name()).getClasses(),
                    AnyLayoutUtils.fetch(List.of(AnyTypeKind.USER.name())).getUser(),
                    pageRef).
                    build(BaseModal.CONTENT_ID, 0, AjaxWizard.Mode.EDIT_APPROVAL));

                send(UserRequestFormDirectoryPanel.this, Broadcast.EXACT, editItemActionEvent);
            }

            @Override
            protected boolean statusCondition(final UserRequestForm modelObject) {
                return SyncopeConsoleSession.get().getSelfTO().getUsername().
                    equals(model.getObject().getAssignee());
            }

        }, ActionLink.ActionType.EDIT_APPROVAL, FlowableEntitlement.USER_REQUEST_FORM_SUBMIT);

        return panel;
    }

    @Override
    protected UserRequestFormProvider dataProvider() {
        return new UserRequestFormProvider(rows);
    }

    @Override
    protected String paginatorRowsKey() {
        return PREF_USER_REQUEST_FORM_PAGINATOR_ROWS;
    }

    @Override
    protected Collection<ActionLink.ActionType> getBatches() {
        return List.of();
    }

    @Override
    public void onEvent(final IEvent<?> event) {
        if (event.getPayload() instanceof UserRequestSearchEvent) {
            UserRequestSearchEvent payload = UserRequestSearchEvent.class.cast(event.getPayload());
            keyword = payload.getKeyword();

            updateResultTable(payload.getTarget());
        } else {
            super.onEvent(event);
        }
    }

    protected final class UserRequestFormProvider extends DirectoryDataProvider<UserRequestForm> {

        private static final long serialVersionUID = -2311716167583335852L;

        public UserRequestFormProvider(final int paginatorRows) {
            super(paginatorRows);

            setSort("createTime", SortOrder.ASCENDING);
        }

        @Override
        public Iterator<UserRequestForm> iterator(final long first, final long count) {
            int page = ((int) first / paginatorRows);
            return UserRequestRestClient.listForms(
                    keyword, (page < 0 ? 0 : page) + 1, paginatorRows, getSort()).iterator();
        }

        @Override
        public long size() {
            return UserRequestRestClient.countForms(keyword);
        }

        @Override
        public IModel<UserRequestForm> model(final UserRequestForm form) {
            return Model.of(form);
        }
    }
}
