/*
 * 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.lifeplus.bean.BlankBean;
import kr.co.zumo.app.lifeplus.bean.MobileAuthorizationBean;
import kr.co.zumo.app.lifeplus.bean.SignUpBean;
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.network.api.LifeplusAPIService;
import kr.co.zumo.app.lifeplus.util.AppUtil;
import kr.co.zumo.app.lifeplus.util.StringUtil;
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 {

  public static final int EVENT_BANNER = 824;
  public static final int EVENT_POLICY_REQUEST = 346;
  public static final int EVENT_POLICY_CONFIRM = 347;
  public static final int EVENT_JOINED = 735;

  protected CompositeDisposable disposable = new CompositeDisposable();

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

  // 회원 가입에 필요한 데이터
  protected SignUpBean signUpBean;

  private boolean isAuthorized = false;
  private String encryptedPin;
  protected MobileAuthorizationBean mobileAuthorizationBean;


  public SignUpModel() {

    signUpBean = new SignUpBean();

  }

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

    agreeItems = null;
    bannerItems = null;
    signUpBean = null;
    isAuthorized = false;
    encryptedPin = null;
    mobileAuthorizationBean = 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);
  }


  /**
   * 핀 저장
   *
   * @param pin
   */
  public void savePin(String pin) {
    try {
      encryptedPin = StringUtil.convertToSHA256(StringUtil.convertToMD5(pin));
      Log.i("APP# SignUpModel | savePin", "| pin: " + pin + ", encryptedPin: " + encryptedPin);
      getPreferences().setEncryptedPin(encryptedPin);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * 배너 요청;
   */
  public void requestBanners() {
    /*
     로컬에서 처리
     혜택 하나. 코인	서비스만 이용해도 코인을 드려요
혜택 둘. 쿠폰	코인을 쿠폰으로 교환하세요
혜택 셋. 쇼핑	구매/예약하면 추가 코인을 드려요

     */

    bannerItems = new ArrayList<>();
    bannerItems.add(new BannerBean(0, "혜택 하나", "코인 서비스만 이용해도 코인을 드려요"));
    bannerItems.add(new BannerBean(1, "혜택 둘", "쿠폰 코인을 쿠폰으로 교환하세요"));
    bannerItems.add(new BannerBean(2, "혜택 셋", "쇼핑 구매/예약하면 추가 코인을 드려요"));

    onResult(new Event.Builder(Event.RESULT).integer(EVENT_BANNER).build());
//
//    disposable.add(
//      new LifeplusAPIService().getBannerList(new BlankBean())
//        .subscribeOn(Schedulers.io())
//        .observeOn(AndroidSchedulers.mainThread())
//        .subscribe(resultBean -> {
//        Log.i("APP# SignUpModel | requestBanners", "|" + resultBean.toPrettyJson());
//
//        if (resultBean.isSuccess()) {
//          bannerItems = resultBean.getData();
//          onResult(new Event.Builder(Event.RESULT).integer(EVENT_BANNER).build());
//        }
//      }, e -> {
//        onError(e);
//      })
//    );
  }

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

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

  /**
   * 약관 리스트 요청
   */
  public void requestPolicy() {
    disposable.add(
      new LifeplusAPIService().getPolicyList(new BlankBean())
        .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 -> {
          onError(new Event.Builder(Event.ERROR).integer(EVENT_POLICY_REQUEST).build(), e);
        })
    );
  }

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

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

  /**
   * 모바일 인증 정보 반환
   *
   * @return
   */
  public MobileAuthorizationBean getMobileAuthorizationBean() {
    return mobileAuthorizationBean;
  }

  /**
   * 회원 가입 시작
   */
  public void signUp() {
    /*
     필수 항목 체크;
     */
    if (false == isAuthorized || null == mobileAuthorizationBean) {
      // 인증 안했음;
      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();
      // fixme 이메일을 입력하지 않았음
      bean.setEmailId("nothing@email.com");
      bean.setName(mobileAuthorizationBean.getName());

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

            // fixme 파싱 에러 발생!!! 임으로 성공 시킴;
            if (AppUtil.isDebug()) {
              saveUserId("_____________dummy_user_id______________");
              onResult(new Event.Builder(Event.RESULT).integer(EVENT_JOINED).build());
            }
            else {
              onError(new Event.Builder(Event.ERROR).integer(EVENT_JOINED).build(), e);
            }
          })
      );
    }
  }

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

    List<PolicyBean> agreeBean = getAgreeItems();

    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 LifeplusAPIService().confirmPolicy(policyConfirmRequestBean)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(resultBean -> {
          onResult(new Event.Builder(Event.RESULT).integer(EVENT_POLICY_CONFIRM).build());
        }, e -> {
          onError(new Event.Builder(Event.ERROR).integer(EVENT_POLICY_CONFIRM).build(), e);
        })
    );
  }
}
