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

import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import kr.co.zumo.app.R;
import kr.co.zumo.app.lifeplus.bean.MobileAuthBean;
import kr.co.zumo.app.lifeplus.bean.api.BannerBean;
import kr.co.zumo.app.lifeplus.bean.api.MemberJoinRequestBean;
import kr.co.zumo.app.lifeplus.bean.api.PolicyBean;
import kr.co.zumo.app.lifeplus.bean.api.PolicyConfirmRequestBean;
import kr.co.zumo.app.lifeplus.bean.api.PolicyVersionBean;
import kr.co.zumo.app.lifeplus.bean.api.RequestBean;
import kr.co.zumo.app.lifeplus.bean.api.UserNoBean;
import kr.co.zumo.app.lifeplus.model.module.LoginModuleParser;
import kr.co.zumo.app.lifeplus.network.api.LifeplusAPIRepository;
import kr.co.zumo.app.lifeplus.util.ResourceUtil;
import kr.co.zumo.app.lifeplus.view.Event;

/**
 * SignUpModel
 * <pre>
 * </pre>
 *
 * @author 민효동
 * @version 1.0
 * @history 민효동   [2018. 9. 21.]   [최초 작성]
 * @since 2018. 9. 21.
 */
public class SignUpModel extends Model {

  protected CompositeDisposable disposable = new CompositeDisposable();

  protected ArrayList<PolicyBean> agreeItems;
  protected ArrayList<BannerBean> bannerItems;

  private boolean isAuthorized = false;
  private String encryptedPin;
  protected MobileAuthBean mobileAuthBean;

  public SignUpModel() {
  }

  @Override
  protected void destroyInternal() {
    if (null != disposable) {
      disposable.dispose();
      disposable = null;
    }

    agreeItems = null;
    bannerItems = null;
    isAuthorized = false;
    encryptedPin = null;
    mobileAuthBean = null;
  }

  @Override
  protected void startInternal() {
  }

  @Override
  protected void stopInternal() {
  }

  @Override
  protected void resumeInternal() {

  }

  @Override
  protected void pauseInternal() {

  }

  /**
   * 약관 리스트
   *
   * @return List<PolicyBean>
   */
  public List<PolicyBean> getAgreeItems() {
    return agreeItems;
  }

  /**
   * 배너 리스트
   *
   * @return
   */
  public ArrayList<BannerBean> getBannerItems() {
    return bannerItems;
  }

  /**
   * 가입 후 유저 아이디를 프리퍼런스에 저장한다.
   *
   * @param userId userId
   */
  public void saveUserId(String userId) {
    Log.i("APP# SignUpModel | saveUserId", "| userId: " + userId);
    SuperModel.getInstance().setUserId(userId);
  }

  public String getUserId() {
    return SuperModel.getInstance().getUserId();
  }

  /**
   * 핀 저장
   *
   * @param pin
   */
  public void savePin(String pin) {
    SuperModel.getInstance().savePinWithEncryption(pin);
    encryptedPin = getPreferences().getEncryptedPin();
  }

  /**
   * 배너 요청
   */
  public void requestBanners() {

    bannerItems = new ArrayList<>();
    bannerItems.add(new BannerBean(0, ResourceUtil.getString(R.string.sign_up_benefit1), ResourceUtil.getString(R.string.sign_up_benefit1_detail)));
    bannerItems.add(new BannerBean(1, ResourceUtil.getString(R.string.sign_up_benefit2), ResourceUtil.getString(R.string.sign_up_benefit2_detail)));
    bannerItems.add(new BannerBean(2, ResourceUtil.getString(R.string.sign_up_benefit3), ResourceUtil.getString(R.string.sign_up_benefit3_detail)));

    onResult(new Event.Builder(Event.RESULT).integer(Event.BANNER_REQUEST).build());
  }

  /**
   * 배너 요청 취소
   */
  public void stopBannerRequest() {
    if (null != disposable) {
      disposable.clear();
    }
  }

  /**
   * 모바일 인증 했음을 표시;
   */
  public void checkMobileAuthorized() {
    isAuthorized = true;
  }

  /**
   * 약관 리스트 요청
   */
  public void requestPolicy() {
    disposable.add(
      new LifeplusAPIRepository().getPolicyList(new RequestBean())
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(resultBean -> {
          Log.i("APP# SignUpModel | requestPolicy", "|" + resultBean.toPrettyJson());
          if (resultBean.isSuccess()) {
            agreeItems = resultBean.getData();
            onResult(new Event.Builder(Event.RESULT).integer(Event.POLICY_REQUEST).build());
          }
        }, e -> {
          onResult(new Event.Builder(Event.ERROR).integer(Event.POLICY_REQUEST).string(e.getLocalizedMessage()).build());
        })
    );
  }

