// 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.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Point;
import android.graphics.drawable.GradientDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.ColorRes;
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import android.util.Log;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.google.gerrit.extensions.client.ChangeStatus;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.reviewit.app.ActionHandler;
import com.google.reviewit.app.Change;
import com.google.reviewit.app.ConfigManager;
import com.google.reviewit.app.QueryConfig;
import com.google.reviewit.util.ChangeUtil;
import com.google.reviewit.widget.ChangeBox;
import com.google.reviewit.util.NoOpAnimatorListener;
import com.google.reviewit.util.ObservableAsynTask;
import com.google.reviewit.util.TaskObserver;
import com.google.reviewit.util.WidgetUtil;
import com.urswolfer.gerrit.client.rest.http.HttpStatusException;

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

/**
 * Fragment that presents changes one by one and lets the user decide to
 * ignore/skip/star each change.
 */
public class SortChangesFragment extends BaseFragment
    implements OnBackPressedAware {
  private static final String TAG = SortChangesFragment.class.getName();

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

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

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

    setHasOptionsMenu(true);

    if (getActionHandler().hasCurrentChange()) {
      getActionHandler().pushBack();
    }

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

  @Override
  public void onAttach(Context context) {
    super.onAttach(context);
  }

  private void display() {
    ConfigManager cfgManager = getApp().getConfigManager();
    QueryConfig config = cfgManager.getQueryConfig();
    if (!config.isComplete()) {
      display(SortSettingFragment.class);
      return;
    }

    if (!isOnline()) {
      setInvisible(v(R.id.progress));
      WidgetUtil.setText(v(R.id.noResultBoxText),
          getString(R.string.no_network));
      setVisible(v(R.id.root, R.id.noResultBox));
      setGone(v(R.id.resultBox, R.id.loadingBox));
      return;
    }

    if (getActionHandler().isQueryNeeded()) {
      if (v(R.id.changeBox) == null) {
        setVisible(v(R.id.loadingBox));
        setInvisible(v(R.id.progress));
        disableButtons();
        showButtons(false);
      } else {
        setVisible(v(R.id.progress));
      }
    } else {
      Change change = getActionHandler().preview();
      if (change != null) {
        ChangeUtil.colorBackground(root, change);
      }
    }
    setVisible(v(R.id.root));

    new AsyncTask<Void, Void, ChangeData>() {
      private View progress;
      private View loadingBox;
      private ViewGroup resultBox;
      private View noResultBox;
      private TextView noResultBoxText;
      private ChangeBox changeBox;

      @Override
      protected void onPreExecute() {
        super.onPreExecute();
        progress = v(R.id.progress);
        loadingBox = v(R.id.loadingBox);
        resultBox = vg(R.id.resultBox);
        noResultBox = v(R.id.noResultBox);
        noResultBoxText = tv(R.id.noResultBoxText);
        changeBox = (ChangeBox) v(R.id.changeBox);
      }

      @Override
      protected ChangeData doInBackground(Void... v) {
        try {
          ActionHandler actionHandler = getActionHandler();
          if (actionHandler.hasNext()) {
            Change change = actionHandler.next();
            int queueSize = actionHandler.getQueueSize();
            Change nextChange = null;
            if (queueSize > 0) {
              nextChange = actionHandler.preview();
            }
            return new ChangeData(change, nextChange, queueSize);
          } else {
            return ChangeData.empty();
          }
        } catch (RestApiException e) {
          // e.g. server not reachable
          Log.e(TAG, "Request failed", e);
          if (e.getCause() != null) {
            return new ChangeData(getString(R.string.error_with_cause,
                e.getMessage(), e.getCause().getMessage()));
          } else {
            return new ChangeData(e.getMessage());
          }
        }
      }

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

        getActivity().invalidateOptionsMenu();
        setInvisible(progress);

        if (changeData.error != null) {
          noResultBoxText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
          noResultBoxText.setText(changeData.error);
          setVisible(noResultBox);
          setGone(resultBox, loadingBox);
          return;
        }

        if (changeData.change != null) {
          setVisible(resultBox);
          setGone(noResultBox, loadingBox);

          if (changeBox == null) {
            changeBox = new ChangeBox(getContext());
            resultBox.addView(changeBox);
            changeBox.display(getApp(), changeData.change);
          }
          ChangeUtil.colorBackground(root, changeData.change);

          initButtons(changeBox);
          initSwipeAnimation(changeBox);

          if (changeData.nextChange != null) {
            ChangeBox changeBox2 = new ChangeBox(getContext());
            resultBox.addView(changeBox2, resultBox.getChildCount() - 1);
            changeBox2.display(getApp(), changeData.nextChange);
          }
          pageEffect(changeData.queueSize);
        } else {
          noResultBoxText.setText(getString(R.string.no_more_changes));
          setVisible(noResultBox);
          setGone(resultBox, loadingBox);
        }
      }
    }.execute();
  }

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

  private void initButtons(final View changeBox) {
    showButtons(true);

    setButtonBackgroundEnabled(R.id.ignoreLayout,
        SemiCircleDrawable.Direction.RIGHT);
    setButtonBackgroundEnabled(R.id.skipButton,
        SemiCircleDrawable.Direction.TOP);
    setButtonBackgroundEnabled(R.id.starLayout,
        SemiCircleDrawable.Direction.LEFT);

    v(R.id.skipButton).setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {
        disableButtons();
        getActionHandler().skip();
        animate(changeBox, ActionHandler.Action.SKIP);
      }
    });

    View.OnClickListener onStarClickListener = new View.OnClickListener() {
      public void onClick(View v) {
        disableButtons();
        getActionHandler().star();
        animate(changeBox, ActionHandler.Action.STAR);
      }
    };
    v(R.id.starButton).setOnClickListener(onStarClickListener);
    v(R.id.starLayout).setOnClickListener(onStarClickListener);

    View.OnClickListener onIgnoreClickListener = new View.OnClickListener() {
      public void onClick(View v) {
        disableButtons();
        getActionHandler().ignore();
        animate(changeBox, ActionHandler.Action.IGNORE);
      }
    };
    v(R.id.ignoreButton).setOnClickListener(onIgnoreClickListener);
    v(R.id.ignoreLayout).setOnClickListener(onIgnoreClickListener);

    changeBox.findViewById(R.id.changeBoxLowerPart).setOnClickListener(
        new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        display(DetailedChangeFragment.class);
      }
    });
  }

  private void disableButtons() {
    setButtonBackgroundDisabled(R.id.ignoreLayout,
        SemiCircleDrawable.Direction.RIGHT);
    setButtonBackgroundDisabled(R.id.skipButton,
        SemiCircleDrawable.Direction.TOP);
    setButtonBackgroundDisabled(R.id.starLayout,
        SemiCircleDrawable.Direction.LEFT);

    v(R.id.skipButton).setOnClickListener(null);
    v(R.id.starButton).setOnClickListener(null);
    v(R.id.starLayout).setOnClickListener(null);
    v(R.id.ignoreButton).setOnClickListener(null);
    v(R.id.ignoreLayout).setOnClickListener(null);
  }

  private void showButtons(boolean show) {
    if (show) {
      setVisible(v(R.id.skipButton, R.id.starButton, R.id.starLayout,
          R.id.ignoreButton, R.id.ignoreLayout));
    } else {
      setInvisible(v(R.id.skipButton, R.id.starButton, R.id.starLayout,
          R.id.ignoreButton, R.id.ignoreLayout));
    }
  }

  // TODO extract animation into own class
  private void initSwipeAnimation(final View changeBox) {
    final Point screenSize = getScreenSize();
    final int screenCenter = screenSize.x / 2;

    // TODO swipe animation doesn't look good on wide screens,
    // e.g. when phone is turned horizontally
    final ViewGroup resultBox = vg(R.id.resultBox);
    changeBox.findViewById(R.id.changeBoxUpperPart).setOnTouchListener(
        new View.OnTouchListener() {
      private ActionHandler.Action action = ActionHandler.Action.NONE;
      private int x;
      private int y;

      @Override
      public boolean onTouch(View v, MotionEvent event) {
        int eventX = (int) event.getRawX();
        int eventY = (int) event.getRawY();
        switch (event.getAction()) {
          case MotionEvent.ACTION_DOWN:
            x = (int) event.getRawX();
            y = (int) event.getRawY();
            break;
          case MotionEvent.ACTION_MOVE:
            changeBox.setX(widgetUtil.getDimension(R.dimen
                .activity_horizontal_margin) + eventX - x);
            changeBox.setY(widgetUtil.getDimension(R.dimen
                .activity_vertical_margin) + eventY - y);

            if (eventX >= screenCenter) {
              changeBox.setRotation(
                  (float) ((eventX - screenCenter) * (Math.PI / 32)));

              if (eventX > (screenCenter + (screenCenter / 2))) {
                ((GradientDrawable) changeBox.getBackground())
                    .setColor(widgetUtil.color(R.color.commitMessageStar));
                action = ActionHandler.Action.STAR;
              } else {
                action = ActionHandler.Action.NONE;
                ((GradientDrawable) changeBox.getBackground())
                    .setColor(widgetUtil.color(R.color.commitMessage));
              }
            } else {
              changeBox.setRotation(
                  (float) ((eventX - screenCenter) * (Math.PI / 32)));
              if (eventX < (screenCenter / 2)) {
                ((GradientDrawable) changeBox.getBackground())
                    .setColor(widgetUtil.color(R.color.commitMessageIgnore));
                action = ActionHandler.Action.IGNORE;
              } else {
                action = ActionHandler.Action.NONE;
                ((GradientDrawable) changeBox.getBackground())
                    .setColor(widgetUtil.color(R.color.commitMessage));
              }
            }
            break;
          case MotionEvent.ACTION_UP:
            ((GradientDrawable) changeBox.getBackground())
                .setColor(widgetUtil.color(R.color.commitMessage));
            switch (action) {
              case STAR:
                getActionHandler().star();
                resultBox.removeView(changeBox);
                display();
                break;
              case IGNORE:
                getActionHandler().ignore();
                resultBox.removeView(changeBox);
                display();
                break;
              case SKIP:
                getActionHandler().skip();
                resultBox.removeView(changeBox);
                display();
                break;
              case NONE:
                WidgetUtil.setXY(changeBox,
                    widgetUtil.getDimension(R.dimen.activity_horizontal_margin),
                    widgetUtil.getDimension(R.dimen.activity_vertical_margin));
                changeBox.setRotation(0);
                break;
              default:
                throw new IllegalStateException("unknown action: " + action);
            }
            break;
          default:
            break;
        }
        return true;
      }
    });
  }

  private void animate(
      final View changeBox, final ActionHandler.Action action) {
    final ViewGroup resultBox = vg(R.id.resultBox);
    Point screenSize = getScreenSize();
    final int screenCenter = screenSize.x / 2;
    ObjectAnimator animator;
    switch (action) {
      case STAR:
        animator = ObjectAnimator.ofFloat(changeBox, "x", screenSize.x);
        break;
      case IGNORE:
        animator = ObjectAnimator.ofFloat(changeBox, "x",
            -changeBox.getWidth());
        break;
      case SKIP:
        animator = ObjectAnimator.ofFloat(changeBox, "alpha", 0);
        break;
      case NONE:
        return;
      default:
        throw new IllegalStateException("unknown action: " + action);
    }

    animator.setDuration(1000);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        switch (action) {
          case STAR:
            changeBox.setRotation((float) (
                (changeBox.getX() + changeBox.getWidth() / 2 - screenCenter)
                    * (Math.PI / 32)));
            ((GradientDrawable) changeBox.getBackground())
                .setColor(widgetUtil.color(R.color.commitMessageStar));
            break;
          case IGNORE:
            changeBox.setRotation(
                (float) ((changeBox.getX() +
                    changeBox.getWidth() / 2 - screenCenter)
                        * (Math.PI / 32)));
            ((GradientDrawable) changeBox.getBackground())
                .setColor(widgetUtil.color(R.color.commitMessageIgnore));
            break;
          case SKIP:
          case NONE:
          default:
            break;
        }
      }
    });
    animator.addListener(new NoOpAnimatorListener() {
      @Override
      public void onAnimationEnd(Animator animation) {
        switch (action) {
          case STAR:
          case IGNORE:
          case SKIP:
            resultBox.removeView(changeBox);
            display();
          case NONE:
          default:
            break;
        }
      }
    });
    animator.start();
  }

  private Point getScreenSize() {
    Point screenSize = new Point();
    getActivity().getWindowManager().getDefaultDisplay().getSize(screenSize);
    return screenSize;
  }

  private void pageEffect(int moreChangesCount) {
    View page = v(R.id.page);
    switch (moreChangesCount) {
      case 0:
        setGone(page);
        return;
      case 1:
        WidgetUtil.setRightMargin(page,
            widgetUtil.getDimension(R.dimen.activity_horizontal_margin) - 6);
        WidgetUtil.setBottomMargin(page,
            widgetUtil.getDimension(R.dimen.reviewit_bottom_area_height) - 6);
        setVisible(page);
        WidgetUtil.setBackground(page,
            widgetUtil.getDrawable(R.drawable.two_page_border));
        return;
      case 2:
        WidgetUtil.setRightMargin(page,
            widgetUtil.getDimension(R.dimen.activity_horizontal_margin) - 12);
        WidgetUtil.setBottomMargin(page,
            widgetUtil.getDimension(R.dimen.reviewit_bottom_area_height) - 12);
        setVisible(page);
        WidgetUtil.setBackground(page,
            widgetUtil.getDrawable(R.drawable.three_page_border));
        return;
      default:
        WidgetUtil.setRightMargin(page,
            widgetUtil.getDimension(R.dimen.activity_horizontal_margin) - 18);
        WidgetUtil.setBottomMargin(page,
            widgetUtil.getDimension(R.dimen.reviewit_bottom_area_height) - 18);
        setVisible(page);
        WidgetUtil.setBackground(page,
            widgetUtil.getDrawable(R.drawable.multi_page_border));
    }
  }

  private void setButtonBackgroundEnabled(
      @IdRes int id, SemiCircleDrawable.Direction direction) {
    setButtonBackground(id, direction, R.color.buttonFill,
        R.color.buttonBorder);
  }

  private void setButtonBackgroundDisabled(
      @IdRes int id, SemiCircleDrawable.Direction direction) {
    setButtonBackground(id, direction, R.color.buttonFillDisabled,
        R.color.buttonBorderDisabled);
  }

  private void setButtonBackground(
      @IdRes int id, SemiCircleDrawable.Direction direction,
      @ColorRes int fillColorId, @ColorRes int borderColorId) {
    WidgetUtil.setBackground(v(id), new SemiCircleDrawable(direction,
        widgetUtil.color(fillColorId), widgetUtil.color(borderColorId)));
  }

  @Override
  public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    ActionHandler actionHandler = getActionHandler();
    inflater.inflate(R.menu.menu_sort_changes, menu);
    for (int i = 0; i < menu.size(); i++) {
      MenuItem item = menu.getItem(i);
      if (item.getItemId() == R.id.action_undo) {
        item.setVisible(actionHandler.undoPossible());
      } else if (item.getItemId() == R.id.action_add_reviewer) {
        item.setVisible(actionHandler.hasCurrentChange());
      } else if (item.getItemId() == R.id.action_abandon) {
        item.setVisible(actionHandler.hasCurrentChange()
            && (actionHandler.getCurrentChange().info.status
                == ChangeStatus.NEW ||
            actionHandler.getCurrentChange().info.status
                == ChangeStatus.SUBMITTED));
      } else if (item.getItemId() == R.id.action_reload_change) {
        item.setVisible(actionHandler.hasCurrentChange());
      } else if (item.getItemId() == R.id.action_restore) {
        item.setVisible(actionHandler.hasCurrentChange() && actionHandler
            .getCurrentChange().info.status == ChangeStatus.ABANDONED);
      }
    }
    super.onCreateOptionsMenu(menu, inflater);
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
      case R.id.action_abandon:
        display(AbandonFragment.create(getClass()));
        return true;
      case R.id.action_add_reviewer:
        display(AddReviewerFragment.create(getClass()));
        return true;
      case R.id.action_help:
        display(HelpFragment.class);
        return true;
      case R.id.action_preferences:
        display(PreferencesFragment.class);
        return true;
      case R.id.action_reload_change:
        reloadChange();
        return true;
      case R.id.action_reload_query:
        reloadQuery();
        return true;
      case R.id.action_restore:
        display(RestoreActivity.create(getClass()));
        return true;
      case R.id.action_undo:
        undo();
        return true;
      default:
        return super.onOptionsItemSelected(item);
    }
  }

  private void undo() {
    ActionHandler actionHandler = getActionHandler();
    if (!actionHandler.undoPossible()) {
      return;
    }
    actionHandler.undo();
    ViewGroup resultBox = vg(R.id.resultBox);
    View changeBox = v(R.id.changeBox);
    while (changeBox != null) {
      resultBox.removeView(changeBox);
      changeBox = v(R.id.changeBox);
    }
    display();
  }

  private void reloadChange() {
    new ObservableAsynTask<Change, Void, String>() {
      @Override
      protected String doInBackground(Change... changes) {
        Change change = changes[0];
        try {
          change.reload();
          return null;
        } catch (RestApiException e) {
          if (e instanceof HttpStatusException) {
            HttpStatusException se = (HttpStatusException) e;
            return getString(R.string.reload_error, se.getStatusCode(),
                se.getStatusText());
          } else {
            return e.getMessage();
          }
        }
      }

      @Override
      protected void postExecute(String errorMsg) {
        if (errorMsg != null) {
          widgetUtil.showError(errorMsg);
        } else {
          display(SortChangesFragment.class);
        }
      }
    }.execute(getActionHandler().getCurrentChange());
  }

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

  @Override
  public boolean onBackPressed() {
    if (getActionHandler().undoPossible()) {
      undo();
      return true;
    }

    return false;
  }

  private static class ChangeData {
    static ChangeData empty() {
      return new ChangeData(null, null, 0);
    }

    final Change change;
    final Change nextChange;
    final int queueSize;
    final String error;

    ChangeData(Change change, Change nextChange, int queueSize) {
      this.change = change;
      this.nextChange = nextChange;
      this.queueSize = queueSize;
      this.error = null;
    }

    ChangeData(String error) {
      this.change = null;
      this.nextChange = null;
      this.queueSize = 0;
      this.error = error;
    }
  }
}
