/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.car.ui.preference;

import static com.android.car.ui.preference.PreferenceDialogFragment.ARG_KEY;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.preference.DialogPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;

import com.android.car.ui.R;
import com.android.car.ui.baselayout.Insets;
import com.android.car.ui.baselayout.InsetsChangedListener;
import com.android.car.ui.core.CarUi;
import com.android.car.ui.recyclerview.CarUiContentListItem;
import com.android.car.ui.recyclerview.CarUiListItem;
import com.android.car.ui.recyclerview.CarUiListItemAdapter;
import com.android.car.ui.recyclerview.CarUiRecyclerView;
import com.android.car.ui.toolbar.Toolbar;
import com.android.car.ui.toolbar.ToolbarController;
import com.android.car.ui.utils.CarUiUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * A fragment that provides a layout with a list of options associated with a {@link
 * ListPreference}.
 */
public class ListPreferenceFragment extends Fragment implements InsetsChangedListener {

    private ToolbarController mToolbar;
    private ListPreference mPreference;
    private CarUiContentListItem mSelectedItem;
    private int mSelectedIndex = -1;
    private final Toolbar.OnBackListener mOnBackListener = () -> {
        if (mSelectedIndex >= 0 && mPreference != null) {
            String entryValue = mPreference.getEntryValues()[mSelectedIndex].toString();

            if (mPreference.callChangeListener(entryValue)) {
                mPreference.setValue(entryValue);
            }
        }

        return false;
    };

    /**
     * Returns a new instance of {@link ListPreferenceFragment} for the {@link ListPreference} with
     * the given {@code key}.
     */
    @NonNull
    static ListPreferenceFragment newInstance(String key) {
        ListPreferenceFragment fragment = new ListPreferenceFragment();
        Bundle b = new Bundle(/* capacity= */ 1);
        b.putString(ARG_KEY, key);
        fragment.setArguments(b);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(
            @NonNull LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        if (CarUi.getToolbar(getActivity()) == null) {
            return inflater.inflate(R.layout.car_ui_list_preference_with_toolbar, container, false);
        } else {
            return inflater.inflate(R.layout.car_ui_list_preference, container, false);
        }
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        final CarUiRecyclerView carUiRecyclerView = CarUiUtils.requireViewByRefId(view, R.id.list);
        mToolbar = CarUi.getToolbar(getActivity());

        // TODO(b/150230923) remove the code for the old toolbar height change when apps are ready
        if (mToolbar == null) {
            Toolbar toolbarView = CarUiUtils.requireViewByRefId(view, R.id.toolbar);
            mToolbar = toolbarView;

            carUiRecyclerView.setPadding(0, toolbarView.getHeight(), 0, 0);
            toolbarView.registerToolbarHeightChangeListener(newHeight -> {
                if (carUiRecyclerView.getPaddingTop() == newHeight) {
                    return;
                }

                int oldHeight = carUiRecyclerView.getPaddingTop();
                carUiRecyclerView.setPadding(0, newHeight, 0, 0);
                carUiRecyclerView.scrollBy(0, oldHeight - newHeight);
            });
        }

        carUiRecyclerView.setClipToPadding(false);
        mPreference = getListPreference();
        mToolbar.setTitle(mPreference.getTitle());
        mToolbar.setState(Toolbar.State.SUBPAGE);

        CharSequence[] entries = mPreference.getEntries();
        CharSequence[] entryValues = mPreference.getEntryValues();

        if (entries == null || entryValues == null) {
            throw new IllegalStateException(
                    "ListPreference requires an entries array and an entryValues array.");
        }

        if (entries.length != entryValues.length) {
            throw new IllegalStateException(
                    "ListPreference entries array length does not match entryValues array length.");
        }

        mSelectedIndex = mPreference.findIndexOfValue(mPreference.getValue());
        List<CarUiListItem> listItems = new ArrayList<>();
        CarUiListItemAdapter adapter = new CarUiListItemAdapter(listItems);

        for (int i = 0; i < entries.length; i++) {
            String entry = entries[i].toString();
            CarUiContentListItem item = new CarUiContentListItem(
                    CarUiContentListItem.Action.RADIO_BUTTON);
            item.setTitle(entry);

            if (i == mSelectedIndex) {
                item.setChecked(true);
                mSelectedItem = item;
            }

            item.setOnCheckedChangeListener((listItem, isChecked) -> {
                if (mSelectedItem != null) {
                    mSelectedItem.setChecked(false);
                    adapter.notifyItemChanged(listItems.indexOf(mSelectedItem));
                }
                mSelectedItem = listItem;
                mSelectedIndex = listItems.indexOf(mSelectedItem);
            });

            listItems.add(item);
        }

        carUiRecyclerView.setAdapter(adapter);
    }

    @Override
    public void onStart() {
        super.onStart();
        mToolbar.registerOnBackListener(mOnBackListener);
        Insets insets = CarUi.getInsets(getActivity());
        if (insets != null) {
            onCarUiInsetsChanged(insets);
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        mToolbar.unregisterOnBackListener(mOnBackListener);
    }

    private ListPreference getListPreference() {
        if (getArguments() == null) {
            throw new IllegalStateException("Preference arguments cannot be null");
        }

        String key = getArguments().getString(ARG_KEY);
        DialogPreference.TargetFragment fragment =
                (DialogPreference.TargetFragment) getTargetFragment();

        if (key == null) {
            throw new IllegalStateException(
                    "ListPreference key not found in Fragment arguments");
        }

        if (fragment == null) {
            throw new IllegalStateException(
                    "Target fragment must be registered before displaying ListPreference "
                            + "screen.");
        }

        Preference preference = fragment.findPreference(key);

        if (!(preference instanceof ListPreference)) {
            throw new IllegalStateException(
                    "Cannot use ListPreferenceFragment with a preference that is not of type "
                            + "ListPreference");
        }

        return (ListPreference) preference;
    }

    @Override
    public void onCarUiInsetsChanged(@NonNull Insets insets) {
        View view = requireView();
        CarUiUtils.requireViewByRefId(view, R.id.list)
                .setPadding(0, insets.getTop(), 0, insets.getBottom());
        view.setPadding(insets.getLeft(), 0, insets.getRight(), 0);
    }
}
