package eu.dnetlib.client;

import com.github.gwtbootstrap.client.ui.*;
import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.ListBox;
import com.github.gwtbootstrap.client.ui.SubmitButton;
import com.github.gwtbootstrap.client.ui.base.IconAnchor;
import com.github.gwtbootstrap.client.ui.constants.*;
import com.github.gwtbootstrap.datepicker.client.ui.DateBox;
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.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import eu.dnetlib.client.widgets.FormFieldSet;
import eu.dnetlib.client.widgets.TextBox;
import eu.dnetlib.goldoa.domain.*;

import java.util.Date;

/**
 * Created by stefania on 4/2/15.
 */
public class NewBudgetRequestWidget implements MyWidget {

    private String token = "";

    private FlowPanel newBudgetRequestPanel = new FlowPanel();

    private Label titleLabel = new Label();
    private Label informationLabel = new Label();

    private Alert informationAlert = new Alert();
    private Alert errorLabel = new Alert();

    private FlowPanel budgetFormPanel = new FlowPanel();

    private Form budgetForm = new Form();
    private ListBox institutions = new ListBox();
    private Label publisher = new Label();
    private TextBox budgetRequestedTextBox = new TextBox();
    private DateBox startDateDateBox = new DateBox();
    private DateBox endDateDateBox = new DateBox();

    private Label bankInfoLabel = new Label();
    private TextBox nameOfBank = new TextBox();
    private TextBox addressOfBank = new TextBox();
    private TextBox accountHolder = new TextBox();
    private TextBox accountNumber = new TextBox();
    private TextBox bankCode = new TextBox();

    private Button submit = new Button("Submit");

    private HTML loadingWheel = new HTML("<div class=\"loader\"></div><div class=\"whiteFilm\"></div>");

    private DataServiceAsync dataService = GWT.create(DataService.class);

