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

import android.util.Log;

import java.util.concurrent.TimeUnit;

import io.reactivex.Completable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import kr.co.zumo.app.lifeplus.view.presenter.SignUpPresenter;

/**
 * SignUpStep
 * <pre>
 * </pre>
 *
 * @author 민효동
 * @version 1.0
 * @history 민효동   [2018. 9. 14.]   [최초 작성]
 * @since 2018. 9. 14.
 */
public abstract class SignUpStep implements ISignUpStep {

  protected Disposable disposable;
  protected SignUpPresenter presenter;
  protected ISignUpStep nextStep;
  protected ISignUpStep nextStepForFail;
  protected boolean isValidated = false;

  public SignUpStep(SignUpPresenter presenter) {
    this.presenter = presenter;
  }

  protected void addItem(SignUpItem item) {
    presenter.addItem(item);
  }

  protected void removeLastItem() {
    presenter.removeLastItem();
  }

  @Override
  public void start() {
    Log.w("APP# SignUpStep | start", "|" + this.getClass().getSimpleName());

    __start();
  }

  @Override
  public void validate() {
    Log.i("APP# SignUpStep | validate", "|" + "=============================>");

    __validate();
  }

  @Override
  public boolean isValidated() {
    return isValidated;
  }

  @Override
  public void dispose() {
    Log.e("APP# SignUpStep | dispose", "|" + this.getClass().getSimpleName());
    if (null != disposable) {
      disposable.dispose();
      disposable = null;
    }
    __dispose();

    if (null != nextStep) {
      nextStep.dispose();
    }

    if (null != nextStepForFail) {
      nextStepForFail.dispose();
    }
  }

  @Override
  public void setNext(ISignUpStep step) {
    nextStep = step;
  }

  @Override
  public void setNextForFail(ISignUpStep step) {
    nextStepForFail = step;
  }

  protected void callNextStep() {
    Log.w("APP# SignUpStep | complete", "|" + this.getClass().getSimpleName());
    if (null != nextStep) {
      nextStep.start();
    }
  }

  protected void callFailStep() {
    Log.w("APP# SignUpStep | fail", "|" + this.getClass().getSimpleName());
    if (null != nextStepForFail) {
      nextStepForFail.start();
    }
    else {
      Log.w("APP# SignUpStep | fail", "|" + "repeat-----------");
      __start();
    }
  }

  protected void timeout(int timeMillis, Action action) {

    disposable = Completable.timer(timeMillis, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
      .subscribe(() -> {
          action.run();
        }, Throwable::printStackTrace
      );
  }

  abstract void __start();

  abstract void __validate();

  abstract void __dispose();
}
