// 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.google.reviewit;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ScrollView;
import android.widget.TextView;

import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.reviewit.app.Change;
import com.google.reviewit.app.Preferences;
import com.google.reviewit.app.QueryHandler;
import com.google.reviewit.util.TaskObserver;
import com.google.reviewit.widget.ChangeEntry;

import java.util.Collections;
import java.util.List;

import static com.google.reviewit.util.LayoutUtil.matchAndFixedLayout;
import static com.google.reviewit.util.WidgetUtil.setGone;
import static com.google.reviewit.util.WidgetUtil.setInvisible;
import static com.google.reviewit.util.WidgetUtil.setVisible;

public class ReviewChangesFragment extends BaseFragment {
  private static final String TAG = ReviewChangesFragment.class.getName();

  @Override
  protected @LayoutRes int getLayout() {
    return R.layout.content_review_changes;
  }

  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    setTitle(getString(R.string.app_menu_review));

    setHasOptionsMenu(true);

    getApp().getPrefManager().setPreferences(
        new Preferences.Builder(getApp().getPrefManager().getPreferences())
            .setStartScreen(Preferences.StartScreen.REVIEW_SCREEN)
            .build());

    TaskObserver.enableProgressBar(getWindow());
    init();

    List<Change> loadedChanges = getApp().getQueryHandler().getLoadedChanges();
    if (loadedChanges.isEmpty()) {
      loadAndDisplay();
    } else {
      display(loadedChanges);
    }
  }

  private void init() {
    SwipeRefreshLayout swipeRefreshLayout =
        (SwipeRefreshLayout) v(R.id.swipeRefreshLayout);
    swipeRefreshLayout.setColorSchemeColors(R.color.progressBar);
    swipeRefreshLayout.setRefreshing(true);
    swipeRefreshLayout.setOnRefreshListener(
        new SwipeRefreshLayout.OnRefreshListener() {
          @Override
          public void onRefresh() {
            getApp().getQueryHandler().reset();
            loadAndDisplay(true);
          }
        });

    v(R.id.reloadButton).setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {
        reloadQuery();
      }
    });

    final View nextPageProgress = v(R.id.nextPageProgress);
    final ScrollView scrollView = (ScrollView) v(R.id.scrollView);
    scrollView.getViewTreeObserver().addOnScrollChangedListener(
        new ViewTreeObserver.OnScrollChangedListener() {
          @Override
          public void onScrollChanged() {
            if (getApp().getQueryHandler().hasNext()
                && nextPageProgress.getVisibility() == View.GONE) {
              View lastChild =
                  scrollView.getChildAt(scrollView.getChildCount() - 1);
              if ((lastChild.getBottom()
                  - (scrollView.getHeight() + scrollView.getScrollY())) == 0) {
                setVisible(nextPageProgress);
                loadAndDisplay();
              }
            }
          }
        });
  }

  private void loadAndDisplay() {
    loadAndDisplay(false);
  }

  private void loadAndDisplay(final boolean clear) {
    if (!isOnline()) {
      setInvisible(v(R.id.progress));
      setGone(v(R.id.initialProgress));
      setVisible(v(R.id.statusText, R.id.reloadButton));
      TextView statusText = tv(R.id.statusText);
      statusText.setText(getString(R.string.no_network));
      statusText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
      return;
    }

    new AsyncTask<Void, Void, ChangeListData>() {
      private SwipeRefreshLayout swipeRefreshLayout;
      private View progress;
      private View initialProgress;
      private View nextPageProgress;
      private View reloadButton;
      private TextView statusText;
      private ViewGroup changeList;

      @Override
      protected void onPreExecute() {
        super.onPreExecute();
        swipeRefreshLayout = (SwipeRefreshLayout) v(R.id.swipeRefreshLayout);
        progress = v(R.id.progress);
        initialProgress = v(R.id.initialProgress);
        nextPageProgress = v(R.id.nextPageProgress);
        reloadButton = v(R.id.reloadButton);
        statusText = tv(R.id.statusText);
        changeList = vg(R.id.changeList);
      }

      @Override
      protected ChangeListData doInBackground(Void... v) {
        try {
          QueryHandler queryHandler = getApp().getQueryHandler();
          if (queryHandler.hasNext()) {
            return new ChangeListData(queryHandler.next());
          } else {
            return new ChangeListData(Collections.<Change>emptyList());
          }
        } catch (RestApiException e) {
          // e.g. server not reachable
          Log.e(TAG, "Request failed", e);
          if (e.getCause() != null) {
            return new ChangeListData(getString(R.string.error_with_cause,
                e.getMessage(), e.getCause().getMessage()));
          } else {
            return new ChangeListData(e.getMessage());
          }
        }
      }

      @Override
      protected void onPostExecute(ChangeListData changeListData) {
        super.onPostExecute(changeListData);

        if (getActivity() == null) {
          // user navigated away while we were waiting for the request
          return;
        }

        getActivity().invalidateOptionsMenu();
        setInvisible(progress);
        setGone(initialProgress, reloadButton, nextPageProgress);
        swipeRefreshLayout.setRefreshing(false);

        if (changeListData.error != null) {
          statusText.setText(changeListData.error);
          return;
        }

        if (!changeListData.changeList.isEmpty()) {
          setGone(statusText);
          if (clear) {
            changeList.removeAllViews();
          }
          for (Change change : changeListData.changeList) {
            ChangeEntry changeEntry = new ChangeEntry(getContext());
            changeEntry.init(getApp(), change);
            changeList.addView(changeEntry);
            addSeparator(changeList);
          }
        } else {
          statusText.setText(getString(R.string.no_changes_match));
        }
      }
    }.execute();
  }

  private void display(List<Change> changes) {
    setInvisible(v(R.id.progress));
    setGone(v(R.id.initialProgress, R.id.reloadButton, R.id.nextPageProgress,
        R.id.statusText));
    ((SwipeRefreshLayout) v(R.id.swipeRefreshLayout)).setRefreshing(false);
    ViewGroup changeList = vg(R.id.changeList);
    for (Change change : changes) {
      ChangeEntry changeEntry = new ChangeEntry(getContext());
      changeEntry.init(ReviewChangesFragment.this, getApp(), change);
      changeList.addView(changeEntry);
      addSeparator(changeList);
    }
  }

  private void addSeparator(ViewGroup viewGroup) {
    View separator = new View(getContext());
    separator.setLayoutParams(
        matchAndFixedLayout(widgetUtil.dpToPx(1)));
    separator.setBackgroundColor(widgetUtil.color(R.color.separator));
    viewGroup.addView(separator);
  }

  private void reloadQuery() {
    getApp().getQueryHandler().reset();
    display(getClass(), false);
  }

  @Override
  public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_review_changes, menu);
    super.onCreateOptionsMenu(menu, inflater);
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
      case R.id.action_reload_query:
        reloadQuery();
        return true;
      default:
        return super.onOptionsItemSelected(item);
    }
  }

  private static class ChangeListData {
    final List<Change> changeList;
    final String error;

    ChangeListData(List<Change> changeList) {
      this.changeList = changeList;
      this.error = null;
    }

    ChangeListData(String error) {
      this.changeList = null;
      this.error = error;
    }
  }
}
