package eu.dnetlib.client.adminpanel;

import com.github.gwtbootstrap.client.ui.*;
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.FlowPanel;
import com.sencha.gxt.widget.core.client.info.Info;
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.Question;
import eu.dnetlib.espas.gui.shared.Topic;

import java.util.List;

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

    private Modal questionModal = new Modal();

    private FlowPanel questionFormPanel = new FlowPanel();

    private Alert errorLabel = new Alert();

    private Form questionForm = new Form();
    private ListBox topicsListBox = new ListBox();
    private TextArea questionTextBox = new TextArea();
    private TextArea answerTextBox = new TextArea();
    private TextBox weight = new TextBox();

    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 QuestionFormListener questionFormListener;

    public QuestionFormModal(final Question question, List<Topic> topics) {

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

        questionModal.add(questionFormPanel);

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

        questionFormPanel.add(questionForm);

        topicsListBox.addItem("-- none selected --", "noneSelected");
        for(Topic topic : topics)
            topicsListBox.addItem(topic.getTopicName(), topic.getId()+"");
        topicsListBox.setAlternateSize(AlternateSize.XXLARGE);
        questionForm.add(new FormFieldSet("Topic", topicsListBox));

        questionTextBox.setAlternateSize(AlternateSize.XXLARGE);
        questionForm.add(new FormFieldSet("Question", questionTextBox));

        answerTextBox.setAlternateSize(AlternateSize.XXLARGE);
        questionForm.add(new FormFieldSet("Answer", answerTextBox));

        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");
        questionForm.add(new FormFieldSet("Weight", weight, weightExample));

        actionButtons.addStyleName("confirmationModalButtons");

        modalFooter.add(actionButtons);
        questionModal.add(modalFooter);

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

        if(question!=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(!questionTextBox.getValue().trim().equals("") && !answerTextBox.getValue().trim().equals("")
                        && !topicsListBox.getValue().equals("noneSelected") && !weight.getValue().trim().equals("")) {

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

                        if (question != null) {

                            Question questionNew = new Question();
                            questionNew.setId(question.getId());
                            questionNew.setQuestion(questionTextBox.getValue().trim());
                            questionNew.setAnswer(answerTextBox.getValue().trim());
                            questionNew.setDate(question.getDate());
                            questionNew.setIsActive(question.isActive());
                            questionNew.setWeight(Float.parseFloat(weight.getValue().trim()));

                            Topic topic = new Topic();
                            topic.setId(Integer.parseInt(topicsListBox.getValue()));
                            questionNew.setTopic(topic);

                            faqService.updateQuestion(questionNew, new AsyncCallback<Void>() {

                                @Override
                                public void onFailure(Throwable caught) {

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

                                @Override
                                public void onSuccess(Void result) {

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

                        } else {

                            Question questionNew = new Question();
                            questionNew.setQuestion(questionTextBox.getValue().trim());
                            questionNew.setAnswer(answerTextBox.getValue().trim());
                            questionNew.setWeight(Float.parseFloat(weight.getValue().trim()));

                            Topic topic = new Topic();
                            topic.setId(Integer.parseInt(topicsListBox.getValue()));
                            questionNew.setTopic(topic);

                            faqService.insertQuestion(questionNew, new AsyncCallback<Void>() {

                                @Override
                                public void onFailure(Throwable caught) {

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

                                @Override
                                public void onSuccess(Void result) {

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

                } else {

                    errorLabel.setVisible(true);
                    errorLabel.setText("All fields are required");
                }
            }
        });
        actionButtons.add(saveButton);

        if(question!=null)
            loadQuestion(question);

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

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

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

    public interface QuestionFormListener {
        void onSaved();
    }

    public void setQuestionFormListener(QuestionFormListener questionFormListener) {
        this.questionFormListener = questionFormListener;
    }

    private void loadQuestion(Question question) {

        questionTextBox.setValue(question.getQuestion());
        answerTextBox.setValue(question.getAnswer());
        topicsListBox.setSelectedValue(question.getTopic().getId()+"");
        weight.setValue(Math.round(question.getWeight()*100) / 100.0+"");
    }

    private boolean isFloat(String value) {

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