// 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;

import android.view.View;
import android.view.ViewGroup;

import org.chromium.base.task.PostTask;
import org.chromium.chrome.autofill_assistant.R;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.autofill_assistant.header.AssistantHeaderModel;
import org.chromium.chrome.browser.autofill_assistant.metrics.DropOutReason;
import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayCoordinator;
import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayModel;
import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayState;
import org.chromium.chrome.browser.autofill_assistant.payment.AssistantPaymentRequestModel;
import org.chromium.chrome.browser.help.HelpAndFeedback;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.snackbar.Snackbar;
import org.chromium.chrome.browser.snackbar.SnackbarManager;
import org.chromium.content_public.browser.UiThreadTaskTraits;
import org.chromium.content_public.browser.WebContents;

/**
 * The main coordinator for the Autofill Assistant, responsible for instantiating all other
 * sub-components and shutting down the Autofill Assistant.
 */
class AssistantCoordinator {
    interface Delegate {
        /**
         * Completely stop the Autofill Assistant.
         */
        void stop();
    }

    private static final String FEEDBACK_CATEGORY_TAG =
            "com.android.chrome.USER_INITIATED_FEEDBACK_REPORT_AUTOFILL_ASSISTANT";
    private static final int SNACKBAR_DELAY_MS = 5_000;
    private static final int GRACEFUL_SHUTDOWN_DELAY_MS = 5_000;

    private final ChromeActivity mActivity;
    private final Delegate mDelegate;

    private final AssistantModel mModel;
    private final View mAssistantView;

    private final AssistantBottomBarCoordinator mBottomBarCoordinator;
    private final AssistantKeyboardCoordinator mKeyboardCoordinator;
    private final AssistantOverlayCoordinator mOverlayCoordinator;

    private boolean mIsShuttingDownGracefully;
    private boolean mIsDropOutRecorded;

    AssistantCoordinator(ChromeActivity activity, WebContents webContents, Delegate delegate) {
        mActivity = activity;
        mDelegate = delegate;
        mModel = new AssistantModel();

        // Inflate autofill_assistant_sheet layout and add it to the main coordinator view.
        ViewGroup coordinator = activity.findViewById(R.id.coordinator);
        mAssistantView = activity.getLayoutInflater()
                                 .inflate(R.layout.autofill_assistant_sheet, coordinator)
                                 .findViewById(R.id.autofill_assistant);

        // Instantiate child components.
        mBottomBarCoordinator =
                new AssistantBottomBarCoordinator(activity, webContents, mAssistantView, mModel);
        mKeyboardCoordinator = new AssistantKeyboardCoordinator(activity);
        mOverlayCoordinator =
                new AssistantOverlayCoordinator(activity, mAssistantView, mModel.getOverlayModel());

        // Listen when we should (dis)allow the soft keyboard or swiping the bottom sheet.
        mModel.addObserver((source, propertyKey) -> {
            if (AssistantModel.ALLOW_SOFT_KEYBOARD == propertyKey) {
                mKeyboardCoordinator.allowShowingSoftKeyboard(
                        mModel.get(AssistantModel.ALLOW_SOFT_KEYBOARD));
            } else if (AssistantModel.ALLOW_SWIPING_SHEET == propertyKey) {
                mBottomBarCoordinator.allowSwipingBottomSheet(
                        mModel.get(AssistantModel.ALLOW_SWIPING_SHEET));
            }
        });

        showAssistantView();
    }

    /**
     * Shut down the Autofill Assistant immediately, without showing a message.
     */
    public void shutdownImmediately(@DropOutReason int reason) {
        if (!mIsDropOutRecorded) {
            AutofillAssistantMetrics.recordDropOut(reason);
            mIsDropOutRecorded = true;
        }
        detachAssistantView();
        mOverlayCoordinator.destroy();
        mDelegate.stop();
    }

