// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.payments.ui;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
import android.support.v7.widget.Toolbar.OnMenuItemClickListener;
import android.text.InputFilter;
import android.text.Spanned;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;

import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.autofill.PhoneNumberUtil;
import org.chromium.chrome.browser.customtabs.CustomTabActivity;
import org.chromium.chrome.browser.payments.ui.PaymentRequestUI.PaymentRequestObserverForTest;
import org.chromium.chrome.browser.preferences.autofill.CreditCardNumberFormattingTextWatcher;
import org.chromium.chrome.browser.widget.AlwaysDismissedDialog;
import org.chromium.chrome.browser.widget.FadingEdgeScrollView;
import org.chromium.chrome.browser.widget.FadingShadow;
import org.chromium.chrome.browser.widget.FadingShadowView;
import org.chromium.ui.UiUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.annotation.Nullable;

/**
 * The PaymentRequest editor dialog. Can be used for editing contact information, shipping address,
 * billing address, and credit cards.
 */
public class EditorView extends AlwaysDismissedDialog implements OnClickListener,
                                                                 DialogInterface.OnShowListener,
                                                                 DialogInterface.OnDismissListener {
    /** The indicator for input fields that are required. */
    public static final String REQUIRED_FIELD_INDICATOR = "*";

    /** Help page that the user is directed to when asking for help. */
    private static final String HELP_URL = "https://support.google.com/chrome/answer/142893?hl=en";

    /** Duration of the animation to show the UI to full height. */
    private static final int DIALOG_ENTER_ANIMATION_MS = 300;

    /** Duration of the animation to hide the UI. */
    private static final int DIALOG_EXIT_ANIMATION_MS = 195;

    private final Context mContext;
    private final PaymentRequestObserverForTest mObserverForTest;
    private final Handler mHandler;
    private final TextView.OnEditorActionListener mEditorActionListener;
    private final int mHalfRowMargin;
    private final List<EditorFieldView> mFieldViews;
    private final List<EditText> mEditableTextFields;
    private final List<Spinner> mDropdownFields;
    private final InputFilter mCardNumberInputFilter;
    private final TextWatcher mCardNumberFormatter;

    @Nullable private TextWatcher mPhoneFormatter;
    private View mLayout;
    private EditorModel mEditorModel;
    private Button mDoneButton;
    private ViewGroup mDataView;
    private View mFooter;
    @Nullable private TextView mCardInput;
    @Nullable private TextView mPhoneInput;

    private Animator mDialogInOutAnimator;

    /**
     * Builds the editor view.
     *
     * @param activity        The activity on top of which the UI should be displayed.
     * @param observerForTest Optional event observer for testing.
     */
    public EditorView(Activity activity, PaymentRequestObserverForTest observerForTest) {
        super(activity, R.style.FullscreenWhite);
        // Sets transparent background for animating content view.
        getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        mContext = activity;
        mObserverForTest = observerForTest;
        mHandler = new Handler();
        mEditorActionListener = new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    mDoneButton.performClick();
                    return true;
                } else if (actionId == EditorInfo.IME_ACTION_NEXT) {
                    View next = v.focusSearch(View.FOCUS_FORWARD);
                    if (next != null) {
                        next.requestFocus();
                        return true;
                    }
                }
                return false;
            }
        };

        mHalfRowMargin = activity.getResources().getDimensionPixelSize(
                R.dimen.payments_section_large_spacing);
        mFieldViews = new ArrayList<>();
        mEditableTextFields = new ArrayList<>();
        mDropdownFields = new ArrayList<>();

        final Pattern cardNumberPattern = Pattern.compile("^[\\d- ]*$");
        mCardNumberInputFilter = new InputFilter() {
            @Override
            public CharSequence filter(
                    CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                // Accept deletions.
                if (start == end) return null;

                // Accept digits, "-", and spaces.
                if (cardNumberPattern.matcher(source.subSequence(start, end)).matches()) {
                    return null;
                }

                // Reject everything else.
                return "";
            }
        };

        mCardNumberFormatter = new CreditCardNumberFormattingTextWatcher();
        mPhoneFormatter = new PhoneNumberUtil.FormatTextWatcher();
    }

    /** Prevents screenshots of this editor. */
    public void disableScreenshots() {
        WindowManager.LayoutParams attributes = getWindow().getAttributes();
        attributes.flags |= WindowManager.LayoutParams.FLAG_SECURE;
        getWindow().setAttributes(attributes);
    }

    /** Launches the Autofill help page on top of the current Context. */
    public static void launchAutofillHelpPage(Context context) {
        CustomTabActivity.showInfoPage(context, HELP_URL);
    }

    /**
     * Prepares the toolbar for use.
     *
     * Many of the things that would ideally be set as attributes don't work and need to be set
     * programmatically.  This is likely due to how we compile the support libraries.
     */
    private void prepareToolbar() {
        EditorDialogToolbar toolbar = (EditorDialogToolbar) mLayout.findViewById(R.id.action_bar);
        toolbar.setTitle(mEditorModel.getTitle());
        toolbar.setTitleTextColor(Color.WHITE);
        toolbar.setShowDeleteMenuItem(false);

        // Show the help article when the user asks.
        toolbar.setOnMenuItemClickListener(new OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                launchAutofillHelpPage(mContext);
                return true;
            }
        });

        // Cancel editing when the user hits the back arrow.
        toolbar.setNavigationContentDescription(R.string.cancel);
        toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismissDialog();
            }
        });

        // Make it appear that the toolbar is floating by adding a shadow.
        FadingShadowView shadow = (FadingShadowView) mLayout.findViewById(R.id.shadow);
        shadow.init(ApiCompatibilityUtils.getColor(mContext.getResources(),
                R.color.toolbar_shadow_color), FadingShadow.POSITION_TOP);

        // The top shadow is handled by the toolbar, so hide the one used in the field editor.
        FadingEdgeScrollView scrollView =
                (FadingEdgeScrollView) mLayout.findViewById(R.id.scroll_view);
        scrollView.setEdgeVisibility(
                FadingEdgeScrollView.DRAW_NO_EDGE, FadingEdgeScrollView.DRAW_FADING_EDGE);
    }

    /**
     * Checks if all of the fields in the form are valid and updates the displayed errors. If there
     * are any invalid fields, makes sure that one of them is focused. Called when user taps [SAVE].
     *
     * @return Whether all fields contain valid information.
     */
    private boolean validateForm() {
        final List<EditorFieldView> invalidViews = getViewsWithInvalidInformation(true);

        // Iterate over all the fields to update what errors are displayed, which is necessary to
        // to clear existing errors on any newly valid fields.
        for (int i = 0; i < mFieldViews.size(); i++) {
            EditorFieldView fieldView = mFieldViews.get(i);
            fieldView.updateDisplayedError(invalidViews.contains(fieldView));
        }

        if (!invalidViews.isEmpty()) {
            // Make sure that focus is on an invalid field.
            EditorFieldView focusedField = getEditorTextField(getCurrentFocus());
            if (invalidViews.contains(focusedField)) {
                // The focused field is invalid, but it may be scrolled off screen. Scroll to it.
                focusedField.scrollToAndFocus();
            } else {
                // Some fields are invalid, but none of the are focused. Scroll to the first invalid
                // field and focus it.
                invalidViews.get(0).scrollToAndFocus();
            }
        }

        return invalidViews.isEmpty();
    }

    /** @return The validatable item for the given view. */
    private EditorFieldView getEditorTextField(View v) {
        if (v instanceof TextView && v.getParent() != null
                && v.getParent() instanceof EditorFieldView) {
            return (EditorFieldView) v.getParent();
        } else if (v instanceof Spinner && v.getTag() != null) {
            return (EditorFieldView) v.getTag();
        } else {
            return null;
        }
    }

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.payments_edit_done_button) {
            if (validateForm()) {
                mEditorModel.done();
                mEditorModel = null;
                dismissDialog();
                return;
            }

            if (mObserverForTest != null) mObserverForTest.onPaymentRequestEditorValidationError();
        } else if (view.getId() == R.id.payments_edit_cancel_button) {
            dismissDialog();
        }
    }

    private void dismissDialog() {
        if (mDialogInOutAnimator != null || !isShowing()) return;

        Animator dropDown =
                ObjectAnimator.ofFloat(mLayout, View.TRANSLATION_Y, 0f, mLayout.getHeight());
        Animator fadeOut = ObjectAnimator.ofFloat(mLayout, View.ALPHA, mLayout.getAlpha(), 0f);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(dropDown, fadeOut);

        mDialogInOutAnimator = animatorSet;
        mDialogInOutAnimator.setDuration(DIALOG_EXIT_ANIMATION_MS);
        mDialogInOutAnimator.setInterpolator(new FastOutLinearInInterpolator());
        mDialogInOutAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mDialogInOutAnimator = null;
                dismiss();
            }
        });

        mDialogInOutAnimator.start();
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        if (mEditorModel != null) mEditorModel.cancel();
        removeTextChangedListenersAndInputFilters();
    }

    private void prepareButtons() {
        mDoneButton = (Button) mLayout.findViewById(R.id.button_primary);
        mDoneButton.setId(R.id.payments_edit_done_button);
        mDoneButton.setOnClickListener(this);

        Button cancelButton = (Button) mLayout.findViewById(R.id.button_secondary);
        cancelButton.setId(R.id.payments_edit_cancel_button);
        cancelButton.setOnClickListener(this);
    }

    /**
     * Create the visual representation of the EditorModel.
     *
     * This would be more optimal as a RelativeLayout, but because it's dynamically generated, it's
     * much more human-parsable with inefficient LinearLayouts for half-width controls sharing rows.
     */
    private void prepareEditor() {
        // Ensure the layout is empty.
        removeTextChangedListenersAndInputFilters();
        mDataView = (ViewGroup) mLayout.findViewById(R.id.contents);
        mDataView.removeAllViews();
        mFieldViews.clear();
        mEditableTextFields.clear();
        mDropdownFields.clear();

        // Add Views for each of the {@link EditorFields}.
        for (int i = 0; i < mEditorModel.getFields().size(); i++) {
            EditorFieldModel fieldModel = mEditorModel.getFields().get(i);
            EditorFieldModel nextFieldModel = null;

            boolean isLastField = i == mEditorModel.getFields().size() - 1;
            boolean useFullLine = fieldModel.isFullLine();
            if (!isLastField && !useFullLine) {
                // If the next field isn't full, stretch it out.
                nextFieldModel = mEditorModel.getFields().get(i + 1);
                if (nextFieldModel.isFullLine()) useFullLine = true;
            }

            if (useFullLine || isLastField) {
                addFieldViewToEditor(mDataView, fieldModel);
            } else {
                // Create a LinearLayout to put it and the next view side by side.
                LinearLayout rowLayout = new LinearLayout(mContext);
                mDataView.addView(rowLayout);

                View firstView = addFieldViewToEditor(rowLayout, fieldModel);
                View lastView = addFieldViewToEditor(rowLayout, nextFieldModel);

                LinearLayout.LayoutParams firstParams =
                        (LinearLayout.LayoutParams) firstView.getLayoutParams();
                LinearLayout.LayoutParams lastParams =
                        (LinearLayout.LayoutParams) lastView.getLayoutParams();

                firstParams.width = 0;
                firstParams.weight = 1;
                ApiCompatibilityUtils.setMarginEnd(firstParams, mHalfRowMargin);
                lastParams.width = 0;
                lastParams.weight = 1;
                i = i + 1;
            }
        }

        // Add the footer.
        mDataView.addView(mFooter);
    }

    private void removeTextChangedListenersAndInputFilters() {
        if (mCardInput != null) {
            mCardInput.removeTextChangedListener(mCardNumberFormatter);
            mCardInput.setFilters(new InputFilter[0]); // Null is not allowed.
            mCardInput = null;
        }

        if (mPhoneInput != null) {
            mPhoneInput.removeTextChangedListener(mPhoneFormatter);
            mPhoneInput = null;
        }
    }

    private View addFieldViewToEditor(ViewGroup parent, final EditorFieldModel fieldModel) {
        View childView = null;

        if (fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_ICONS) {
            childView = new EditorIconsField(mContext, parent, fieldModel).getLayout();
        } else if (fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_LABEL) {
            childView = new EditorLabelField(mContext, parent, fieldModel).getLayout();
        } else if (fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_DROPDOWN) {
            Runnable prepareEditorRunnable = new Runnable() {
                @Override
                public void run() {
                    // The fields may have changed.
                    prepareEditor();
                    if (mObserverForTest != null) mObserverForTest.onPaymentRequestReadyToEdit();
                }
            };
            EditorDropdownField dropdownView =
                    new EditorDropdownField(mContext, parent, fieldModel, prepareEditorRunnable);
            mFieldViews.add(dropdownView);
            mDropdownFields.add(dropdownView.getDropdown());

            childView = dropdownView.getLayout();
        } else if (fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_CHECKBOX) {
            final CheckBox checkbox = new CheckBox(mLayout.getContext());
            checkbox.setId(R.id.payments_edit_checkbox);
            checkbox.setText(fieldModel.getLabel());
            checkbox.setChecked(fieldModel.isChecked());
            checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    fieldModel.setIsChecked(isChecked);
                    if (mObserverForTest != null) mObserverForTest.onPaymentRequestReadyToEdit();
                }
            });

            childView = checkbox;
        } else {
            InputFilter filter = null;
            TextWatcher formatter = null;
            if (fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_CREDIT_CARD) {
                filter = mCardNumberInputFilter;
                formatter = mCardNumberFormatter;
            } else if (fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_PHONE) {
                formatter = mPhoneFormatter;
            }

            EditorTextField inputLayout = new EditorTextField(mContext, fieldModel,
                    mEditorActionListener, filter, formatter, mObserverForTest);
            mFieldViews.add(inputLayout);

            EditText input = inputLayout.getEditText();
            mEditableTextFields.add(input);

            if (fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_CREDIT_CARD) {
                assert mCardInput == null;
                mCardInput = input;
            } else if (fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_PHONE) {
                assert mPhoneInput == null;
                mPhoneInput = input;
            }

            childView = inputLayout;
        }

        parent.addView(childView);
        return childView;
    }

    /**
     * Displays the editor user interface for the given model.
     *
     * @param editorModel The description of the editor user interface to display.
     */
    public void show(final EditorModel editorModel) {
        setOnShowListener(this);
        setOnDismissListener(this);
        mEditorModel = editorModel;

        mLayout = LayoutInflater.from(mContext).inflate(R.layout.payment_request_editor, null);
        setContentView(mLayout);

        mFooter = LayoutInflater.from(mContext).inflate(
                R.layout.payment_request_editor_footer, null, false);

        prepareToolbar();
        prepareEditor();
        prepareButtons();
        show();
    }

    /** Rereads the values in the model to update the UI. */
    public void update() {
        for (int i = 0; i < mFieldViews.size(); i++) {
            mFieldViews.get(i).update();
        }
    }

    @Override
    public void onShow(DialogInterface dialog) {
        assert mDialogInOutAnimator == null;

        // Hide keyboard and disable EditText views for animation efficiency.
        if (getCurrentFocus() != null) UiUtils.hideKeyboard(getCurrentFocus());
        for (int i = 0; i < mEditableTextFields.size(); i++) {
            mEditableTextFields.get(i).setEnabled(false);
        }

        mLayout.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        mLayout.buildLayer();
        Animator popUp =
                ObjectAnimator.ofFloat(mLayout, View.TRANSLATION_Y, mLayout.getHeight(), 0f);
        Animator fadeIn = ObjectAnimator.ofFloat(mLayout, View.ALPHA, 0f, 1f);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(popUp, fadeIn);

        mDialogInOutAnimator = animatorSet;
        mDialogInOutAnimator.setDuration(DIALOG_ENTER_ANIMATION_MS);
        mDialogInOutAnimator.setInterpolator(new LinearOutSlowInInterpolator());
        mDialogInOutAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mLayout.setLayerType(View.LAYER_TYPE_NONE, null);
                for (int i = 0; i < mEditableTextFields.size(); i++) {
                    mEditableTextFields.get(i).setEnabled(true);
                }
                // Note that keyboard will not show for dropdown field since it's not necessary.
                if (getCurrentFocus() != null) UiUtils.showKeyboard(getCurrentFocus());
                mDialogInOutAnimator = null;
                initFocus();
            }
        });

        mDialogInOutAnimator.start();
    }

    private void initFocus() {
        // Immediately focus the first invalid field to make it faster to edit.
        final List<EditorFieldView> invalidViews = getViewsWithInvalidInformation(false);
        if (!invalidViews.isEmpty()) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    invalidViews.get(0).scrollToAndFocus();
                    if (mObserverForTest != null) mObserverForTest.onPaymentRequestReadyToEdit();
                }
            });
        } else {
            // The first field will be focused, we are ready to edit.
            if (mObserverForTest != null) mObserverForTest.onPaymentRequestReadyToEdit();
        }
    }

    private List<EditorFieldView> getViewsWithInvalidInformation(boolean findAll) {
        List<EditorFieldView> invalidViews = new ArrayList<>();
        for (int i = 0; i < mFieldViews.size(); i++) {
            EditorFieldView fieldView = mFieldViews.get(i);
            if (!fieldView.isValid()) {
                invalidViews.add(fieldView);
                if (!findAll) break;
            }
        }
        return invalidViews;
    }

    /** @return All editable text fields in the editor. Used only for tests. */
    @VisibleForTesting
    public List<EditText> getEditableTextFieldsForTest() {
        return mEditableTextFields;
    }

    /** @return All dropdown fields in the editor. Used only for tests. */
    @VisibleForTesting
    public List<Spinner> getDropdownFieldsForTest() {
        return mDropdownFields;
    }
}
