package kr.co.hanwha.hifive.admin.network;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import java.util.HashMap;

import kr.co.hanwha.hifive.BuildConfig;
import kr.co.hanwha.hifive.HFApplication;
import kr.co.hanwha.hifive.admin.network.model.AdminCodeRoot;
import kr.co.hanwha.hifive.admin.network.model.AdminMemberDetailRoot;
import kr.co.hanwha.hifive.admin.network.model.AdminMemberRoot;
import kr.co.hanwha.hifive.admin.network.model.AdminMemberTaskRoot;
import kr.co.hanwha.hifive.admin.network.model.AdminVersionCvRoot;
import kr.co.hanwha.hifive.data.model.BaseData;
import kr.co.hanwha.hifive.data.model.UpdateData;
import kr.co.hanwha.hifive.network.hanwha.HanwhaNetworkCallback;
import kr.co.hanwha.hifive.network.hanwha.HanwhaNetworkClient;
import kr.co.hanwha.hifive.network.hanwha.HanwhaNetworkError;
import kr.co.hanwha.hifive.util.HFCommonUtil;
import kr.co.hanwha.hifive.util.HFInfoUtil;

/**
 * Created by sanghoonkwon on 2018. 3. 9..
 */

public class AdminNetworkUtil {
    protected final String BASE_URL = (HFApplication.SERVER == HFApplication.SERVER_TYPE.REAL ? BuildConfig.REAL_URL :
            (HFApplication.SERVER == HFApplication.SERVER_TYPE.DEV ? BuildConfig.DEV_URL : BuildConfig.LOCAL_URL));

    private final int RESULT_SUCCESS = 0;

    /**************************************************
     * 멤버 목록
     **************************************************/
    protected final String MEMBERS_SEARCH_HR = BASE_URL + "/members/search/hr";
    /**************************************************
     * 멤버 상세 정보
     **************************************************/
    protected final String MEMBERS_GET_DETAILS_HR = BASE_URL + "/members/get/details/hr";
    /**************************************************
     * 멤버 - RESET PASSWORD
     **************************************************/
    protected final String MEMBERS_UPDATE_PASSWORD = BASE_URL + "/members/update/password";
    /**************************************************
     * 멤버 - RESET SIMPLE PASSWORD
     **************************************************/
    protected final String MEMBERS_DELETE_AUTHCODE = BASE_URL + "/members/delete/authcode";
    /**************************************************
     * 멤버 - TASK 목록 조회
     **************************************************/
    protected final String MEMBERS_GET_TASKS = BASE_URL + "/members/get/tasks";
    /**************************************************
     * 멤버 - 등록 / 수정
     **************************************************/
    protected final String MEMBERS_ADDUP = BASE_URL + "/members/addup";
    /**************************************************
     * 업데이트 확인
     **************************************************/
    protected final String APP_UPDATE = BASE_URL + "/app/update";
    /**************************************************
     * 버전 정보 목록 조회
     **************************************************/
    protected final String APP_CV_GET = BASE_URL + "/app/cv/get";
    /**************************************************
     * 버전 정보 수정
     **************************************************/
    protected final String APP_CV_UPDATE = BASE_URL + "/app/cv/update";
    /**************************************************
     * 버전 정보 등록
     **************************************************/
    protected final String APP_CV_ADD = BASE_URL + "/app/cv/add";
    /**************************************************
     * 버전 정보 삭제
     **************************************************/
    protected final String APP_CV_DELETE = BASE_URL + "/app/cv/delete";
    /**************************************************
     * 코드 조회
     **************************************************/
    protected final String APP_GET_CODES = BASE_URL + "/app/get/codes";


    private final String PARAM_ENCRYPTION_MEMBER_ID = "encryption_member_id";
    private final String PARAM_MEMBER_ID = "member_id";
    private final String PARAM_PASSWORD = "password";
    private final String PARAM_LOGIN_ID = "login_id";
    private final String PARAM_ID = "id";
    private final String PARAM_PLATFORM_TYPE = "platform_type";
    private final String PARAM_RELEASED_AT = "released_at";
    private final String PARAM_VERSION = "version";
    private final String PARAM_STRING_BUNDLE = "string_bundle";
    private final String PARAM_IS_FORCED = "is_forced";
    private final String PARAM_UPDATE_NOTICE = "update_notice";
    private final String PARAM_UPDATE_URL = "update_url";