    /**
     * Schedule the shut down of the Autofill Assistant such that any status message currently
     * visible will still be shown for a few seconds before shutting down. Optionally replace
     * the status message with a generic error message iff {@code showGiveUpMessage} is true.
     */
    // TODO(crbug.com/806868): Move this method to native.
    public void gracefulShutdown(boolean showGiveUpMessage, @DropOutReason int reason) {
        mIsShuttingDownGracefully = true;

        // Make sure bottom bar is expanded.
        mBottomBarCoordinator.expand();

        // Hide everything except header.
        mModel.getOverlayModel().set(AssistantOverlayModel.STATE, AssistantOverlayState.hidden());
        mModel.getDetailsModel().clearDetails();
        mModel.getPaymentRequestModel().set(AssistantPaymentRequestModel.OPTIONS, null);
        mModel.getCarouselModel().clearChips();

        if (showGiveUpMessage) {
            mModel.getHeaderModel().set(AssistantHeaderModel.STATUS_MESSAGE,
                    mActivity.getString(R.string.autofill_assistant_give_up));
        }
        PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT,
                () -> shutdownImmediately(reason), GRACEFUL_SHUTDOWN_DELAY_MS);
    }

    /**
     * Shut down the Autofill Assistant and close the current Chrome tab.
     */
    public void close() {
        shutdownImmediately(DropOutReason.CUSTOM_TAB_CLOSED);
        mActivity.finish();
    }

    /**
     * Show the onboarding screen and call {@code onAccept} if the user agreed to proceed, shutdown
     * otherwise.
     */
    public void showOnboarding(Runnable onAccept) {
        // Hide header buttons.
        mModel.getHeaderModel().set(AssistantHeaderModel.FEEDBACK_VISIBLE, false);
        mModel.getHeaderModel().set(AssistantHeaderModel.CLOSE_VISIBLE, false);

        // Show overlay to prevent user from interacting with the page during onboarding.
        mModel.getOverlayModel().set(AssistantOverlayModel.STATE, AssistantOverlayState.full());

        // Disable swiping for the onboarding because it interferes with letting the user scroll
        // the onboarding contents.
        mBottomBarCoordinator.allowSwipingBottomSheet(false);
        AssistantOnboardingCoordinator.show(mActivity, mBottomBarCoordinator.getView())
                .then(accepted -> {
                    mBottomBarCoordinator.allowSwipingBottomSheet(true);
                    if (!accepted) {
                        shutdownImmediately(DropOutReason.DECLINED);
                        return;
                    }

                    // Show header buttons.
                    mModel.getHeaderModel().set(AssistantHeaderModel.FEEDBACK_VISIBLE, true);
                    mModel.getHeaderModel().set(AssistantHeaderModel.CLOSE_VISIBLE, true);

                    // Hide overlay.
                    mModel.getOverlayModel().set(
                            AssistantOverlayModel.STATE, AssistantOverlayState.hidden());

                    onAccept.run();
                });
    }

    /**
     * Get the model representing the current state of the UI.
     */

    public AssistantModel getModel() {
        return mModel;
    }

    // Getters to retrieve the sub coordinators.

    public AssistantBottomBarCoordinator getBottomBarCoordinator() {
        return mBottomBarCoordinator;
    }

    /**
     * Dismiss the assistant view and show a cancellable snackbar alerting the user that the
     * Autofill assistant is shutting down.
     */
    public void dismissAndShowSnackbar(String message, @DropOutReason int reason) {
        if (mIsShuttingDownGracefully) {
            shutdownImmediately(reason);
            return;
        }

        hideAssistantView();

        Snackbar snackBar =
                Snackbar.make(message,
                                new SnackbarManager.SnackbarController() {
                                    @Override
                                    public void onAction(Object actionData) {
                                        // Shutdown was cancelled.
                                        showAssistantView();
                                    }

                                    @Override
                                    public void onDismissNoAction(Object actionData) {
                                        shutdownImmediately(reason);
                                    }
                                },
                                Snackbar.TYPE_ACTION, Snackbar.UMA_AUTOFILL_ASSISTANT_STOP_UNDO)
                        .setAction(mActivity.getString(R.string.undo), /* actionData= */ null);
        snackBar.setSingleLine(false);
        snackBar.setDuration(SNACKBAR_DELAY_MS);
        mActivity.getSnackbarManager().showSnackbar(snackBar);
    }

    /**
     * Show the Chrome feedback form.
     */
    public void showFeedback(String debugContext) {
        HelpAndFeedback.getInstance(mActivity).showFeedback(mActivity, Profile.getLastUsedProfile(),
                mActivity.getActivityTab().getUrl(), FEEDBACK_CATEGORY_TAG,
                FeedbackContext.buildContextString(mActivity, debugContext, 4));
    }

    // Private methods.

    private void showAssistantView() {
        mAssistantView.setVisibility(View.VISIBLE);
        mKeyboardCoordinator.enableListenForKeyboardVisibility(true);

        mBottomBarCoordinator.expand();
        mBottomBarCoordinator.getView().announceForAccessibility(
                mActivity.getString(R.string.autofill_assistant_available_accessibility));
    }

    private void hideAssistantView() {
        mAssistantView.setVisibility(View.GONE);
        mKeyboardCoordinator.enableListenForKeyboardVisibility(false);
    }

    private void detachAssistantView() {
        mActivity.<ViewGroup>findViewById(R.id.coordinator).removeView(mAssistantView);
    }
}
