// Copyright 2018 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.autofill_assistant.user_data;

import android.app.Activity;
import android.text.TextUtils;
import android.view.View;

import org.chromium.chrome.browser.ChromeVersionInfo;
import org.chromium.chrome.browser.autofill.PersonalDataManager;
import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantAdditionalSectionContainer;
import org.chromium.chrome.browser.payments.AddressEditor;
import org.chromium.chrome.browser.payments.AutofillPaymentApp;
import org.chromium.chrome.browser.payments.AutofillPaymentInstrument;
import org.chromium.chrome.browser.payments.BasicCardUtils;
import org.chromium.chrome.browser.payments.CardEditor;
import org.chromium.chrome.browser.payments.ContactEditor;
import org.chromium.chrome.browser.payments.PaymentInstrument;
import org.chromium.chrome.browser.widget.prefeditor.EditorDialog;
import org.chromium.content_public.browser.WebContents;
import org.chromium.payments.mojom.PaymentMethodData;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * This class is responsible for pushing updates to the Autofill Assistant UI for requesting user
 * data. These updates are pulled from the {@link AssistantCollectUserDataModel} when a notification
 * of an update is received.
 */
class AssistantCollectUserDataBinder
        implements PropertyModelChangeProcessor.ViewBinder<AssistantCollectUserDataModel,
                AssistantCollectUserDataBinder.ViewHolder, PropertyKey> {
    /**
     * Helper class that compares instances of {@link PersonalDataManager.AutofillProfile} by
     * completeness in regards to the current state of the given {@link
     * AssistantCollectUserDataModel}.
     */
    class CompletenessComparator implements Comparator<PersonalDataManager.AutofillProfile> {
        final boolean mRequestName;
        final boolean mRequestShipping;
        final boolean mRequestEmail;
        final boolean mRequestPhone;
        CompletenessComparator(AssistantCollectUserDataModel model) {
            mRequestName = model.get(AssistantCollectUserDataModel.REQUEST_NAME);
            mRequestShipping = model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS);
            mRequestEmail = model.get(AssistantCollectUserDataModel.REQUEST_EMAIL);
            mRequestPhone = model.get(AssistantCollectUserDataModel.REQUEST_PHONE);
        }

        @Override
        public int compare(
                PersonalDataManager.AutofillProfile a, PersonalDataManager.AutofillProfile b) {
            int result = countCompleteFields(a) - countCompleteFields(b);
            // Fallback, compare by name alphabetically.
            if (result == 0) {
                return a.getFullName().compareTo(b.getFullName());
            }
            return result;
        }

        private int countCompleteFields(PersonalDataManager.AutofillProfile profile) {
            int completeFields = 0;
            if (mRequestName && !TextUtils.isEmpty((profile.getFullName()))) {
                completeFields++;
            }
            if (mRequestShipping && !TextUtils.isEmpty(profile.getStreetAddress())) {
                completeFields++;
            }
            if (mRequestEmail && !TextUtils.isEmpty(profile.getEmailAddress())) {
                completeFields++;
            }
            if (mRequestPhone && !TextUtils.isEmpty(profile.getPhoneNumber())) {
                completeFields++;
            }
            return completeFields;
        }
    }

    /**
     * A wrapper class that holds the different views of the CollectUserData request.
     */
    static class ViewHolder {
        private final View mRootView;
        private final AssistantVerticalExpanderAccordion mPaymentRequestExpanderAccordion;
        private final int mSectionToSectionPadding;
        private final AssistantLoginSection mLoginSection;
        private final AssistantContactDetailsSection mContactDetailsSection;
        private final AssistantDateSection mDateRangeStartSection;
        private final AssistantDateSection mDateRangeEndSection;
        private final AssistantPaymentMethodSection mPaymentMethodSection;
        private final AssistantShippingAddressSection mShippingAddressSection;
        private final AssistantTermsSection mTermsSection;
        private final AssistantTermsSection mTermsAsCheckboxSection;
        private final AssistantAdditionalSectionContainer mPrependedSections;
        private final AssistantAdditionalSectionContainer mAppendedSections;
        private final Object mDividerTag;
        private final Activity mActivity;
        private PersonalDataManager.PersonalDataManagerObserver mPersonalDataManagerObserver;

        public ViewHolder(View rootView, AssistantVerticalExpanderAccordion accordion,
                int sectionPadding, AssistantLoginSection loginSection,
                AssistantContactDetailsSection contactDetailsSection,
                AssistantDateSection dateRangeStartSection,
                AssistantDateSection dateRangeEndSection,
                AssistantPaymentMethodSection paymentMethodSection,
                AssistantShippingAddressSection shippingAddressSection,
                AssistantTermsSection termsSection, AssistantTermsSection termsAsCheckboxSection,
                AssistantAdditionalSectionContainer prependedSections,
                AssistantAdditionalSectionContainer appendedSections, Object dividerTag,
                Activity activity) {
            mRootView = rootView;
            mPaymentRequestExpanderAccordion = accordion;
            mSectionToSectionPadding = sectionPadding;
            mLoginSection = loginSection;
            mContactDetailsSection = contactDetailsSection;
            mDateRangeStartSection = dateRangeStartSection;
            mDateRangeEndSection = dateRangeEndSection;
            mPaymentMethodSection = paymentMethodSection;
            mShippingAddressSection = shippingAddressSection;
            mTermsSection = termsSection;
            mTermsAsCheckboxSection = termsAsCheckboxSection;
            mPrependedSections = prependedSections;
            mAppendedSections = appendedSections;
            mDividerTag = dividerTag;
            mActivity = activity;
        }

        /**
         * Explicitly clean up.
         */
        public void destroy() {
            stopListenToPersonalDataManager();
        }

        private void startListenToPersonalDataManager(
                PersonalDataManager.PersonalDataManagerObserver observer) {
            if (mPersonalDataManagerObserver != null) {
                return;
            }
            mPersonalDataManagerObserver = observer;
            PersonalDataManager.getInstance().registerDataObserver(mPersonalDataManagerObserver);
        }

        private void stopListenToPersonalDataManager() {
            if (mPersonalDataManagerObserver == null) {
                return;
            }
            PersonalDataManager.getInstance().unregisterDataObserver(mPersonalDataManagerObserver);
            mPersonalDataManagerObserver = null;
        }
    }

    @Override
    public void bind(
            AssistantCollectUserDataModel model, ViewHolder view, PropertyKey propertyKey) {
        boolean handled = updateEditors(model, propertyKey, view);
        handled = updateRootVisibility(model, propertyKey, view) || handled;
        handled = updateSectionVisibility(model, propertyKey, view) || handled;
        handled = updateSectionTitles(model, propertyKey, view) || handled;
        handled = updateSectionContents(model, propertyKey, view) || handled;
        handled = updateSectionSelectedItem(model, propertyKey, view) || handled;
        /* Update section paddings *after* updating section visibility. */
        handled = updateSectionPaddings(model, propertyKey, view) || handled;

        if (propertyKey == AssistantCollectUserDataModel.DELEGATE) {
            AssistantCollectUserDataDelegate collectUserDataDelegate =
                    model.get(AssistantCollectUserDataModel.DELEGATE);

            AssistantTermsSection.Delegate termsDelegate =
                    collectUserDataDelegate == null ? null : new AssistantTermsSection.Delegate() {
                        @Override
                        public void onStateChanged(@AssistantTermsAndConditionsState int state) {
                            collectUserDataDelegate.onTermsAndConditionsChanged(state);
                        }

                        @Override
                        public void onLinkClicked(int link) {
                            collectUserDataDelegate.onTermsAndConditionsLinkClicked(link);
                        }
                    };
            AssistantDateSection.Delegate dateStartDelegate = collectUserDataDelegate == null
                    ? null
                    : (year, month, day, hour, minute, second) -> {
                AssistantDateTime newStartValue =
                        new AssistantDateTime(year, month, day, hour, minute, second);
                if (newStartValue.getTimeInUtcMillis()
                        > view.mDateRangeEndSection.getCurrentValue().getTimeInUtcMillis()) {
                    view.mDateRangeEndSection.setCurrentValue(newStartValue);
                }
                collectUserDataDelegate.onDateTimeRangeStartChanged(
                        year, month, day, hour, minute, second);
            };
            AssistantDateSection.Delegate dateEndDelegate = collectUserDataDelegate == null
                    ? null
                    : (year, month, day, hour, minute, second) -> {
                AssistantDateTime newEndValue =
                        new AssistantDateTime(year, month, day, hour, minute, second);
                if (newEndValue.getTimeInUtcMillis()
                        < view.mDateRangeStartSection.getCurrentValue().getTimeInUtcMillis()) {
                    view.mDateRangeStartSection.setCurrentValue(newEndValue);
                }
                collectUserDataDelegate.onDateTimeRangeEndChanged(
                        year, month, day, hour, minute, second);
            };
            view.mTermsSection.setDelegate(termsDelegate);
            view.mTermsAsCheckboxSection.setDelegate(termsDelegate);
            view.mContactDetailsSection.setListener(collectUserDataDelegate != null
                            ? collectUserDataDelegate::onContactInfoChanged
                            : null);
            view.mPaymentMethodSection.setListener(collectUserDataDelegate != null
                            ? collectUserDataDelegate::onPaymentMethodChanged
                            : null);
            view.mShippingAddressSection.setListener(collectUserDataDelegate != null
                            ? collectUserDataDelegate::onShippingAddressChanged
                            : null);
            view.mLoginSection.setListener(collectUserDataDelegate != null
                            ? collectUserDataDelegate::onLoginChoiceChanged
                            : null);
            view.mDateRangeStartSection.setDelegate(dateStartDelegate);
            view.mDateRangeEndSection.setDelegate(dateEndDelegate);
            view.mPrependedSections.setDelegate(collectUserDataDelegate != null
                            ? collectUserDataDelegate::onKeyValueChanged
                            : null);
            view.mAppendedSections.setDelegate(collectUserDataDelegate != null
                            ? collectUserDataDelegate::onKeyValueChanged
                            : null);
        } else if (propertyKey == AssistantCollectUserDataModel.SUPPORTED_BASIC_CARD_NETWORKS) {
            updateAvailablePaymentMethods(model);
        } else if (propertyKey == AssistantCollectUserDataModel.SUPPORTED_PAYMENT_METHODS) {
            updateAvailableAutofillPaymentMethods(model);
        } else {
            assert handled : "Unhandled property detected in AssistantCollectUserDataBinder!";
        }
    }

    private boolean shouldShowContactDetails(AssistantCollectUserDataModel model) {
        return model.get(AssistantCollectUserDataModel.REQUEST_NAME)
                || model.get(AssistantCollectUserDataModel.REQUEST_PHONE)
                || model.get(AssistantCollectUserDataModel.REQUEST_EMAIL);
    }

    private boolean updateSectionTitles(
            AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
        if (propertyKey == AssistantCollectUserDataModel.LOGIN_SECTION_TITLE) {
            view.mLoginSection.setTitle(
                    model.get(AssistantCollectUserDataModel.LOGIN_SECTION_TITLE));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_START_LABEL) {
            view.mDateRangeStartSection.setTitle(
                    model.get(AssistantCollectUserDataModel.DATE_RANGE_START_LABEL));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_END_LABEL) {
            view.mDateRangeEndSection.setTitle(
                    model.get(AssistantCollectUserDataModel.DATE_RANGE_END_LABEL));
            return true;
        }
        return false;
    }

    /**
     * Updates the available items for each PR section.
     * @return whether the property key was handled.
     */
    private boolean updateSectionContents(
            AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
        if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS) {
            List<AutofillPaymentInstrument> availablePaymentMethods =
                    model.get(AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS);
            if (availablePaymentMethods == null) availablePaymentMethods = Collections.emptyList();
            view.mPaymentMethodSection.onAvailablePaymentMethodsChanged(availablePaymentMethods);
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_PROFILES
                || propertyKey == AssistantCollectUserDataModel.DEFAULT_EMAIL) {
            List<PersonalDataManager.AutofillProfile> autofillProfiles =
                    model.get(AssistantCollectUserDataModel.AVAILABLE_PROFILES);
            if (autofillProfiles == null) {
                autofillProfiles = Collections.emptyList();
            }
            if (shouldShowContactDetails(model)) {
                view.mContactDetailsSection.onProfilesChanged(autofillProfiles,
                        model.get(AssistantCollectUserDataModel.REQUEST_EMAIL),
                        model.get(AssistantCollectUserDataModel.REQUEST_NAME),
                        model.get(AssistantCollectUserDataModel.REQUEST_PHONE),
                        model.get(AssistantCollectUserDataModel.DEFAULT_EMAIL));
            }
            if (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)) {
                view.mPaymentMethodSection.onProfilesChanged(autofillProfiles);
            }
            if (model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS)) {
                view.mShippingAddressSection.onProfilesChanged(autofillProfiles);
            }
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.REQUIRE_BILLING_POSTAL_CODE
                || propertyKey == AssistantCollectUserDataModel.BILLING_POSTAL_CODE_MISSING_TEXT) {
            view.mPaymentMethodSection.setRequiresBillingPostalCode(
                    model.get(AssistantCollectUserDataModel.REQUIRE_BILLING_POSTAL_CODE));
            view.mPaymentMethodSection.setBillingPostalCodeMissingText(
                    model.get(AssistantCollectUserDataModel.BILLING_POSTAL_CODE_MISSING_TEXT));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_LOGINS) {
            if (model.get(AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE)) {
                view.mLoginSection.onLoginsChanged(
                        model.get(AssistantCollectUserDataModel.AVAILABLE_LOGINS));
            }
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_START) {
            view.mDateRangeStartSection.setDateChoiceOptions(
                    model.get(AssistantCollectUserDataModel.DATE_RANGE_START));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_END) {
            view.mDateRangeEndSection.setDateChoiceOptions(
                    model.get(AssistantCollectUserDataModel.DATE_RANGE_END));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.PREPENDED_SECTIONS) {
            view.mPrependedSections.setSections(
                    model.get(AssistantCollectUserDataModel.PREPENDED_SECTIONS));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.APPENDED_SECTIONS) {
            view.mAppendedSections.setSections(
                    model.get(AssistantCollectUserDataModel.APPENDED_SECTIONS));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.ACCEPT_TERMS_AND_CONDITIONS_TEXT) {
            view.mTermsSection.setAcceptTermsAndConditionsText(
                    model.get(AssistantCollectUserDataModel.ACCEPT_TERMS_AND_CONDITIONS_TEXT));
            view.mTermsAsCheckboxSection.setAcceptTermsAndConditionsText(
                    model.get(AssistantCollectUserDataModel.ACCEPT_TERMS_AND_CONDITIONS_TEXT));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.TERMS_REQUIRE_REVIEW_TEXT) {
            view.mTermsSection.setTermsRequireReviewText(
                    model.get(AssistantCollectUserDataModel.TERMS_REQUIRE_REVIEW_TEXT));
            view.mTermsAsCheckboxSection.setTermsRequireReviewText(
                    model.get(AssistantCollectUserDataModel.TERMS_REQUIRE_REVIEW_TEXT));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.THIRDPARTY_PRIVACY_NOTICE_TEXT) {
            view.mTermsSection.setThirdPartyPrivacyNoticeText(
                    model.get(AssistantCollectUserDataModel.THIRDPARTY_PRIVACY_NOTICE_TEXT));
            view.mTermsAsCheckboxSection.setThirdPartyPrivacyNoticeText(
                    model.get(AssistantCollectUserDataModel.THIRDPARTY_PRIVACY_NOTICE_TEXT));
            return true;
        }

        return false;
    }

    /**
     * Updates visibility of PR sections.
     * @return whether the property key was handled.
     */
    private boolean updateSectionVisibility(
            AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
        if ((propertyKey == AssistantCollectUserDataModel.REQUEST_NAME)
                || (propertyKey == AssistantCollectUserDataModel.REQUEST_EMAIL)
                || (propertyKey == AssistantCollectUserDataModel.REQUEST_PHONE)) {
            view.mContactDetailsSection.setVisible(shouldShowContactDetails(model));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS) {
            view.mShippingAddressSection.setVisible(
                    model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.REQUEST_PAYMENT) {
            view.mPaymentMethodSection.setVisible(
                    (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.SHOW_TERMS_AS_CHECKBOX) {
            if (model.get(AssistantCollectUserDataModel.SHOW_TERMS_AS_CHECKBOX)) {
                view.mTermsSection.getView().setVisibility(View.GONE);
                view.mTermsAsCheckboxSection.getView().setVisibility(View.VISIBLE);
            } else {
                view.mTermsSection.getView().setVisibility(View.VISIBLE);
                view.mTermsAsCheckboxSection.getView().setVisibility(View.GONE);
            }
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE) {
            view.mLoginSection.setVisible(
                    model.get(AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE));
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.REQUEST_DATE_RANGE) {
            boolean requestDateRange = model.get(AssistantCollectUserDataModel.REQUEST_DATE_RANGE);
            view.mDateRangeStartSection.setVisible(requestDateRange);
            view.mDateRangeEndSection.setVisible(requestDateRange);
            return true;
        }
        return false;
    }

    /**
     * Updates visibility of the root widget.
     * @return whether the property key was handled.
     */
    private boolean updateRootVisibility(
            AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
        if (propertyKey != AssistantCollectUserDataModel.VISIBLE) {
            return false;
        }
        int visibility =
                model.get(AssistantCollectUserDataModel.VISIBLE) ? View.VISIBLE : View.GONE;
        if (view.mRootView.getVisibility() != visibility) {
            if (visibility == View.VISIBLE) {
                // Update available profiles and credit cards before PR is made visible.
                updateAvailableProfiles(model, view);
                updateAvailablePaymentMethods(model);

                view.startListenToPersonalDataManager(() -> {
                    AssistantCollectUserDataBinder.this.updateAvailableProfiles(model, view);
                    AssistantCollectUserDataBinder.this.updateAvailablePaymentMethods(model);
                });
            } else {
                view.stopListenToPersonalDataManager();
            }
            view.mRootView.setVisibility(visibility);
        }
        return true;
    }

    /**
     * Updates the currently selected item in each PR section.
     * @return whether the property key was handled.
     */
    private boolean updateSectionSelectedItem(
            AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
        if (propertyKey == AssistantCollectUserDataModel.SHIPPING_ADDRESS) {
            view.mShippingAddressSection.addOrUpdateItem(
                    model.get(AssistantCollectUserDataModel.SHIPPING_ADDRESS), true);
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.PAYMENT_METHOD) {
            view.mPaymentMethodSection.addOrUpdateItem(
                    model.get(AssistantCollectUserDataModel.PAYMENT_METHOD), true);
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.CONTACT_DETAILS) {
            view.mContactDetailsSection.addOrUpdateItem(
                    model.get(AssistantCollectUserDataModel.CONTACT_DETAILS), true);
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.TERMS_STATUS) {
            int termsStatus = model.get(AssistantCollectUserDataModel.TERMS_STATUS);
            view.mTermsSection.setTermsStatus(termsStatus);
            view.mTermsAsCheckboxSection.setTermsStatus(termsStatus);
            return true;
        } else if (propertyKey == AssistantCollectUserDataModel.SELECTED_LOGIN) {
            view.mLoginSection.addOrUpdateItem(
                    model.get(AssistantCollectUserDataModel.SELECTED_LOGIN), true);
            return true;
        }
        return false;
    }

    // TODO(crbug.com/806868): Move this logic to native.
    private void updateAvailableProfiles(AssistantCollectUserDataModel model, ViewHolder view) {
        List<PersonalDataManager.AutofillProfile> autofillProfiles =
                PersonalDataManager.getInstance().getProfilesToSuggest(
                        /* includeNameInLabel= */ false);

        // Suggest complete profiles first.
        Collections.sort(autofillProfiles, new CompletenessComparator(model));
        model.set(AssistantCollectUserDataModel.AVAILABLE_PROFILES, autofillProfiles);
    }

    /**
     * Updates the paddings between sections and section dividers.
     * @return whether the property key was handled.
     */
    private boolean updateSectionPaddings(
            AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
        if ((propertyKey != AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS)
                && (propertyKey != AssistantCollectUserDataModel.REQUEST_NAME)
                && (propertyKey != AssistantCollectUserDataModel.REQUEST_EMAIL)
                && (propertyKey != AssistantCollectUserDataModel.REQUEST_PHONE)
                && (propertyKey != AssistantCollectUserDataModel.REQUEST_PAYMENT)
                && (propertyKey != AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE)
                && (propertyKey != AssistantCollectUserDataModel.REQUEST_DATE_RANGE)
                && (propertyKey != AssistantCollectUserDataModel.EXPANDED_SECTION)
                && (propertyKey != AssistantCollectUserDataModel.PREPENDED_SECTIONS)
                && (propertyKey != AssistantCollectUserDataModel.APPENDED_SECTIONS)) {
            return false;
        }

        // Update section paddings such that the first and last section are flush to the top/bottom,
        // and all other sections have the same amount of padding in-between them.

        if (!model.get(AssistantCollectUserDataModel.PREPENDED_SECTIONS).isEmpty()) {
            view.mPrependedSections.setPaddings(
                    0, view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mLoginSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mContactDetailsSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mDateRangeStartSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mDateRangeEndSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mPaymentMethodSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mShippingAddressSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mAppendedSections.setPaddings(view.mSectionToSectionPadding,
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
        } else if (model.get(AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE)) {
            view.mLoginSection.setPaddings(0, view.mSectionToSectionPadding);
            view.mContactDetailsSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mDateRangeStartSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mDateRangeEndSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mPaymentMethodSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mShippingAddressSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mAppendedSections.setPaddings(view.mSectionToSectionPadding,
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
        } else if (shouldShowContactDetails(model)) {
            view.mContactDetailsSection.setPaddings(0, view.mSectionToSectionPadding);
            view.mDateRangeStartSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mDateRangeEndSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mPaymentMethodSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mShippingAddressSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mAppendedSections.setPaddings(view.mSectionToSectionPadding,
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
        } else if (model.get(AssistantCollectUserDataModel.REQUEST_DATE_RANGE)) {
            view.mDateRangeStartSection.setPaddings(0, view.mSectionToSectionPadding);
            view.mDateRangeEndSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mPaymentMethodSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mShippingAddressSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mAppendedSections.setPaddings(view.mSectionToSectionPadding,
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
        } else if (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)) {
            view.mPaymentMethodSection.setPaddings(0, view.mSectionToSectionPadding);
            view.mShippingAddressSection.setPaddings(
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
            view.mAppendedSections.setPaddings(view.mSectionToSectionPadding,
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
        } else if (model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS)) {
            view.mShippingAddressSection.setPaddings(0, view.mSectionToSectionPadding);
            view.mAppendedSections.setPaddings(view.mSectionToSectionPadding,
                    view.mSectionToSectionPadding, view.mSectionToSectionPadding);
        } else if (!model.get(AssistantCollectUserDataModel.APPENDED_SECTIONS).isEmpty()) {
            view.mAppendedSections.setPaddings(
                    0, view.mSectionToSectionPadding, view.mSectionToSectionPadding);
        }
        view.mTermsSection.setPaddings(view.mSectionToSectionPadding, 0);
        view.mTermsAsCheckboxSection.setPaddings(view.mSectionToSectionPadding, 0);

        // Hide dividers for currently invisible sections and after the expanded section, if any.
        boolean prevSectionIsExpandedOrInvisible = false;
        for (int i = 0; i < view.mPaymentRequestExpanderAccordion.getChildCount(); i++) {
            View child = view.mPaymentRequestExpanderAccordion.getChildAt(i);
            if (child instanceof AssistantVerticalExpander) {
                prevSectionIsExpandedOrInvisible = ((AssistantVerticalExpander) child).isExpanded()
                        || child.getVisibility() != View.VISIBLE;
            } else if (child.getTag() == view.mDividerTag) {
                child.setVisibility(prevSectionIsExpandedOrInvisible ? View.GONE : View.VISIBLE);
            } else {
                prevSectionIsExpandedOrInvisible = false;
            }
        }
        return true;
    }

    /**
     * Updates/recreates section editors.
     * @return whether the property key was handled.
     */
    private boolean updateEditors(
            AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
        if ((propertyKey != AssistantCollectUserDataModel.WEB_CONTENTS)
                && (propertyKey != AssistantCollectUserDataModel.REQUEST_NAME)
                && (propertyKey != AssistantCollectUserDataModel.REQUEST_EMAIL)
                && (propertyKey != AssistantCollectUserDataModel.REQUEST_PHONE)
                && (propertyKey
                        != AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS)) {
            return false;
        }

        WebContents webContents = model.get(AssistantCollectUserDataModel.WEB_CONTENTS);
        if (webContents == null) {
            view.mContactDetailsSection.setEditor(null);
            view.mPaymentMethodSection.setEditor(null);
            view.mShippingAddressSection.setEditor(null);
            return true;
        }

        if (shouldShowContactDetails(model)) {
            ContactEditor contactEditor =
                    new ContactEditor(model.get(AssistantCollectUserDataModel.REQUEST_NAME),
                            model.get(AssistantCollectUserDataModel.REQUEST_PHONE),
                            model.get(AssistantCollectUserDataModel.REQUEST_EMAIL),
                            !webContents.isIncognito());
            contactEditor.setEditorDialog(new EditorDialog(view.mActivity, null,
                    /*deleteRunnable =*/null));
            view.mContactDetailsSection.setEditor(contactEditor);
        }

        AddressEditor addressEditor = new AddressEditor(AddressEditor.Purpose.PAYMENT_REQUEST,
                /* saveToDisk= */ !webContents.isIncognito());
        addressEditor.setEditorDialog(new EditorDialog(view.mActivity, null,
                /*deleteRunnable =*/null));

        CardEditor cardEditor = new CardEditor(webContents, addressEditor,
                /* includeOrgLabel= */ false, /* observerForTest= */ null);
        Map<String, PaymentMethodData> paymentMethods =
                model.get(AssistantCollectUserDataModel.SUPPORTED_PAYMENT_METHODS);
        if (paymentMethods != null) {
            for (Map.Entry<String, PaymentMethodData> entry : paymentMethods.entrySet()) {
                cardEditor.addAcceptedPaymentMethodIfRecognized(entry.getValue());
            }
        }

        EditorDialog cardEditorDialog = new EditorDialog(view.mActivity, null,
                /*deleteRunnable =*/null);
        if (ChromeVersionInfo.isBetaBuild() || ChromeVersionInfo.isStableBuild()) {
            cardEditorDialog.disableScreenshots();
        }
        cardEditor.setEditorDialog(cardEditorDialog);

        view.mShippingAddressSection.setEditor(addressEditor);
        view.mPaymentMethodSection.setEditor(cardEditor);
        return true;
    }

    /**
     * Updates the map of supported payment methods (identifier -> methodData), filtered by
     * |SUPPORTED_BASIC_CARD_NETWORKS|.
     */
    // TODO(crbug.com/806868): Move the logic to retrieve and filter payment methods to native.
    private void updateAvailablePaymentMethods(AssistantCollectUserDataModel model) {
        // Only enable 'basic-card' payment method.
        PaymentMethodData methodData = new PaymentMethodData();
        methodData.supportedMethod = BasicCardUtils.BASIC_CARD_METHOD_NAME;

        // Apply basic-card filter if specified
        List<String> supportedBasicCardNetworks =
                model.get(AssistantCollectUserDataModel.SUPPORTED_BASIC_CARD_NETWORKS);
        if (supportedBasicCardNetworks != null && supportedBasicCardNetworks.size() > 0) {
            ArrayList<Integer> filteredNetworks = new ArrayList<>();
            Map<String, Integer> networks = BasicCardUtils.getNetworkIdentifiers();
            for (int i = 0; i < supportedBasicCardNetworks.size(); i++) {
                assert networks.containsKey(supportedBasicCardNetworks.get(i));
                filteredNetworks.add(networks.get(supportedBasicCardNetworks.get(i)));
            }

            methodData.supportedNetworks = new int[filteredNetworks.size()];
            for (int i = 0; i < filteredNetworks.size(); i++) {
                methodData.supportedNetworks[i] = filteredNetworks.get(i);
            }
        }

        Map<String, PaymentMethodData> supportedPaymentMethods = new HashMap<>();
        supportedPaymentMethods.put(BasicCardUtils.BASIC_CARD_METHOD_NAME, methodData);
        model.set(AssistantCollectUserDataModel.SUPPORTED_PAYMENT_METHODS, supportedPaymentMethods);
    }

    /**
     * Updates the list of available autofill payment methods (i.e., the list of available payment
     * methods available to the user as items in the UI).
     */
    // TODO(crbug.com/806868): Move this logic to native.
    private void updateAvailableAutofillPaymentMethods(AssistantCollectUserDataModel model) {
        WebContents webContents = model.get(AssistantCollectUserDataModel.WEB_CONTENTS);

        AutofillPaymentApp autofillPaymentApp = new AutofillPaymentApp(webContents);
        Map<String, PaymentMethodData> supportedPaymentMethods =
                model.get(AssistantCollectUserDataModel.SUPPORTED_PAYMENT_METHODS);
        List<PaymentInstrument> paymentMethods = autofillPaymentApp.getInstruments(
                supportedPaymentMethods != null ? supportedPaymentMethods : Collections.emptyMap(),
                /*forceReturnServerCards=*/true);

        List<AutofillPaymentInstrument> availablePaymentMethods = new ArrayList<>();
        for (PaymentInstrument method : paymentMethods) {
            if (method instanceof AutofillPaymentInstrument) {
                availablePaymentMethods.add(((AutofillPaymentInstrument) method));
            }
        }
        model.set(AssistantCollectUserDataModel.AVAILABLE_AUTOFILL_PAYMENT_METHODS,
                availablePaymentMethods);
    }
}