    /**
     * 전체 멤버 목록 조회
     *
     * @param context              Context
     * @param encryption_member_id 암호화된 멤버 ID
     * @param callback             CALLBACK
     */
    public void requestMemberList(@NonNull Context context, @NonNull String encryption_member_id, @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = MEMBERS_SEARCH_HR;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PARAM_ENCRYPTION_MEMBER_ID, encryption_member_id);

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getDefaultHeader(context), map, AdminMemberRoot.class, mCommonHanwhaNetworkCallback);
    }

    /**
     * 멤버 상세 조회
     *
     * @param context   Context
     * @param member_id 멤버 ID
     * @param callback  CALLBACK
     */
    public void requestMemberDetail(@NonNull Context context, @NonNull int member_id, @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = MEMBERS_GET_DETAILS_HR;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PARAM_MEMBER_ID, member_id);

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getDefaultHeader(context), map, AdminMemberDetailRoot.class, mCommonHanwhaNetworkCallback);
    }

    /**
     * 멤버 - 등록 / 수정
     *
     * @param context   Context
     * @param member_id 멤버 ID
     * @param callback  CALLBACK
     */
    public void requestMemberModify(@NonNull Context context, @NonNull int member_id, @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = MEMBERS_ADDUP;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PARAM_MEMBER_ID, member_id);

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getDefaultHeader(context), map, AdminMemberDetailRoot.class, mCommonHanwhaNetworkCallback);
    }

    /**
     * 비밀번호 재설정
     *
     * @param context   Context
     * @param member_id 멤버 ID
     * @param callback  CALLBACK
     */
    public void requestMemberResetPassword(@NonNull Context context, @NonNull int member_id, @NonNull String new_password, @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = MEMBERS_UPDATE_PASSWORD;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PARAM_MEMBER_ID, member_id);
        map.put(PARAM_PASSWORD, new_password);

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getDefaultHeader(context), map, BaseData.class, mCommonHanwhaNetworkCallback);
    }

    /**
     * 간편 비밀번호 초기화
     *
     * @param context   Context
     * @param member_id 멤버 ID
     * @param callback  CALLBACK
     */
    public void requestMemberResetSimplePassword(@NonNull Context context, @NonNull int member_id, @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = MEMBERS_DELETE_AUTHCODE;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PARAM_MEMBER_ID, member_id);

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getDefaultHeader(context), map, BaseData.class, mCommonHanwhaNetworkCallback);
    }

    /**
     * 멤버 TASK 목록 조회
     *
     * @param context   Context
     * @param member_id 멤버 ID
     * @param callback  CALLBACK
     */
    public void requestMemberTaskList(@NonNull Context context, @NonNull int member_id, @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = MEMBERS_GET_TASKS;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PARAM_MEMBER_ID, member_id);

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getDefaultHeader(context), map, AdminMemberTaskRoot.class, mCommonHanwhaNetworkCallback);
    }

    /**
     * 최신 업데이트 버전 조회 (iOS)
     *
     * @param context  Context
     * @param callback 콜백
     */
    public void requestCheckUpdateIos(@NonNull Context context, @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = APP_UPDATE;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PARAM_LOGIN_ID, "");

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getIosHeader(context), map, UpdateData.class, mCommonHanwhaNetworkCallback);
    }

    /**
     * 최신 업데이트 버전 조회 (Android)
     *
     * @param context  Context
     * @param callback 콜백
     */
    public void requestCheckUpdateAndroid(@NonNull Context context, @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = APP_UPDATE;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PARAM_LOGIN_ID, "");

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getDefaultHeader(context), map, UpdateData.class, mCommonHanwhaNetworkCallback);
    }

    /**
     * 버전 정보 목록 조회
     *
     * @param context              Context
     * @param encryption_member_id 암호화된 멤버 고유 ID
     * @param callback             콜백
     */
    public void requestClientVersionList(@NonNull Context context, @NonNull String encryption_member_id, @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = APP_CV_GET;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PARAM_ENCRYPTION_MEMBER_ID, encryption_member_id);

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getDefaultHeader(context), map, AdminVersionCvRoot.class, mCommonHanwhaNetworkCallback);
    }

    /**
     * 버전 정보 수정
     *
     * @param context              Context
     * @param encryption_member_id 암호화된 멤버 고유 ID
     * @param id
     * @param platform_type
     * @param released_at
     * @param version
     * @param string_bundle
     * @param is_forced
     * @param update_notice
     * @param update_url
     * @param callback             콜백
     */
    public void requestClientVersionUpdate(@NonNull Context context,
                                           @NonNull String encryption_member_id,
                                           @NonNull int id,
                                           @NonNull int platform_type,
                                           @NonNull String released_at,
                                           @NonNull String version,
                                           @Nullable String string_bundle,
                                           @NonNull boolean is_forced,
                                           @NonNull String update_notice,
                                           @NonNull String update_url,
                                           @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = APP_CV_UPDATE;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PARAM_ENCRYPTION_MEMBER_ID, encryption_member_id);
        map.put(PARAM_ID, id);
        map.put(PARAM_PLATFORM_TYPE, platform_type);
        map.put(PARAM_RELEASED_AT, released_at);
        map.put(PARAM_VERSION, version);
        map.put(PARAM_STRING_BUNDLE, string_bundle);
        map.put(PARAM_IS_FORCED, is_forced);
        map.put(PARAM_UPDATE_NOTICE, update_notice);
        map.put(PARAM_UPDATE_URL, update_url);

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getDefaultHeader(context), map, BaseData.class, mCommonHanwhaNetworkCallback);
    }

    /**
     * 버전 정보 등록
     *
     * @param context              Context
     * @param encryption_member_id 암호화된 멤버 고유 ID
     * @param platform_type
     * @param released_at
     * @param version
     * @param string_bundle
     * @param is_forced
     * @param update_notice
     * @param update_url
     * @param callback             콜백
     */
    public void requestClientVersionAdd(@NonNull Context context,
                                        @NonNull String encryption_member_id,
                                        @NonNull int platform_type,
                                        @NonNull String released_at,
                                        @NonNull String version,
                                        @Nullable String string_bundle,
                                        @NonNull boolean is_forced,
                                        @NonNull String update_notice,
                                        @NonNull String update_url,
                                        @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = APP_CV_ADD;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PARAM_ENCRYPTION_MEMBER_ID, encryption_member_id);
        map.put(PARAM_PLATFORM_TYPE, platform_type);
        map.put(PARAM_RELEASED_AT, released_at);
        map.put(PARAM_VERSION, version);
        map.put(PARAM_STRING_BUNDLE, string_bundle);
        map.put(PARAM_IS_FORCED, is_forced);
        map.put(PARAM_UPDATE_NOTICE, update_notice);
        map.put(PARAM_UPDATE_URL, update_url);

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getDefaultHeader(context), map, BaseData.class, mCommonHanwhaNetworkCallback);
    }

    /**
     * 버전 정보 삭제
     *
     * @param context              Context
     * @param encryption_member_id 암호화된 멤버 고유 ID
     * @param id                   버전 ID
     * @param callback             콜백
     */
    public void requestClientVersionDelete(@NonNull Context context,
                                           @NonNull String encryption_member_id,
                                           @NonNull int id,
                                           @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = APP_CV_DELETE;
        HashMap<String, Object> map = new HashMap<>();
        map.put(PARAM_ENCRYPTION_MEMBER_ID, encryption_member_id);
        map.put(PARAM_ID, id);

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getDefaultHeader(context), map, BaseData.class, mCommonHanwhaNetworkCallback);
    }

    /**
     * 전체 코드 목록 조회
     *
     * @param context  Context
     * @param callback 콜백
     */
    public void requestCodeList(@NonNull Context context,
                                @Nullable HanwhaNetworkCallback callback) {
        HanwhaNetworkClient.REST rest = HanwhaNetworkClient.REST.POST;
        String url = APP_GET_CODES;
        HashMap<String, Object> map = new HashMap<>();

        HanwhaNetworkClient client = new HanwhaNetworkClient();
        mHanwhaNetworkCallback = callback;
        client.request(context, rest, url, getDefaultHeader(context), map, AdminCodeRoot.class, mCommonHanwhaNetworkCallback);
    }

    /**************************************************
     * HanwhaNetworkCallback
     **************************************************/
    private HanwhaNetworkCallback mHanwhaNetworkCallback = null;
    HanwhaNetworkCallback mCommonHanwhaNetworkCallback = new HanwhaNetworkCallback() {
        @Override
        public void onSuccess(Object response) {
            if (mHanwhaNetworkCallback != null) {
                if (response != null && response instanceof BaseData) {
                    BaseData baseData = (BaseData) response;
                    if (baseData != null) {
                        if (baseData.getRtn_code() == RESULT_SUCCESS) {
                            mHanwhaNetworkCallback.onSuccess(response);
                        } else {
                            mHanwhaNetworkCallback.onFailure(new HanwhaNetworkError(baseData.getRtn_code(), baseData.getRtn_message()));
                        }
                    } else {
                        mHanwhaNetworkCallback.onFailure(new HanwhaNetworkError());
                    }
                } else {
                    mHanwhaNetworkCallback.onFailure(new HanwhaNetworkError());
                }
            }
        }

        @Override
        public void onFailure(HanwhaNetworkError error) {
            if (mHanwhaNetworkCallback != null) mHanwhaNetworkCallback.onFailure(error);
        }

        @Override
        public void onPreExecute() {
            if (mHanwhaNetworkCallback != null) mHanwhaNetworkCallback.onPreExecute();
        }

        @Override
        public void onPostExecute() {
            if (mHanwhaNetworkCallback != null) mHanwhaNetworkCallback.onPostExecute();
        }
    };

    /**************************************************
     * Header
     **************************************************/

    private final String CONTENT_TYPE = "Content-Type";
    private final String USER_AGENT = "User-Agent";
    private final String USER_TYPE = "User-Type";

    private HashMap<String, String> getIosHeader(Context context) {
        HashMap header = new HashMap();
        header.put(CONTENT_TYPE, "application/json");
        header.put(USER_AGENT, "iPhone/10.0.0" + " " + "DCA/0.0.0");
        header.put(USER_TYPE, HFInfoUtil.getDepartmentValue(context));
        return header;
    }

    private HashMap<String, String> getDefaultHeader(Context context) {
        HashMap header = new HashMap();
        header.put(CONTENT_TYPE, "application/json");
        header.put(USER_AGENT, getOsVersion() + " " + "DCA/0.0.0");
        header.put(USER_TYPE, HFInfoUtil.getDepartmentValue(context));
        return header;
    }

    private String getOsVersion() {
        return "Android/" + HFCommonUtil.getDeviceOsVersion();
    }
}