  /**
   * 약관 요청 취소
   */
  public void stopPolicyRequest() {
    if (null != disposable) {
      disposable.clear();
    }
  }

  /**
   * 모바일 인증 정보 저장
   *
   * @param mobileAuthBean
   */
  public void setMobileAuthorizationBean(MobileAuthBean mobileAuthBean) {
    this.mobileAuthBean = mobileAuthBean;
  }

  /**
   * 모바일 인증 정보 반환
   *
   * @return
   */
  public MobileAuthBean getMobileAuthorizationBean() {
    if (null == mobileAuthBean) {
      mobileAuthBean = new MobileAuthBean();
    }
    return mobileAuthBean;
  }

  /**
   * 회원 가입 시작
   */
  public void signUp() {
    /*
     필수 항목 체크;
     */
    if (false == isAuthorized || null == mobileAuthBean) {
      // 인증 안했음;
      Log.e("APP#  SignUpModel | signUp", "|" + "인증 안했음");
    }
    else if (false == getPreferences().getEncryptedPin().equals(encryptedPin)) {
      // 핀 입력 안했음
      Log.e("APP#  SignUpModel | signUp", "|" + "핀 입력 안했음");
    }
    else if (false == isValidatedPolicy()) {
      // 필수 동의 안했음
      Log.e("APP#  SignUpModel | signUp", "|" + "필수 동의 안했음");
    }
    else {
      // 필수 항목 체크 완료;

      MemberJoinRequestBean bean = new MemberJoinRequestBean("", mobileAuthBean.getName(), SuperModel.getInstance().getDeviceUuid());

      disposable.add(
        new LifeplusAPIRepository().insertMember(bean)
          .subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe(resultBean -> {
            Log.i("APP# SignUpModel | signUp", "|" + resultBean.toPrettyJson());
            saveUserId(resultBean.getData().getUserNo());
            onResult(new Event.Builder(Event.RESULT).integer(Event.MEMBER_JOIN).build());
          }, e -> {
            Log.i("APP# SignUpModel | signUp", "|" + e.getLocalizedMessage());
            onResult(new Event.Builder(Event.ERROR).integer(Event.MEMBER_JOIN).string(e.getLocalizedMessage()).build());
          })
      );
    }
  }

  /**
   * 로그인
   */
  public void login() {
    disposable.add(
      new LifeplusAPIRepository().selectMember(new UserNoBean(getUserId()))
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(loginResultBean -> {
          Log.i("APP# SignUpModel | login", "| loginResultBean: " + loginResultBean.toPrettyJson());
          if (new LoginModuleParser().parse(loginResultBean)) {
            // 정상 처리 됐음
            onResult(new Event.Builder(Event.RESULT).integer(Event.MEMBER_LOGIN).build());
          }
          else {
            // 서버와 통신 완료 후 에러 리턴
            onResult(new Event.Builder(Event.ERROR).integer(Event.MEMBER_LOGIN).string(loginResultBean.toJson()).build());
          }
        }, e -> {
          // 서버와 통신이 되지 않은 에러
          onResult(new Event.Builder(Event.ERROR).integer(Event.MEMBER_LOGIN).string(e.getLocalizedMessage()).build());
        })
    );
  }

  /**
   * 필수 약관을 모두 동의 했는지 확인
   *
   * @return
   */
  public boolean isValidatedPolicy() {

    List<PolicyBean> agreeBean = getAgreeItems();
    if (null == agreeBean) {
      return false;
    }

    for (PolicyBean bean : agreeBean) {
      if (bean.isMandatory()) {
        if (false == bean.isChecked()) {
          return false;
        }
      }
    }

    return true;
  }

  /**
   * 동의한 약관 전송
   */
  public void sendPolicy() {

    PolicyConfirmRequestBean policyConfirmRequestBean = new PolicyConfirmRequestBean();

    List<PolicyBean> agreeBean = getAgreeItems();
    for (PolicyBean bean : agreeBean) {
      if (bean.isChecked()) {
        policyConfirmRequestBean.addBean(new PolicyVersionBean(bean.getType(), bean.getVersion()));
      }
    }

    disposable.add(
      new LifeplusAPIRepository().confirmPolicy(policyConfirmRequestBean)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(resultBean -> {
          onResult(new Event.Builder(Event.RESULT).integer(Event.POLICY_CONFIRM).build());
        }, e -> {
          onResult(new Event.Builder(Event.ERROR).integer(Event.POLICY_CONFIRM).string(e.getLocalizedMessage()).build());
        })
    );
  }
}
