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.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.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.TimeZone;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import eu.dnetlib.espas.gui.client.FormFieldSet;
import eu.dnetlib.espas.gui.client.MessageService;
import eu.dnetlib.espas.gui.client.MessageServiceAsync;
import eu.dnetlib.espas.gui.shared.Message;

import java.util.Date;


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

    private Modal announcementModal = new Modal();

    private FlowPanel announcementFormPanel = new FlowPanel();

    private Alert errorLabel = new Alert();

    private Form announcementForm = new Form();
    private TextBox validFrom = new TextBox();
    private TextBox validTo = new TextBox();
    private TextArea messageArea = new TextArea();

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

    private DateTimeFormat dtf = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ");
    private TimeZone tz = TimeZone.createTimeZone(0);

    private MessageServiceAsync messageService = GWT.create(MessageService.class);

    private AnnouncementsFormListener announcementsFormListener;

    public AnnouncementFormModal(final Message message) {

        if(message!=null)
            announcementModal.setTitle("Edit current announcement");
        else
            announcementModal.setTitle("Add a new announcement");

        announcementModal.add(announcementFormPanel);

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

        announcementFormPanel.add(announcementForm);

        com.google.gwt.user.client.ui.Label dateFromExample = new com.google.gwt.user.client.ui.Label("e.g. " + dtf.format(new Date()));
        dateFromExample.addStyleName("comment");
        dateFromExample.addStyleName("fontItalic");

        validFrom.setAlternateSize(AlternateSize.XXLARGE);
        validFrom.addStyleName("inputWithComment");
        announcementForm.add(new FormFieldSet("Valid From", validFrom, dateFromExample));

        com.google.gwt.user.client.ui.Label dateToExample = new com.google.gwt.user.client.ui.Label("e.g. " + dtf.format(new Date()));
        dateToExample.addStyleName("comment");
        dateToExample.addStyleName("fontItalic");

        validTo.setAlternateSize(AlternateSize.XXLARGE);
        validTo.addStyleName("inputWithComment");
        announcementForm.add(new FormFieldSet("Valid To", validTo, dateToExample));

        messageArea.setAlternateSize(AlternateSize.XXLARGE);
        announcementForm.add(new FormFieldSet("Message Area", messageArea));

        actionButtons.addStyleName("confirmationModalButtons");

        modalFooter.add(actionButtons);
        announcementModal.add(modalFooter);

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

        if(message!=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);

                boolean isValidFromValid = isValidFromValid();
                boolean isValidToValid = isValidToValid();
                boolean hasMessage = messageArea.getValue()!=null && !messageArea.getValue().trim().equals("");

                if(isValidFromValid && isValidToValid && hasMessage) {

                    if(message!=null) {

                        Message messageNew = new Message();
                        messageNew.setId(message.getId());
                        messageNew.setValidFrom(DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(validFrom.getValue()));
                        messageNew.setValidTo(DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(validTo.getValue()));
                        messageNew.setMessageText(messageArea.getValue());

                        messageService.updateMessage(messageNew, new AsyncCallback<Void>() {

                            @Override
                            public void onFailure(Throwable throwable) {

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

                            @Override
                            public void onSuccess(Void aVoid) {

                                hide();
                                if(announcementsFormListener!=null)
                                    announcementsFormListener.onSaved();
                            }
                        });
                    } else {

                        Message messageNew = new Message();
                        messageNew.setValidFrom(DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(validFrom.getValue()));
                        messageNew.setValidTo(DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(validTo.getValue()));
                        messageNew.setMessageText(messageArea.getValue());

                        messageService.insertMessage(messageNew, new AsyncCallback<Void>() {

                            @Override
                            public void onFailure(Throwable throwable) {

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

                            @Override
                            public void onSuccess(Void aVoid) {

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

                } else {

                    errorLabel.setVisible(true);

                    if(!isValidFromValid && !isValidToValid && !hasMessage) {
                        errorLabel.setText("Valid From Date and Valid To Date is invalid, and message is missing.");
                    } else if(!isValidFromValid && !isValidToValid && hasMessage) {
                        errorLabel.setText("Valid From Date and Valid To Date is invalid.");
                    } else if(!isValidFromValid && isValidToValid && !hasMessage) {
                        errorLabel.setText("Valid From Date is invalid and message is missing.");
                    } else if(!isValidFromValid && isValidToValid && hasMessage) {
                        errorLabel.setText("Valid From Date is invalid.");
                    } else if(isValidFromValid && !isValidToValid && !hasMessage) {
                        errorLabel.setText("Valid To Date is invalid and message is missing.");
                    } else if(isValidFromValid && !isValidToValid && hasMessage) {
                        errorLabel.setText("Valid To Date is invalid.");
                    } else if(isValidFromValid && isValidToValid && !hasMessage) {
                        errorLabel.setText("Message is missing.");
                    }
                }
            }
        });
        actionButtons.add(saveButton);

        if(message!=null)
            loadAnnouncement(message);

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

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

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

    public interface AnnouncementsFormListener {
        void onSaved();
    }

    public void setAnnouncementsFormListener(AnnouncementsFormListener announcementsFormListener) {
        this.announcementsFormListener = announcementsFormListener;
    }

    private void loadAnnouncement(Message message) {

        validFrom.setValue(dtf.format(message.getValidFrom(), tz));
        validTo.setValue(dtf.format(message.getValidTo(), tz));
        messageArea.setValue(message.getMessageText());
    }

    private boolean isValidFromValid() {

        try {
            DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(validFrom.getValue());
        } catch (Exception exc) {
            return false;
        }

        return true;
    }

    private boolean isValidToValid() {

        try {
            DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(validTo.getValue());
        } catch (Exception exc) {
            return false;
        }

        return true;
    }
}
