/*
 * 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.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.HashSet;
import java.util.List;
import java.util.Set;

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

    private CarUiMultiSelectListPreference mPreference;
    private Set<String> mNewValues;
    private ToolbarController mToolbar;

    /**
     * Returns a new instance of {@link MultiSelectListPreferenceFragment} for the {@link
     * CarUiMultiSelectListPreference} with the given {@code key}.
     */
    @NonNull
    static MultiSelectListPreferenceFragment newInstance(String key) {
        MultiSelectListPreferenceFragment fragment = new MultiSelectListPreferenceFragment();
        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 recyclerView = CarUiUtils.requireViewByRefId(view, R.id.list);
        mToolbar = CarUi.getToolbar(requireActivity());

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

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

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

        mPreference = getPreference();

        recyclerView.setClipToPadding(false);
        mToolbar.setTitle(mPreference.getTitle());
        mToolbar.setState(Toolbar.State.SUBPAGE);

        mNewValues = new HashSet<>(mPreference.getValues());
        CharSequence[] entries = mPreference.getEntries();
        CharSequence[] entryValues = mPreference.getEntryValues();

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

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

        List<CarUiListItem> listItems = new ArrayList<>();
        boolean[] selectedItems = mPreference.getSelectedItems();

        for (int i = 0; i < entries.length; i++) {
            String entry = entries[i].toString();
            String entryValue = entryValues[i].toString();
            CarUiContentListItem item = new CarUiContentListItem(
                    CarUiContentListItem.Action.CHECK_BOX);
            item.setTitle(entry);
            item.setChecked(selectedItems[i]);
            item.setOnCheckedChangeListener((listItem, isChecked) -> {
                if (isChecked) {
                    mNewValues.add(entryValue);
                } else {
                    mNewValues.remove(entryValue);
                }
            });

            listItems.add(item);
        }

        CarUiListItemAdapter adapter = new CarUiListItemAdapter(listItems);
        recyclerView.setAdapter(adapter);
    }

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

    @Override
    public void onStop() {
        super.onStop();
        updatePreference();
    }

    private void updatePreference() {
        if (mPreference.callChangeListener(mNewValues)) {
            mPreference.setValues(mNewValues);
        }
    }

    private CarUiMultiSelectListPreference getPreference() {
        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(
                    "MultiSelectListPreference key not found in Fragment arguments");
        }

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

        Preference preference = fragment.findPreference(key);

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

        return (CarUiMultiSelectListPreference) 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);
    }
}
