package com.kfzs.duanduan.datashare;

import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;

import com.kfzs.duanduan.data.graph.provider.current.Current;
import com.kfzs.duanduan.data.graph.provider.player.User;
import com.kfzs.duanduan.datashare.provider.KFZSDDProvider;
import com.kfzs.duanduan.datashare.provider.KFZSDDSQLiteOpenHelper;
import com.kfzs.duanduan.datashare.provider.session.SessionBean;
import com.kfzs.duanduan.datashare.provider.session.SessionContentValues;
import com.kfzs.duanduan.datashare.provider.session.SessionCursor;
import com.kfzs.duanduan.datashare.provider.session.SessionSelection;

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

/**
 * <pre>
 *     sinlov
 *
 *     /\__/\
 *    /`    '\
 *  ≈≈≈ 0  0 ≈≈≈ Hello world!
 *    \  --  /
 *   /        \
 *  /          \
 * |            |
 *  \  ||  ||  /
 *   \_oo__oo_/≡≡≡≡≡≡≡≡o
 *
 * </pre>
 * Created by sinlov on 17/2/21.
 */
public class KFZSDDContentSession {

    public static final int SUCCESS = 1;
    public static final int NOT_HAS_ANY_SESSION = 1 ^ 2;
    public static final int HEAD_SESSION_HAS_CHANGE_STOP_JOB = 1 ^ 3;
    public static final int CAN_NOT_FIND_QUERY_OUT_BY_KEY = 1 ^ 4;

    private static KFZSDDContentSession instance;
    private SessionBean saveSessionBean;
    private KFZSDDSQLiteOpenHelper openHelper;

    public boolean isHasHeadSession(Context ctx) {
        checkConfig(ctx);
        Current user = DDProviderHelper.getInstance().getLastUser(ctx);
        if (user != null) {
            return true;
        } else
            return false;
    }

