/*
 * COPYRIGHT (c) 2018 All rights reserved by HANWHA LIFE.
 */
package kr.co.zumo.app.lifeplus.view.custom.pin;

import android.content.Context;
import android.support.annotation.StringRes;
import android.support.constraint.ConstraintLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

import kr.co.zumo.app.R;
import kr.co.zumo.app.lifeplus.util.ResourceUtil;
import kr.co.zumo.app.lifeplus.util.StringUtil;

/**
 * PinView
 * <pre>
 * </pre>
 *
 * @author 민효동
 * @version 1.0
 * @history 민효동   [2018-10-04]   [최초 작성]
 * @since 2018-10-04
 */
public class CustomPinView extends ConstraintLayout implements IPinContract.View {

  private ArrayList<Integer> numberList;
  private ArrayList<Button> buttonList;
  private ArrayList<ImageView> imageList;
  private String password;
  private String guideString = "";
  @StringRes
  private int titleStringId = R.string.empty_string;

  private TextView textGuide;
  private TextView textTitle;
  private TextView textReset;
  private Button buttonShuffle;
  private ImageButton buttonDelete;

  private IPinContract.Presenter presenter;

  public void setPresenter(IPinContract.Presenter presenter) {
    this.presenter = presenter;

    this.presenter.onPinStart();
  }

  public CustomPinView(Context context) {
    super(context);
    init(context);
  }

  public CustomPinView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
  }

  public CustomPinView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context);
  }

  private void init(Context context) {

    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.fragment_pin, this);

    password = "";

    View view = this;

    buttonShuffle = view.findViewById(R.id.button_shuffle);
    buttonDelete = view.findViewById(R.id.button_delete);
    textGuide = view.findViewById(R.id.text_guide);
    textTitle = view.findViewById(R.id.text_title);
    textReset = view.findViewById(R.id.button_sign_up_pin_code_reset);

    if (StringUtil.isFull(guideString)) {
      textGuide.setText(guideString);
    }

    if (R.string.empty_string != titleStringId) {
      textTitle.setText(titleStringId);
    }

    numberList = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
    buttonList = createButtonListFromView(view);
    imageList = createImageListFromView(view);

    buttonShuffle.setOnClickListener(v -> shuffleKeyboard());

    buttonDelete.setOnClickListener(v -> doSomeAfterClickDeleteButton());

    textReset.setOnClickListener(v -> presenter.onClickPinReset());

    int size = buttonList.size();
    for (int i = 0; i < size; ++i) {
      buttonList.get(i).setOnClickListener(v -> doSomeAfterClickNumberButton(v));
    }

  }

  /***********************************
   * IPinContract.View
   ***********************************/

  private ArrayList<Button> createButtonListFromView(View view) {
    ArrayList<Button> list = new ArrayList<Button>();
    list.add((Button) view.findViewById(R.id.button_0));
    list.add((Button) view.findViewById(R.id.button_1));
    list.add((Button) view.findViewById(R.id.button_2));
    list.add((Button) view.findViewById(R.id.button_3));
    list.add((Button) view.findViewById(R.id.button_4));
    list.add((Button) view.findViewById(R.id.button_5));
    list.add((Button) view.findViewById(R.id.button_6));
    list.add((Button) view.findViewById(R.id.button_7));
    list.add((Button) view.findViewById(R.id.button_8));
    list.add((Button) view.findViewById(R.id.button_9));

    return list;
  }

  private ArrayList<ImageView> createImageListFromView(View view) {
    ArrayList<ImageView> list = new ArrayList<ImageView>();
    list.add((ImageView) view.findViewById(R.id.image_pin_code1));
    list.add((ImageView) view.findViewById(R.id.image_pin_code2));
    list.add((ImageView) view.findViewById(R.id.image_pin_code3));
    list.add((ImageView) view.findViewById(R.id.image_pin_code4));
    return list;
  }


  private void shuffleKeyboard() {

    Collections.shuffle(numberList);
    int size = buttonList.size();

    for (int i = 0; i < size; ++i) {
      buttonList.get(i).setText(String.valueOf(numberList.get(i)));
    }
  }

  private void doSomeAfterAllPinCode() {
    String pin = password;
    password = "";

    presenter.onPinResult(pin);
  }

  private void doSomeAfterClickDeleteButton() {
    if (password.length() == 0) {
      return;
    }

    password = password.substring(0, password.length() - 1);
    updateImageAfterPinInput();

  }

  private void doSomeAfterClickNumberButton(View view) {

    int passwordSize = password.length();

    if (passwordSize < 4) {
      password += ((Button) view).getText().toString().charAt(0);

      updateImageAfterPinInput();

      passwordSize = password.length();
      if (passwordSize == 4) {
        Log.e("APP#  PinDialog | onClick", "|" + "if(password.length == 4)");
        doSomeAfterAllPinCode();
      }
    }
  }

  private void updateImageAfterPinInput() {
    int passwordSize = password.length();
    for (int i = 0; i < imageList.size(); ++i) {
      ImageView imageView = imageList.get(i);
      if (i < passwordSize) {
        imageView.setImageResource(R.drawable.circle_full);
      }
      else {
        imageView.setImageResource(R.drawable.circle_empty);
      }
    }
  }

  /**
   * 가이드 텍스트를 업데이트 한다.
   *
   * @param stringId
   */
  public void updateGuideText(@StringRes int stringId) {
    guideString = ResourceUtil.getString(stringId);

    if (null != textGuide) {
      textGuide.setText(guideString);
    }
  }

  @Override
  public void updateGuideTextColor(int color) {
    textGuide.setTextColor(color);
  }

  @Override
  public void setResetButtonVisible(boolean isVisible) {
    textReset.setVisibility(isVisible ? View.VISIBLE : View.GONE);
  }

  @Override
  public void updateGuideText(String str) {

    if (null != textGuide) {
      textGuide.setText(str);
    }
  }

  /**
   * title 텍스트를 업데이트 한다.
   *
   * @param stringId
   */
  public void updateTitleText(@StringRes int stringId) {
    titleStringId = stringId;

    if (null != textTitle) {
      textTitle.setText(titleStringId);
    }
  }

  @Override
  public void setEnabled() {
    setEnabledInternal(true);
  }

  @Override
  public void setDisabled() {
    setEnabledInternal(false);
  }

  @Override
  public void restart() {
    shuffleKeyboard();
    updateImageAfterPinInput();
    setEnabledInternal(true);
  }

  private void setEnabledInternal(boolean enabled) {
    textReset.setEnabled(enabled);
    buttonDelete.setEnabled(enabled);
    buttonShuffle.setEnabled(enabled);
    for (Button button : buttonList) {
      button.setEnabled(enabled);
    }
    for (ImageView imageView : imageList) {
      imageView.setEnabled(enabled);
    }
  }

  @Override
  public void dispose() {
  }
}
