// Copyright 2022 The Chromium Authors
// 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.password_edit_dialog;

import android.content.Context;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;

import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;

import org.chromium.base.Callback;
import org.chromium.ui.text.EmptyTextWatcher;

import java.util.List;

/**
 * The view which represents a username label and input control and
 * a password label and input control.
 * The view has the functionality of editing both password and username.
 */
class PasswordEditDialogWithDetailsView extends PasswordEditDialogView {
    private AutoCompleteTextView mUsernameView;
    private TextInputLayout mUsernameInputLayout;
    private TextInputEditText mPasswordField;
    private TextInputLayout mPasswordInputLayout;
    private Callback<String> mUsernameChangedCallback;
    private Callback<String> mPasswordChangedCallback;
    private List<String> mUsernames;

    public PasswordEditDialogWithDetailsView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * Stores references to the dialog fields after dialog inflation.
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mUsernameView = findViewById(R.id.username_view);
        mUsernameInputLayout = findViewById(R.id.username_input_layout);
        mUsernameInputLayout.setEndIconOnClickListener(view -> mUsernameView.showDropDown());
        mUsernameView.addTextChangedListener(new EmptyTextWatcher() {
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                if (mUsernameChangedCallback == null) return;
                mUsernameChangedCallback.onResult(charSequence.toString());
            }

            @Override
            public void afterTextChanged(Editable editable) {
                setDropDownVisibility(editable.toString());
            }
        });

        mPasswordField = findViewById(R.id.password);
        mPasswordField.setInputType(InputType.TYPE_CLASS_TEXT
                | InputType.TYPE_TEXT_VARIATION_PASSWORD | InputType.TYPE_TEXT_FLAG_MULTI_LINE);
        mPasswordField.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                if (mPasswordChangedCallback == null) return;
                mPasswordChangedCallback.onResult(charSequence.toString());
            }

            @Override
            public void afterTextChanged(Editable editable) {}
        });
        mPasswordInputLayout = findViewById(R.id.password_text_input_layout);
    }

    @Override
    public void setPassword(String password) {
        if (mPasswordField.getText().toString().equals(password)) return;
        mPasswordField.setText(password);
    }

    @Override
    public void setPasswordChangedCallback(Callback<String> callback) {
        mPasswordChangedCallback = callback;
    }

    @Override
    public void setPasswordError(String error) {
        mPasswordInputLayout.setError(error);
    }

    /** Sets usernames list in the AutoCompleteTextView */
    public void setUsernames(List<String> usernames) {
        mUsernames = usernames;
        ArrayAdapter<String> usernamesAdapter = new NoFilterArrayAdapter<>(
                getContext(), R.layout.password_edit_dialog_dropdown_item, usernames);
        mUsernameView.setAdapter(usernamesAdapter);
        setDropDownVisibility(mUsernameView.getText().toString());
    }

    /**
     * Sets callback for handling username change.
     *
     * @param callback The callback to be called with new username typed into the
     *         AutoCompleteTextView
     */
    public void setUsernameChangedCallback(Callback<String> callback) {
        mUsernameChangedCallback = callback;
    }

    /** Sets username in the text input */
    public void setUsername(String username) {
        if (mUsernameView.getText().toString().equals(username)) return;
        mUsernameView.setText(username);
        setDropDownVisibility(username);
    }

    private void setDropDownVisibility(String currentUsername) {
        if (shouldShowDropDown(currentUsername)) {
            mUsernameInputLayout.setEndIconVisible(true);
        } else {
            // Hide the dropdown button and dismiss the dropdown (in case if it's open).
            mUsernameInputLayout.setEndIconVisible(false);
            mUsernameView.dismissDropDown();
        }
    }

    private boolean shouldShowDropDown(String currentUsername) {
        // Do not show the dropdown, when there are no usernames to list.
        if (mUsernames == null) return false;
        // Show the dropdown when there is more than one choice.
        if (mUsernames.size() > 1) return true;
        // Show the dropdown when there is one choice which is different from current username.
        return (mUsernames.size() == 1 && !mUsernames.get(0).equals(currentUsername));
    }
}