    /**
     * if has not any head session will return true
     *
     * @param ctx {@link Context}
     * @return not change or change and empty head session
     */
    public boolean isHeadSessionChange(Context ctx) {
        if (saveSessionBean == null) {
            saveSessionBean = findOutHeadSession(ctx);
        }
        if (saveSessionBean != null) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * get save session it will refresh by {@link #findOutHeadSession(Context)}
     *
     * @return {@link SessionBean}
     */
    public SessionBean getSaveHeadSessionInMem() {
        if (saveSessionBean == null) {
            throw new NullPointerException("not has head session by head, just use findOutHeadSession()");
        }
        return saveSessionBean;
    }

    /**
     * return last update session or null, so you can use {@link #isHasHeadSession(Context)} first
     *
     * @param ctx {@link Context}
     * @return {@link SessionBean} or null
     *
     */
    @Deprecated
    public SessionBean findOutHeadSession(Context ctx) {

       /* private long mId;
        private String mAccount;
        private String mOpenId;
        private long mUpdateTime;
        private String mToken;
        private Integer mUid;
        private Integer mHash;*/
        Current lastUser = DDProviderHelper.getInstance().getLastUser(ctx);

        if (lastUser != null) {
            return new SessionBean(lastUser);
        }
        return null;

    }

    /**
     * change head session by account if success return 0
     * <br/>success return {@link #SUCCESS}
     * <br/>if has not any session return {@link #NOT_HAS_ANY_SESSION}
     * <br/>if account can find return {@link #CAN_NOT_FIND_QUERY_OUT_BY_KEY}
     *
     * @param ctx    {@link Context}
     * @param openID {@link String}
     * @return {@link #SUCCESS} or {@link #NOT_HAS_ANY_SESSION} or {@link #CAN_NOT_FIND_QUERY_OUT_BY_KEY}
     * @deprecated
     */
    public int changeHeadSession(Context ctx, String openID) {
        SessionSelection where = new SessionSelection();
        int count = where.count(ctx);
        if (count > 0) {
            where.openId(openID);
            ContentResolver contentResolver = ctx.getContentResolver();
            SessionCursor query = where.query(contentResolver);
            if (query == null) {
                throwSessionProviderConfigError();
            }
            if (query.getCount() == 0) {
                query.close();
                return NOT_HAS_ANY_SESSION;
            } else {
                query.moveToNext();
                SessionContentValues sessionContentValues = new SessionContentValues();
                sessionContentValues.putOpenId(query.getOpenId());
                sessionContentValues.putAccount(query.getAccount());
                Integer uid = query.getUid();
                sessionContentValues.putUid(uid);
                String token = query.getToken();
                sessionContentValues.putToken(token);
                long nowTime = System.currentTimeMillis();
                sessionContentValues.putUpdateTime(nowTime);
                String temp = query.getAccount() + uid + token;
                int hash = temp.hashCode();
                sessionContentValues.putHash(hash);
                contentResolver.update(sessionContentValues.uri(), sessionContentValues.values(), null, null);
                query.close();
                isHeadSessionChange(ctx);
                return SUCCESS;
            }
        } else {
            return CAN_NOT_FIND_QUERY_OUT_BY_KEY;
        }
    }

    /**
     * remove headSession by {@link #saveSessionBean} so, you can also use it after {@link #isHeadSessionChange(Context)} return false
     *
     * @param ctx {@link Context}
     * @return {@link #SUCCESS} or {@link #HEAD_SESSION_HAS_CHANGE_STOP_JOB} or {@link #CAN_NOT_FIND_QUERY_OUT_BY_KEY}
     */
    public int removeHeadSession(Context ctx) {

        boolean isSuccess = DDProviderHelper.getInstance().deleteCurrent(ctx);
        return isSuccess ? SUCCESS : CAN_NOT_FIND_QUERY_OUT_BY_KEY;
        /*boolean headSessionChange = isHeadSessionChange(ctx);
        if (headSessionChange) {
            return HEAD_SESSION_HAS_CHANGE_STOP_JOB;
        } else {
            String account = saveSessionBean.getAccount();
            SessionSelection where = new SessionSelection();
            ContentResolver contentResolver = ctx.getContentResolver();
            where.account(account);
            int delete = where.delete(contentResolver);
            if (delete == 1) {
                //TODO change
                findOutHeadSession(ctx);
                Integer hash = saveSessionBean.getHash();
                XMLShareSession.saveHeadHash(ctx, hash);
                return SUCCESS;
            } else {
                return CAN_NOT_FIND_QUERY_OUT_BY_KEY;
            }
        }*/
    }

    public void insertOrUpdateSession(Context ctx, String account, String openID, Integer uid, String token) {
        checkConfig(ctx);
        User user = new User();

        user.setMOpenId(openID);
        user.setMToken(token);
        user.setMUserName(account);
        user.setMUserId(String.valueOf(uid));
        user.setMUpdateTime(String.valueOf(System.currentTimeMillis()));

        DDProviderHelper.getInstance().addOrUpdateUser(ctx, user);

        DDProviderHelper.getInstance().setLastUser(ctx, new Current(user));
        isHeadSessionChange(ctx);

//
//        SessionContentValues sessionContentValues = new SessionContentValues();
//        sessionContentValues.putAccount(account);
//        sessionContentValues.putOpenId(openID);
//        sessionContentValues.putUid(uid);
//        sessionContentValues.putToken(token);
//        long nowTime = System.currentTimeMillis();
//        sessionContentValues.putUpdateTime(nowTime);
//        String temp = account + uid + token;
//        int hash = temp.hashCode();
//        sessionContentValues.putHash(hash);
//        SessionSelection where = new SessionSelection();
//        where.account(account);
//        ContentResolver contentResolver = ctx.getContentResolver();
//        SessionCursor query = where.query(contentResolver);
//        if (query == null) {
//            throwSessionProviderConfigError();
//        }
//        query.moveToNext();
//        if (query.getCount() == 0) {
//            contentResolver.insert(sessionContentValues.uri(), sessionContentValues.values());
//        } else {
//            if (query.getAccount().equals(account)) {
//                contentResolver.update(sessionContentValues.uri(), sessionContentValues.values(), null, null);
//            } else {
//                contentResolver.insert(sessionContentValues.uri(), sessionContentValues.values());
//            }
//        }
//        SessionBean sessionBean = new SessionBean();
//        sessionBean.setAccount(account);
//        sessionBean.setOpenId(openID);
//        sessionBean.setUpdateTime(nowTime);
//        sessionBean.setUid(uid);
//        sessionBean.setHash(hash);
//        sessionBean.setToken(token);
//        this.saveSessionBean = sessionBean;
//        query.close();

    }

    public List<User> checkOutAllUser(Context ctx) {
        return DDProviderHelper.getInstance().getUserList(ctx);

    }

    /**
     * remove all session and return delete session count
     *
     * @param ctx {@link Context}
     * @return count of delete session raw
     */
    public int clearAllSession(Context ctx) {
        SessionSelection sessionSelection = new SessionSelection();
        int count = sessionSelection.count(ctx);
        if (count > 0) {
            this.saveSessionBean = null;
            XMLShareSession.saveHeadHash(ctx, 0);
            return sessionSelection.delete(ctx);
        } else {
            this.saveSessionBean = null;
            XMLShareSession.saveHeadHash(ctx, 0);
            return 0;
        }
    }

    private void checkConfig(Context ctx) {
        String graphMeta;
        String dataShareMeta;
        openHelper = KFZSDDSQLiteOpenHelper.getInstance(ctx);
        try {
            ApplicationInfo info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(), PackageManager.GET_META_DATA);
            Bundle metaData = info.metaData;
            graphMeta = String.valueOf(metaData.get("DUANDUAN_GRAPH"));
            dataShareMeta = String.valueOf(metaData.get("DUANDUAN_DATASHARE"));
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            graphMeta = "";
            dataShareMeta = "";
        }
        String graph = BuildConfigSaver.getInstance().getGraph();
        if (!graphMeta.equals(graph)) {
            throw new IllegalArgumentException("DUANDUAN_GRAPH in Manifest: " + graphMeta + " |in BuildConfig:  " + graph + " | not same, please check config");
        }
        String dataShare = BuildConfigSaver.getInstance().getDatashare();
        if (!dataShareMeta.equals(dataShare)) {
            throw new IllegalArgumentException("DUANDUAN_DATASHARE in Manifest: " + dataShareMeta + " |in BuildConfig:  " + dataShare + " | not same, please check config");
        }
    }

    private void throwSessionProviderConfigError() {
        throw new IllegalArgumentException("Please check config!\nNow com.kfzs.duanduan.datashare.provider.KFZSDDProvider AUTHORITY is set: " + KFZSDDProvider.AUTHORITY + " maybe error!");
    }

    public static synchronized KFZSDDContentSession getInstance() {
        if (instance == null) {
            KFZSDDContentSession.instance = new KFZSDDContentSession();
        }
        return instance;
    }

    private KFZSDDContentSession() {
    }
}
