package eu.dnetlib.client.adminpanel;

import com.github.gwtbootstrap.client.ui.*;
import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.Label;
import com.github.gwtbootstrap.client.ui.ListBox;
import com.github.gwtbootstrap.client.ui.TextArea;
import com.github.gwtbootstrap.client.ui.TextBox;
import com.github.gwtbootstrap.client.ui.constants.AlertType;
import com.github.gwtbootstrap.client.ui.constants.AlternateSize;
import com.github.gwtbootstrap.client.ui.constants.BackdropType;
import com.github.gwtbootstrap.client.ui.constants.ButtonType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import eu.dnetlib.espas.gui.client.FAQService;
import eu.dnetlib.espas.gui.client.FAQServiceAsync;
import eu.dnetlib.espas.gui.client.FormFieldSet;
import eu.dnetlib.espas.gui.shared.Topic;

/**
 * Created by stefania on 10/14/15.
 */
public class TopicFormModal {

    private Modal topicModal = new Modal();

    private FlowPanel topicFormPanel = new FlowPanel();

    private Alert errorLabel = new Alert();

    private Form topicForm = new Form();
    private TextBox name = new TextBox();
    private TextArea description = new TextArea();
    private TextBox weight = new TextBox();
    private ListBox questionsOrderListBox = new ListBox();

    private ModalFooter modalFooter = new ModalFooter();
    private FlowPanel actionButtons = new FlowPanel();
    private Button cancelButton = new Button();
    private Button saveButton = new Button();

    private FAQServiceAsync faqService = GWT.create(FAQService.class);

    private TopicFormListener topicFormListener;

    public TopicFormModal(final Topic topic) {

        if(topic!=null)
            topicModal.setTitle("Edit current topic");
        else
            topicModal.setTitle("Add a new topic");

        topicModal.add(topicFormPanel);

        errorLabel.setType(AlertType.ERROR);
        errorLabel.setVisible(false);
        errorLabel.setClose(false);
        topicFormPanel.add(errorLabel);

        topicFormPanel.add(topicForm);

        name.setAlternateSize(AlternateSize.XXLARGE);
        topicForm.add(new FormFieldSet("Name", name));

        description.setAlternateSize(AlternateSize.XXLARGE);
        topicForm.add(new FormFieldSet("Description", description));

        final com.google.gwt.user.client.ui.Label weightExample = new com.google.gwt.user.client.ui.Label("float representation e.g. 3.5");
        weightExample.addStyleName("comment");
        weightExample.addStyleName("fontItalic");

        weight.setAlternateSize(AlternateSize.XXLARGE);
        weight.addStyleName("inputWithComment");
        topicForm.add(new FormFieldSet("Weight", weight, weightExample));

        questionsOrderListBox.addItem("weight", "weight");
        questionsOrderListBox.addItem("hit count", "hitCount");
        questionsOrderListBox.setAlternateSize(AlternateSize.XXLARGE);
        topicForm.add(new FormFieldSet("Order Questions by", questionsOrderListBox));

        actionButtons.addStyleName("confirmationModalButtons");

        modalFooter.add(actionButtons);
        topicModal.add(modalFooter);

        cancelButton.setText("Cancel");
        cancelButton.setType(ButtonType.DEFAULT);
        cancelButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                hide();
            }
        });
        actionButtons.add(cancelButton);

        if(topic!=null)
            saveButton.setText("Save changes");
        else
            saveButton.setText("Save");
        saveButton.setType(ButtonType.SUCCESS);
        saveButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {

                errorLabel.setVisible(false);

                if(!name.getValue().trim().equals("") && !weight.getValue().trim().isEmpty()) {

                    if(isFloat(weight.getValue().trim())) {

                        if (topic != null) {

                            Topic topicNew = new Topic();
                            topicNew.setId(topic.getId());
                            topicNew.setTopicName(name.getValue().trim());
                            topicNew.setWeight(Float.parseFloat(weight.getValue().trim()));
                            topicNew.setQuestionOrder(questionsOrderListBox.getValue());
                            topicNew.setTopicDescription(description.getValue().trim());

                            faqService.updateTopic(topicNew, new AsyncCallback<Void>() {

                                @Override
                                public void onFailure(Throwable caught) {

                                    errorLabel.setText("System error updating existing topic");
                                    errorLabel.setVisible(true);
                                }

                                @Override
                                public void onSuccess(Void result) {

                                    hide();
                                    if (topicFormListener != null)
                                        topicFormListener.onSaved();
                                }
                            });

                        } else {

                            Topic topicNew = new Topic();
                            topicNew.setTopicName(name.getValue().trim());
                            topicNew.setWeight(Float.parseFloat(weight.getValue().trim()));
                            topicNew.setQuestionOrder(questionsOrderListBox.getValue());
                            topicNew.setTopicDescription(description.getValue().trim());

                            faqService.insertTopic(topicNew, new AsyncCallback<Void>() {

                                @Override
                                public void onFailure(Throwable caught) {

                                    errorLabel.setText("System error inserting the new topic");
                                    errorLabel.setVisible(true);
                                }

                                @Override
                                public void onSuccess(Void result) {

                                    hide();
                                    if (topicFormListener != null)
                                        topicFormListener.onSaved();
                                }
                            });
                        }
                    } else {
                        errorLabel.setVisible(true);
                        errorLabel.setText("Weight must be float");
                    }

                } else {

                    errorLabel.setVisible(true);
                    errorLabel.setText("Name, weight and questions order fields are required");
                }
            }
        });
        actionButtons.add(saveButton);

        if(topic!=null)
            loadTopic(topic);

        topicModal.addStyleName("formModal");
        topicModal.setAnimation(true);
        topicModal.setBackdrop(BackdropType.STATIC);
    }

    public void show() {
        topicModal.show();
    }

    public void hide() {
        topicModal.hide();
        topicModal.removeFromParent();
    }

    public interface TopicFormListener {
        void onSaved();
    }

    public void setTopicFormListener(TopicFormListener topicFormListener) {
        this.topicFormListener = topicFormListener;
    }

    private void loadTopic(Topic topic) {

        name.setValue(topic.getTopicName());
        description.setValue(topic.getTopicDescription());
        weight.setValue(Math.round(topic.getWeight()*100) / 100.0+"");
        questionsOrderListBox.setSelectedValue(topic.getQuestionOrder());
    }

    private boolean isFloat(String value) {

        try {
            Float.parseFloat(value);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }
}