    public NewBudgetRequestWidget() {

        newBudgetRequestPanel.addStyleName("content");

        titleLabel.setText("New Budget Request");
        titleLabel.addStyleName("contentTitleLabel");

        informationLabel.setText("Request a new budget for an institution that you are affiliated with.");
        informationLabel.addStyleName("contentInfoLabel");

        informationAlert.addStyleName("alertLabel");
        informationAlert.setType(AlertType.SUCCESS);
        informationAlert.setClose(false);
        informationAlert.setVisible(false);

        errorLabel.addStyleName("alertLabel");
        errorLabel.setType(AlertType.ERROR);
        errorLabel.setClose(false);
        errorLabel.setVisible(false);

        budgetForm.setType(FormType.HORIZONTAL);
        budgetForm.addStyleName("budgetForm");

        budgetFormPanel.add(budgetForm);

        if(Utils.currentUserHasRoleApproved("publisher") && GoldOAPortal.currentUser.getPublisher()!=null) {
            publisher.setText(GoldOAPortal.currentUser.getPublisher().getName());
            budgetForm.add(new FormFieldSet("Publisher (*)", publisher));
        } else {
            for (Affiliation affiliation : GoldOAPortal.currentUser.getAffiliations()) {
                Organization organization = affiliation.getOrganization();
                if (organization != null)
                    institutions.addItem(organization.getName(), organization.getId());
            }
            institutions.setAlternateSize(AlternateSize.XXLARGE);
            budgetForm.add(new FormFieldSet("Organization (*)", institutions));
        }

        Label budgetLabel = new Label("Euros");
        budgetLabel.addStyleName("inlineBlock");

        budgetRequestedTextBox.setAlternateSize(AlternateSize.XLARGE);
        budgetRequestedTextBox.addStyleName("inlineBlock");
        budgetForm.add(new FormFieldSet("Budget Requested (*)", budgetRequestedTextBox, budgetLabel));

        startDateDateBox.setValue(new Date());
        startDateDateBox.setFormat("yyyy/mm/dd");
        budgetForm.add(new FormFieldSet("Start Date (*)", startDateDateBox));

        Date endDate = new Date();
        CalendarUtil.addMonthsToDate(endDate, 6);
        endDateDateBox.setValue(endDate);
        endDateDateBox.setFormat("yyyy/mm/dd");
        budgetForm.add(new FormFieldSet("End Date (*)", endDateDateBox));

        bankInfoLabel.setText("Bank Information");
        bankInfoLabel.addStyleName("strong");
        budgetForm.add(new FormFieldSet(null, bankInfoLabel));

        nameOfBank.setAlternateSize(AlternateSize.XLARGE);
        budgetForm.add(new FormFieldSet("Name of bank (*)", nameOfBank));

        addressOfBank.setAlternateSize(AlternateSize.XLARGE);
        budgetForm.add(new FormFieldSet("Address of bank (*)", addressOfBank));

        accountHolder.setAlternateSize(AlternateSize.XLARGE);
        budgetForm.add(new FormFieldSet("Account holder (*)", accountHolder));

        accountNumber.setAlternateSize(AlternateSize.XLARGE);
        budgetForm.add(new FormFieldSet("Account number (IBAN format) (*)", accountNumber));

        bankCode.setAlternateSize(AlternateSize.XLARGE);
        budgetForm.add(new FormFieldSet("Bank code (BIC) / SWIFT code (*)", bankCode));

        submit.setType(ButtonType.PRIMARY);
        submit.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent clickEvent) {

                errorLabel.setVisible(false);
                informationAlert.setVisible(false);

                if(isComplete()) {

                    if(isPositiveFloat(budgetRequestedTextBox.getValue().trim())) {

                        BankAccount bankAccount = new BankAccount();
                        bankAccount.setAccountHolder(accountHolder.getValue().trim());
                        bankAccount.setBankAddress(addressOfBank.getValue().trim());
                        bankAccount.setBankCode(bankCode.getValue().trim());
                        bankAccount.setBankName(nameOfBank.getValue().trim());
                        bankAccount.setIban(accountNumber.getValue().trim());

                        final Budget budget = new Budget();
                        //budget.setUser(GoldOAPortal.currentUser);
                       // budget.setBankAccount(bankAccount);
                       // budget.setAmountRequested(Float.parseFloat(budgetRequestedTextBox.getValue().trim()));

                        if(Utils.currentUserHasRoleApproved("publisher") && GoldOAPortal.currentUser.getPublisher()!=null) {
                         //   budget.setPublisher(GoldOAPortal.currentUser.getPublisher());

                            dataService.submitBudgetRequest(budget, new AsyncCallback<Budget>() {

                                @Override
                                public void onFailure(Throwable caught) {

                                    budgetFormPanel.removeStyleName("loading-small");
                                    budgetFormPanel.remove(loadingWheel);

                                    errorLabel.setText("System error submitting budget request");
                                    errorLabel.setVisible(true);
                                }

                                @Override
                                public void onSuccess(Budget result) {

                                    budgetFormPanel.removeStyleName("loading-small");
                                    budgetFormPanel.remove(loadingWheel);

                                    informationAlert.setText("Budget request was submitted successfully");
                                    informationAlert.setVisible(true);

                                    budgetFormPanel.remove(budgetForm);
                                }
                            });


                        } else {
                            dataService.getOrganization(institutions.getSelectedValue(), new AsyncCallback<Organization>() {
                                @Override
                                public void onFailure(Throwable throwable) {
                                    Window.alert("Organization failure!");
                                }

                                @Override
                                public void onSuccess(Organization organization) {
                                  //  budget.getOrganizations().add(organization);
                                    budget.setStartdate(startDateDateBox.getValue());
                                    budget.setEnddate(endDateDateBox.getValue());
                                  //  budget.setDate(new Date());
                                 //   budget.setCurrency(Currency.EUR);

                                    budgetFormPanel.addStyleName("loading-small");
                                    budgetFormPanel.add(loadingWheel);

                                    dataService.submitBudgetRequest(budget, new AsyncCallback<Budget>() {

                                        @Override
                                        public void onFailure(Throwable caught) {

                                            budgetFormPanel.removeStyleName("loading-small");
                                            budgetFormPanel.remove(loadingWheel);

                                            errorLabel.setText("System error submitting budget request");
                                            errorLabel.setVisible(true);
                                        }

                                        @Override
                                        public void onSuccess(Budget result) {

                                            budgetFormPanel.removeStyleName("loading-small");
                                            budgetFormPanel.remove(loadingWheel);

                                            informationAlert.setText("Budget request was submitted successfully");
                                            informationAlert.setVisible(true);

                                            budgetFormPanel.remove(budgetForm);
                                        }
                                    });
                                }
                            });
                        }




                    } else {
                        errorLabel.setText("Budget must be a number greater than 0.");
                        errorLabel.setVisible(true);
                    }
                } else {
                    errorLabel.setText("All asterisk (*) fields are required.");
                    errorLabel.setVisible(true);
                }
            }
        });
        budgetForm.add(new FormFieldSet(null, submit));

        newBudgetRequestPanel.add(titleLabel);
        newBudgetRequestPanel.add(informationLabel);
        newBudgetRequestPanel.add(informationAlert);
        newBudgetRequestPanel.add(errorLabel);
        newBudgetRequestPanel.add(budgetFormPanel);
    }

    @Override
    public Widget asWidget() {
        return newBudgetRequestPanel;
    }

    @Override
    public void clear() {

        errorLabel.setVisible(false);
        informationAlert.setVisible(false);

        budgetRequestedTextBox.setValue("");
        institutions.clear();

        budgetForm.reset();
    }

    @Override
    public void reload() {

        MyWidgetHelper.hideSidebar();

        SidebarPanel helpPanel = new SidebarPanel("Help");
        MyWidgetHelper.loadHelp(helpPanel, token.split("\\.")[0]);

        for(Affiliation affiliation : GoldOAPortal.currentUser.getAffiliations()) {
            Organization organization = affiliation.getOrganization();
            if(organization!=null)
                institutions.addItem(organization.getName(), organization.getId());
        }

        startDateDateBox.setValue(new Date());
        Date endDate = new Date();
        CalendarUtil.addMonthsToDate(endDate, 6);
        endDateDateBox.setValue(endDate);
    }

    @Override
    public void setToken(String token) {
        this.token = token;
    }

    @Override
    public void afterAdditionToRootPanel() {

    }

    private boolean isComplete() {

        if(!budgetRequestedTextBox.getValue().trim().equals("")
                && !nameOfBank.getValue().trim().equals("") && !addressOfBank.getValue().trim().equals("")
                && !accountHolder.getValue().trim().equals("") && !accountNumber.getValue().trim().equals("")
                && !bankCode.getValue().trim().equals(""))
            return true;

        return false;
    }

    private boolean isPositiveFloat(String number) {

        try {
            Float numberValue = Float.parseFloat(number);
            if(numberValue > 0)
                return true;
        } catch(NumberFormatException nfe) {
            return false;
        }

        return false;
    }
}
