package com.airbnb.lottie.samples;

import android.Manifest;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.util.Pair;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatSeekBar;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.airbnb.lottie.LottieAnimationView;
import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.OnCompositionLoadedListener;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class AnimationFragment extends Fragment {
  private static final String TAG = AnimationFragment.class.getSimpleName();

  private static final int RC_ASSET = 1337;
  private static final int RC_FILE = 1338;
  private static final int RC_URL = 1339;
  private static final int RC_QR = 1340;
  private static final int RC_CAMERA = 1341;

  static final String EXTRA_ANIMATION_NAME = "animation_name";
  static final String EXTRA_URL = "json_url";
  private static final float SCALE_SLIDER_FACTOR = 50f;

  static AnimationFragment newInstance() {
    return new AnimationFragment();
  }

  private final Map<String, String> assetFolders = new HashMap<String, String>() {{
    put("WeAccept.json", "Images/WeAccept");
  }};

  private OkHttpClient client;

  @BindView(R.id.toolbar) Toolbar toolbar;
  @BindView(R.id.instructions) ViewGroup instructionsContainer;
  @BindView(R.id.animation_container) ViewGroup animationContainer;
  @BindView(R.id.animation_view) LottieAnimationView animationView;
  @BindView(R.id.seek_bar) AppCompatSeekBar seekBar;
  @BindView(R.id.scale_seek_bar) AppCompatSeekBar scaleSeekBar;
  @BindView(R.id.scale_text) TextView scaleTextView;
  @BindView(R.id.invert_colors) ImageButton invertButton;
  @BindView(R.id.play_button) ImageButton playButton;
  @BindView(R.id.loop) ImageButton loopButton;
  @BindView(R.id.animation_name) TextView animationNameView;
  @BindView(R.id.qr_code) TextView qrCodeTextView;
  @BindView(R.id.sample_animations) TextView sampleAnimationsTextView;
  @BindView(R.id.load_animation) TextView loadAnimationTextView;
  @BindView(R.id.load_from_json) TextView loadFromJsonTextView;

  @Nullable
  @Override
  public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
      @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_animation, container, false);
    ButterKnife.bind(this, view);

    ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
    toolbar.setNavigationIcon(R.drawable.ic_back);
    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
        getFragmentManager().popBackStack();
      }
    });
    setHasOptionsMenu(true);
    postUpdatePlayButtonText();
    onLoopChanged();

    setDrawableLeft(qrCodeTextView, R.drawable.ic_qr_scan);
    setDrawableLeft(sampleAnimationsTextView, R.drawable.ic_assets);
    setDrawableLeft(loadAnimationTextView, R.drawable.ic_file);
    setDrawableLeft(loadFromJsonTextView, R.drawable.ic_network);

    animationView.addAnimatorListener(new Animator.AnimatorListener() {
      @Override public void onAnimationStart(Animator animation) {
        startRecordingDroppedFrames();
      }

      @Override public void onAnimationEnd(Animator animation) {
        recordDroppedFrames();
        postUpdatePlayButtonText();
      }

      @Override public void onAnimationCancel(Animator animation) {
        postUpdatePlayButtonText();
      }

      @Override public void onAnimationRepeat(Animator animation) {
        recordDroppedFrames();
        startRecordingDroppedFrames();
      }
    });
    animationView.addAnimatorUpdateListener(
        new ValueAnimator.AnimatorUpdateListener() {
          @Override public void onAnimationUpdate(ValueAnimator animation) {
            seekBar.setProgress((int) (animation.getAnimatedFraction() * 100));
          }
        });

    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
      @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (!animationView.isAnimating()) {
          animationView.setProgress(progress / 100f);
        }
      }

      @Override public void onStartTrackingTouch(SeekBar seekBar) {
      }

      @Override public void onStopTrackingTouch(SeekBar seekBar) {
      }
    });

    scaleSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
      @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        animationView.setScale(progress / SCALE_SLIDER_FACTOR);
        scaleTextView.setText(String.format(Locale.US, "%.2f", animationView.getScale()));
      }

      @Override public void onStartTrackingTouch(SeekBar seekBar) {
      }

      @Override public void onStopTrackingTouch(SeekBar seekBar) {
      }
    });

    return view;
  }

  private void setDrawableLeft(TextView textView, @DrawableRes int resId) {
    Drawable drawable = VectorDrawableCompat.create(getResources(), resId, getActivity().getTheme());
    textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
  }

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

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

  @Override public boolean onOptionsItemSelected(MenuItem item) {
    if (item.isCheckable()) {
      item.setChecked(!item.isChecked());
    }
    switch (item.getItemId()) {
      case R.id.hardware_acceleration:
        animationView.useExperimentalHardwareAcceleration(item.isChecked());
        return true;
      case R.id.merge_paths:
        animationView.enableMergePathsForKitKatAndAbove(item.isChecked());
        return true;
    }
    return super.onOptionsItemSelected(item);
  }

  @Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != Activity.RESULT_OK) {
      return;
    }

    switch (requestCode) {
      case RC_ASSET:
        final String assetName = data.getStringExtra(EXTRA_ANIMATION_NAME);
        animationView.setImageAssetsFolder(assetFolders.get(assetName));
        LottieComposition.Factory.fromAssetFileName(getContext(), assetName,
            new OnCompositionLoadedListener() {
              @Override public void onCompositionLoaded(@Nullable LottieComposition composition) {
                if (composition == null) {
                  onLoadError();
                  return;
                }
                setComposition(composition, assetName);
              }
            });
        break;
      case RC_FILE:
        onFileLoaded(data.getData());
        break;
      case RC_URL:

        break;
      case RC_QR:
        loadUrl(data.getExtras().getString(EXTRA_URL));
        break;
    }
  }

  private void setComposition(LottieComposition composition, String name) {
    if (composition.hasImages() && TextUtils.isEmpty(animationView.getImageAssetsFolder())) {
      //noinspection ConstantConditions
      Snackbar.make(
          getView(),
          "This animation has images and no image folder was set",
          Snackbar.LENGTH_LONG).show();
      return;
    }
    instructionsContainer.setVisibility(View.GONE);
    seekBar.setProgress(0);
    animationView.setComposition(composition);
    animationNameView.setText(name);
    scaleTextView.setText(String.format(Locale.US, "%.2f", animationView.getScale()));
    scaleSeekBar.setProgress((int) (animationView.getScale() * SCALE_SLIDER_FACTOR));

  }

  @OnClick(R.id.play_button)
  void onPlayClicked() {
    if (animationView.isAnimating()) {
      animationView.pauseAnimation();
      postUpdatePlayButtonText();
    } else {
      if (animationView.getProgress() == 1f) {
        animationView.setProgress(0f);
      }
      animationView.resumeAnimation();
      postUpdatePlayButtonText();
    }
  }

  @OnClick(R.id.loop)
  void onLoopChanged() {
    loopButton.setActivated(!loopButton.isActivated());
    animationView.loop(loopButton.isActivated());
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
      @NonNull int[] grantResults) {
    if (requestCode == RC_CAMERA && grantResults.length > 0 && grantResults[0] == PackageManager
        .PERMISSION_GRANTED) {
      startActivityForResult(new Intent(getContext(), QRScanActivity.class), RC_QR);
    } else {
      Toast.makeText(getContext(), R.string.permission_required, Toast.LENGTH_LONG).show();
    }

  }

  @OnClick(R.id.qrscan)
  void onQRScanClicked() {
    animationView.cancelAnimation();
    if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) !=
        PackageManager.PERMISSION_GRANTED) {

      requestPermissions(new String[]{Manifest.permission.CAMERA}, RC_CAMERA);

    } else {
      startActivityForResult(new Intent(getContext(), QRScanActivity.class), RC_QR);
    }
  }

  @OnClick(R.id.restart)
  void onRestartClicked() {
    boolean restart = animationView.isAnimating();
    animationView.cancelAnimation();
    animationView.setProgress(0f);
    if (restart) {
      animationView.playAnimation();
    }
  }

  @OnClick(R.id.invert_colors)
  void onInvertClicked() {
    animationContainer.setActivated(!animationContainer.isActivated());
    invertButton.setActivated(animationContainer.isActivated());
  }

  @OnClick(R.id.load_asset)
  void onLoadAssetClicked() {
    animationView.cancelAnimation();
    android.support.v4.app.DialogFragment assetFragment = ChooseAssetDialogFragment.newInstance();
    assetFragment.setTargetFragment(this, RC_ASSET);
    assetFragment.show(getFragmentManager(), "assets");
  }

  @OnClick(R.id.load_file)
  void onLoadFileClicked() {
    animationView.cancelAnimation();
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("*/*");
    intent.addCategory(Intent.CATEGORY_OPENABLE);

    try {
      startActivityForResult(Intent.createChooser(intent, "Select a JSON file"), RC_FILE);
    } catch (android.content.ActivityNotFoundException ex) {
      // Potentially direct the user to the Market with a Dialog
      Toast.makeText(getContext(), "Please install a File Manager.", Toast.LENGTH_SHORT).show();
    }
  }

  @OnClick(R.id.load_url_or_json)
  void onLoadUrlOrJsonClicked() {
    animationView.cancelAnimation();
    final EditText urlOrJsonView = new EditText(getContext());
    new AlertDialog.Builder(getContext())
        .setTitle("Enter a URL or JSON string")
        .setView(urlOrJsonView)
        .setPositiveButton("Load", new DialogInterface.OnClickListener() {
          @Override public void onClick(DialogInterface dialog, int which) {
            loadUrlOrJson(urlOrJsonView.getText().toString());
          }
        })
        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
          @Override public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
          }
        })
        .show();
  }

  private void postUpdatePlayButtonText() {
    new Handler().post(new Runnable() {
      @Override public void run() {
        updatePlayButtonText();
      }
    });
  }

  private void updatePlayButtonText() {
    playButton.setActivated(animationView.isAnimating());
  }

  private void onFileLoaded(final Uri uri) {
    InputStream fis;

    try {
      switch (uri.getScheme()) {
        case "file":
          fis = new FileInputStream(uri.getPath());
          break;
        case "content":
          fis = getContext().getContentResolver().openInputStream(uri);
          break;
        default:
          onLoadError();
          return;
      }
    } catch (FileNotFoundException e) {
      onLoadError();
      return;
    }

    LottieComposition.Factory
        .fromInputStream(getContext(), fis, new OnCompositionLoadedListener() {
          @Override public void onCompositionLoaded(@Nullable LottieComposition composition) {
            if (composition == null) {
              onLoadError();
              return;
            }
            setComposition(composition, uri.getPath());
          }
        });
  }

  private void loadUrlOrJson(String text) {
    if (text.charAt(0) == '{') {
      // Assume JSON
      loadJsonString(text);
      return;
    }
    loadUrl(text);
  }

  private void loadJsonString(String jsonString) {
    try {
      JSONObject json = new JSONObject(jsonString);
      LottieComposition.Factory
          .fromJson(getResources(), json, new OnCompositionLoadedListener() {
            @Override public void onCompositionLoaded(@Nullable LottieComposition composition) {
              if (composition == null) {
                onLoadError();
                return;
              }
              setComposition(composition, "Animation");
            }
          });
    } catch (JSONException e) {
      onLoadError();
    }
  }

  private void loadUrl(String url) {
    Request request;
    try {
      request = new Request.Builder()
          .url(url)
          .build();
    } catch (IllegalArgumentException e) {
      onLoadError();
      return;
    }


    if (client == null) {
      client = new OkHttpClient();
    }
    client.newCall(request).enqueue(new Callback() {
      @Override public void onFailure(Call call, IOException e) {
        onLoadError();
      }

      @Override public void onResponse(Call call, Response response) throws IOException {
        if (!response.isSuccessful()) {
          onLoadError();
        }

        loadJsonString(response.body().string());
      }
    });
  }

  private void onLoadError() {
    //noinspection ConstantConditions
    Snackbar.make(getView(), "Failed to load animation", Snackbar.LENGTH_LONG).show();
  }

  private void startRecordingDroppedFrames() {
    getApplication().startRecordingDroppedFrames();
  }

  private void recordDroppedFrames() {
    Pair<Integer, Long> droppedFrames = getApplication().stopRecordingDroppedFrames();
    Log.d(TAG, "Dropped frames: " + droppedFrames.first);
  }

  private ILottieApplication getApplication() {
    return (ILottieApplication) getActivity().getApplication();
  }
}