/*
 * 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.tv.dvr.ui;

import android.annotation.TargetApi;
import android.app.FragmentManager;
import android.content.Context;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import androidx.leanback.widget.GuidanceStylist.Guidance;
import androidx.leanback.widget.GuidedAction;
import androidx.leanback.widget.GuidedActionsStylist;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.data.SeriesRecording;
import java.util.ArrayList;
import java.util.List;

/** Fragment for DVR series recording settings. */
@TargetApi(Build.VERSION_CODES.N)
@SuppressWarnings("AndroidApiChecker") // TODO(b/32513850) remove when error prone is updated
public class DvrPrioritySettingsFragment extends TrackedGuidedStepFragment {
    /** Name of series recording id starting the fragment. Type: Long */
    public static final String COME_FROM_SERIES_RECORDING_ID = "series_recording_id";

    private static final int ONE_TIME_RECORDING_ID = 0;
    // button action's IDs are negative.
    private static final long ACTION_ID_SAVE = -100L;

    private final List<SeriesRecording> mSeriesRecordings = new ArrayList<>();

    private SeriesRecording mSelectedRecording;
    private SeriesRecording mComeFromSeriesRecording;
    private float mSelectedActionElevation;
    private int mActionColor;
    private int mSelectedActionColor;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mSeriesRecordings.clear();
        mSeriesRecordings.add(
                new SeriesRecording.Builder()
                        .setTitle(getString(R.string.dvr_priority_action_one_time_recording))
                        .setPriority(Long.MAX_VALUE)
                        .setId(ONE_TIME_RECORDING_ID)
                        .build());
        DvrDataManager dvrDataManager = TvSingletons.getSingletons(context).getDvrDataManager();
        long comeFromSeriesRecordingId = getArguments().getLong(COME_FROM_SERIES_RECORDING_ID, -1);
        for (SeriesRecording series : dvrDataManager.getSeriesRecordings()) {
            if (series.getState() == SeriesRecording.STATE_SERIES_NORMAL
                    || series.getId() == comeFromSeriesRecordingId) {
                mSeriesRecordings.add(series);
            }
        }
        mSeriesRecordings.sort(SeriesRecording.PRIORITY_COMPARATOR);
        mComeFromSeriesRecording = dvrDataManager.getSeriesRecording(comeFromSeriesRecordingId);
        mSelectedActionElevation = getResources().getDimension(R.dimen.card_elevation_normal);
        mActionColor = getResources().getColor(R.color.dvr_guided_step_action_text_color, null);
        mSelectedActionColor =
                getResources().getColor(R.color.dvr_guided_step_action_text_color_selected, null);
    }

    @Override
    public void onResume() {
        super.onResume();
        setSelectedActionPosition(
                mComeFromSeriesRecording == null
                        ? 1
                        : mSeriesRecordings.indexOf(mComeFromSeriesRecording));
    }

    @Override
    public Guidance onCreateGuidance(Bundle savedInstanceState) {
        String breadcrumb =
                mComeFromSeriesRecording == null ? null : mComeFromSeriesRecording.getTitle();
        return new Guidance(
                getString(R.string.dvr_priority_title),
                getString(R.string.dvr_priority_description),
                breadcrumb,
                null);
    }

    @Override
    public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
        int position = 0;
        for (SeriesRecording seriesRecording : mSeriesRecordings) {
            actions.add(
                    new GuidedAction.Builder(getActivity())
                            .id(position++)
                            .title(seriesRecording.getTitle())
                            .build());
        }
    }

    @Override
    public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
        actions.add(
                new GuidedAction.Builder(getActivity())
                        .id(ACTION_ID_SAVE)
                        .title(getString(R.string.dvr_priority_button_action_save))
                        .build());
        actions.add(
                new GuidedAction.Builder(getActivity())
                        .clickAction(GuidedAction.ACTION_ID_CANCEL)
                        .build());
    }

    @Override
    public void onTrackedGuidedActionClicked(GuidedAction action) {
        long actionId = action.getId();
        if (actionId == ACTION_ID_SAVE) {
            DvrManager dvrManager = TvSingletons.getSingletons(getContext()).getDvrManager();
            int size = mSeriesRecordings.size();
            for (int i = 1; i < size; ++i) {
                long priority = DvrScheduleManager.suggestSeriesPriority(size - i);
                SeriesRecording seriesRecording = mSeriesRecordings.get(i);
                if (seriesRecording.getPriority() != priority) {
                    dvrManager.updateSeriesRecording(
                            SeriesRecording.buildFrom(seriesRecording)
                                    .setPriority(priority)
                                    .build());
                }
            }
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.popBackStack();
        } else if (actionId == GuidedAction.ACTION_ID_CANCEL) {
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.popBackStack();
        } else if (mSelectedRecording == null) {
            mSelectedRecording = mSeriesRecordings.get((int) actionId);
            for (int i = 0; i < mSeriesRecordings.size(); ++i) {
                updateItem(i);
            }
        } else {
            mSelectedRecording = null;
            for (int i = 0; i < mSeriesRecordings.size(); ++i) {
                updateItem(i);
            }
        }
    }

    @Override
    public String getTrackerPrefix() {
        return "DvrPrioritySettingsFragment";
    }

    @Override
    public String getTrackerLabelForGuidedAction(GuidedAction action) {
        long actionId = action.getId();
        if (actionId == ACTION_ID_SAVE) {
            return "save";
        } else {
            return super.getTrackerLabelForGuidedAction(action);
        }
    }

    @Override
    public void onGuidedActionFocused(GuidedAction action) {
        super.onGuidedActionFocused(action);
        if (mSelectedRecording == null) {
            return;
        }
        if (action.getId() < 0) {
            mSelectedRecording = null;
            for (int i = 0; i < mSeriesRecordings.size(); ++i) {
                updateItem(i);
            }
            return;
        }
        int position = (int) action.getId();
        int previousPosition = mSeriesRecordings.indexOf(mSelectedRecording);
        mSeriesRecordings.remove(mSelectedRecording);
        mSeriesRecordings.add(position, mSelectedRecording);
        updateItem(previousPosition);
        updateItem(position);
        notifyActionChanged(previousPosition);
        notifyActionChanged(position);
    }

    @Override
    public GuidedActionsStylist onCreateButtonActionsStylist() {
        return new DvrGuidedActionsStylist(true);
    }

    @Override
    public GuidedActionsStylist onCreateActionsStylist() {
        return new DvrGuidedActionsStylist(false) {
            @Override
            public void onBindViewHolder(ViewHolder vh, GuidedAction action) {
                super.onBindViewHolder(vh, action);
                updateItem(vh.itemView, (int) action.getId());
            }

            @Override
            public int onProvideItemLayoutId() {
                return R.layout.priority_settings_action_item;
            }
        };
    }

    private void updateItem(int position) {
        View itemView = getActionItemView(position);
        if (itemView == null) {
            return;
        }
        updateItem(itemView, position);
    }

    private void updateItem(View itemView, int position) {
        GuidedAction action = getActions().get(position);
        action.setTitle(mSeriesRecordings.get(position).getTitle());
        boolean selected =
                mSelectedRecording != null
                        && mSeriesRecordings.indexOf(mSelectedRecording) == position;
        TextView titleView = (TextView) itemView.findViewById(R.id.guidedactions_item_title);
        ImageView imageView = (ImageView) itemView.findViewById(R.id.guidedactions_item_tail_image);
        if (position == 0) {
            // one-time recording
            itemView.setBackgroundResource(R.drawable.setup_selector_background);
            imageView.setVisibility(View.GONE);
            itemView.setFocusable(false);
            itemView.setElevation(0);
            // strings.xml <i> tag doesn't work.
            titleView.setTypeface(titleView.getTypeface(), Typeface.ITALIC);
        } else if (mSelectedRecording == null) {
            titleView.setTextColor(mActionColor);
            itemView.setBackgroundResource(R.drawable.setup_selector_background);
            imageView.setImageResource(R.drawable.ic_draggable_white);
            imageView.setVisibility(View.VISIBLE);
            itemView.setFocusable(true);
            itemView.setElevation(0);
            titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL);
        } else if (selected) {
            titleView.setTextColor(mSelectedActionColor);
            itemView.setBackgroundResource(R.drawable.priority_settings_action_item_selected);
            imageView.setImageResource(R.drawable.ic_dragging_grey);
            imageView.setVisibility(View.VISIBLE);
            itemView.setFocusable(true);
            itemView.setElevation(mSelectedActionElevation);
            titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL);
        } else {
            titleView.setTextColor(mActionColor);
            itemView.setBackgroundResource(R.drawable.setup_selector_background);
            imageView.setVisibility(View.INVISIBLE);
            itemView.setFocusable(true);
            itemView.setElevation(0);
            titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL);
        }
    }
}
