/*
 * Copyright (C) 2016 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.radio;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.radio.RadioManager.ProgramInfo;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.car.widget.DayNightStyle;
import androidx.car.widget.PagedListView;
import androidx.fragment.app.Fragment;

import com.android.car.broadcastradio.support.Program;
import com.android.car.radio.storage.RadioStorage;

import java.util.List;

/**
 * A fragment that is responsible for displaying a list of the user's saved radio stations.
 */
public class RadioPresetsFragment extends Fragment implements
        FragmentWithFade,
        RadioAnimationManager.OnExitCompleteListener,
        RadioController.ProgramInfoChangeListener,
        RadioStorage.PresetsChangeListener {
    private static final String TAG = "PresetsFragment";
    private static final int ANIM_DURATION_MS = 200;

    private View mCurrentRadioCard;

    private RadioStorage mRadioStorage;
    private RadioController mRadioController;
    private RadioAnimationManager mAnimManager;

    private PresetListExitListener mPresetListExitListener;

    private PagedListView mPresetsList;
    private final PresetsAdapter mPresetsAdapter = new PresetsAdapter();

    /**
     * An interface that will be notified when the user has indicated that they would like to
     * exit the preset list.
     */
    public interface PresetListExitListener {
        /**
         * Method to be called when the preset list should be closed and the main radio display
         * should be shown.
         */
        void OnPresetListExit();
    }

    /**
     * Sets the {@link RadioController} that is responsible for updating the UI of this fragment
     * with the information of the current radio station.
     */
    private void setRadioController(RadioController radioController) {
        mRadioController = radioController;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.radio_presets_list, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        Context context = getContext();

        mPresetsAdapter.setOnPresetItemClickListener(mRadioController::tune);
        mPresetsAdapter.setOnPresetItemFavoriteListener(this::handlePresetItemFavoriteChanged);

        mCurrentRadioCard = view.findViewById(R.id.current_radio_station_card);

        mAnimManager = new RadioAnimationManager(getContext(), view);
        mAnimManager.playEnterAnimation();

        // Clicking on the current radio station card will close the activity and return to the
        // main radio screen.
        mCurrentRadioCard.setOnClickListener(
                v -> mAnimManager.playExitAnimation(RadioPresetsFragment.this /* listener */));

        mPresetsList = view.findViewById(R.id.presets_list);
        mPresetsList.setDayNightStyle(DayNightStyle.ALWAYS_LIGHT);
        mPresetsList.setAdapter(mPresetsAdapter);
        mPresetsList.getRecyclerView().addOnScrollListener(new PresetListScrollListener(
                context, view, mCurrentRadioCard, mPresetsList));

        mRadioStorage = RadioStorage.getInstance(context);
        mRadioStorage.addPresetsChangeListener(this);
        setPresetsOnList(mRadioStorage.getPresets());
    }

    @Override
    public void fadeOutContent() {
        ObjectAnimator containerAlphaAnimator =
                ObjectAnimator.ofFloat(mCurrentRadioCard, View.ALPHA, 0f);
        containerAlphaAnimator.setDuration(ANIM_DURATION_MS);
        containerAlphaAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {}

            @Override
            public void onAnimationEnd(Animator animation) {
                mCurrentRadioCard.setVisibility(View.GONE);
            }

            @Override
            public void onAnimationCancel(Animator animation) {}

            @Override
            public void onAnimationRepeat(Animator animation) {}
        });

        ObjectAnimator presetListAlphaAnimator =
                ObjectAnimator.ofFloat(mPresetsList, View.ALPHA, 0f);
        presetListAlphaAnimator.setDuration(ANIM_DURATION_MS);
        presetListAlphaAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {}

            @Override
            public void onAnimationEnd(Animator animation) {
                mPresetsList.setVisibility(View.GONE);
            }

            @Override
            public void onAnimationCancel(Animator animation) {}

            @Override
            public void onAnimationRepeat(Animator animation) {}
        });

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(containerAlphaAnimator, presetListAlphaAnimator);
        animatorSet.start();
    }

    @Override
    public void fadeInContent() {
        // Only the current radio card needs to be faded in as that is the only part
        // of the fragment that will peek over the manual tuner.
        ObjectAnimator containerAlphaAnimator =
                ObjectAnimator.ofFloat(mCurrentRadioCard, View.ALPHA, 1f);
        containerAlphaAnimator.setDuration(ANIM_DURATION_MS);
        containerAlphaAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                mCurrentRadioCard.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animator animation) {}

            @Override
            public void onAnimationCancel(Animator animation) {}

            @Override
            public void onAnimationRepeat(Animator animation) {}
        });

        ObjectAnimator presetListAlphaAnimator =
                ObjectAnimator.ofFloat(mPresetsList, View.ALPHA, 1f);
        presetListAlphaAnimator.setDuration(ANIM_DURATION_MS);
        presetListAlphaAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                mPresetsList.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animator animation) {}

            @Override
            public void onAnimationCancel(Animator animation) {}

            @Override
            public void onAnimationRepeat(Animator animation) {}
        });

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(containerAlphaAnimator, presetListAlphaAnimator);
        animatorSet.start();
    }

    @Override
    public void onStart() {
        super.onStart();
        mRadioController.initialize(getView());
        mRadioController.setShouldColorStatusBar(true);
        mRadioController.addProgramInfoChangeListener(this);

        // TODO(b/73950974): use callback only
        ProgramInfo info = mRadioController.getCurrentProgramInfo();
        if (info != null) {
            mPresetsAdapter.setActiveProgram(Program.fromProgramInfo(info));
        }
    }

    @Override
    public void onDestroy() {
        mRadioStorage.removePresetsChangeListener(this);
        mRadioController.removeProgramInfoChangeListener(this);
        mPresetListExitListener = null;
        super.onDestroy();
    }

    @Override
    public void onExitAnimationComplete() {
        if (mPresetListExitListener != null) {
            mPresetListExitListener.OnPresetListExit();
        }
    }


    @Override
    public void onProgramInfoChanged(@NonNull ProgramInfo info) {
        mPresetsAdapter.setPresets(mRadioStorage.getPresets());
        mPresetsAdapter.setActiveProgram(Program.fromProgramInfo(info));
    }

    @Override
    public void onPresetsRefreshed() {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onPresetsRefreshed()");
        }
    }

    private void handlePresetItemFavoriteChanged(Program program, boolean saveAsFavorite) {
        if (saveAsFavorite) {
            mRadioStorage.storePreset(program);
        } else {
            mRadioStorage.removePreset(program.getSelector());
        }
    }

    /**
     * Sets the given list of presets into the PagedListView {@link #mPresetsList}.
     */
    private void setPresetsOnList(List<Program> presets) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "setPresetsOnList(). # of presets: " + presets.size());
        }

        mPresetsAdapter.setPresets(presets);
    }

    /**
     * Returns a new instance of the {@link RadioPresetsFragment}.
     *
     * @param radioController The {@link RadioController} that is responsible for updating the UI
     *                        of the returned fragment.
     */
    public static RadioPresetsFragment newInstance(RadioController radioController,
            PresetListExitListener existListener) {
        RadioPresetsFragment fragment = new RadioPresetsFragment();
        fragment.setRadioController(radioController);
        fragment.mPresetListExitListener = existListener;

        return fragment;
    }
}
