package com.kfzs.duanduan;

import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;

import com.kf.utils.ToastBuilder;
import com.kfzs.android.view.CompatActivity;
import com.sheep.gamegroup.util.ActivityManager;
import com.umeng.analytics.MobclickAgent;

import java.util.List;

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

    /**
     * auto TAG for mark subclass
     */
    protected String TAG;

    public static boolean isDebugMode = false;
    private static final int FINISH_BACK_STACK_THRESHOLD = 0;

    private FragmentManager fragmentManager = getSupportFragmentManager();
    private FragmentTransaction fragmentTransaction;
    private boolean isAddStack = false;
    /**
     * supper application see {@link KFZSApp}
     */
    protected KFZSApp app;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
//        StatusBarUtils.setColor(this, ThemeUtils.getInstance().getColorDark(), 0);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        super.onCreate(savedInstanceState);

        TAG = this.getClass().getCanonicalName();
        app = KFZSApp.getInstance();
    }

    /**
     * 不如注入方便，暂时这样用吧。。。
     *
     * @param id
     * @param <T>
     * @return
     */
    protected <T extends View> T findViewByIdT(int id) {
        return (T) super.findViewById(id);
    }


    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton) {
        addSupportFragment(containerViewId, fragment, null, isSupportBackButton);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton, Integer animIn, Integer animOut) {
        addSupportFragment(containerViewId, fragment, null, isSupportBackButton, animIn, animOut);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, String tag, boolean isSupportBackButton, String stackTag) {
        addSupportFragment(containerViewId, fragment, null, tag, isSupportBackButton, stackTag, null, null);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton, String stackTag) {
        addSupportFragment(containerViewId, fragment, null, null, isSupportBackButton, stackTag, null, null);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton) {
        addSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton, Integer animIn, Integer animOut) {
        addSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton, animIn, animOut);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton) {
        addSupportFragment(containerViewId, fragment, bundle, tag, isSupportBackButton, null);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton, String stackTag) {
        addSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton, stackTag);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, String tag, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
        addSupportFragment(containerViewId, fragment, null, tag, isSupportBackButton, stackTag, animIn, animOut);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
        addSupportFragment(containerViewId, fragment, null, null, isSupportBackButton, stackTag, animIn, animOut);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton, String stackTag) {
        addSupportFragment(containerViewId, fragment, bundle, tag, isSupportBackButton, stackTag, null, null);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
        addSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton, stackTag, animIn, animOut);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton, Integer animIn, Integer animOut) {
        addSupportFragment(containerViewId, fragment, bundle, tag, isSupportBackButton, null, animIn, animOut);
    }

    public void addSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
        if (null == fragment) {
            new Throwable("your fragment is null").printStackTrace();
            return;
        }
        fragmentTransaction = fragmentManager.beginTransaction();
        if (null != bundle) {
            fragment.setArguments(bundle);
        }
        fragmentTransaction.add(containerViewId, fragment, tag);
        if (null != animIn && null != animOut) {
            fragmentTransaction.setCustomAnimations(animIn, animOut);
        }
        if (isSupportBackButton) {
            fragmentTransaction.addToBackStack(stackTag);
            fragmentTransaction.commit();
            isAddStack = true;
        } else {
            removeChildFragment();
            isAddStack = false;
        }
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton) {
        replaceSupportFragment(containerViewId, fragment, null, isSupportBackButton);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton, Integer animIn, Integer animOut) {
        replaceSupportFragment(containerViewId, fragment, null, isSupportBackButton, animIn, animOut);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, String tag, boolean isSupportBackButton, String stackTag) {
        replaceSupportFragment(containerViewId, fragment, null, tag, isSupportBackButton, stackTag, null, null);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton, String stackTag) {
        replaceSupportFragment(containerViewId, fragment, null, null, isSupportBackButton, stackTag, null, null);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton) {
        replaceSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton, Integer animIn, Integer animOut) {
        replaceSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton, animIn, animOut);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton) {
        replaceSupportFragment(containerViewId, fragment, bundle, tag, isSupportBackButton, null);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton, String stackTag) {
        replaceSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton, stackTag);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, String tag, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
        replaceSupportFragment(containerViewId, fragment, null, tag, isSupportBackButton, stackTag, animIn, animOut);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
        replaceSupportFragment(containerViewId, fragment, null, null, isSupportBackButton, stackTag, animIn, animOut);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton, String stackTag) {
        replaceSupportFragment(containerViewId, fragment, bundle, tag, isSupportBackButton, stackTag, null, null);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
        replaceSupportFragment(containerViewId, fragment, bundle, null, isSupportBackButton, stackTag, animIn, animOut);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton, Integer animIn, Integer animOut) {
        replaceSupportFragment(containerViewId, fragment, bundle, tag, isSupportBackButton, null, animIn, animOut);
    }

    public void replaceSupportFragment(int containerViewId, BaseCompatFragment fragment, Bundle bundle, String tag, boolean isSupportBackButton, String stackTag, Integer animIn, Integer animOut) {
        if (null == fragment) {
            new Throwable("your fragment is null").printStackTrace();
        }
        fragmentTransaction = fragmentManager.beginTransaction();
        if (null != bundle) {
            assert fragment != null;
            fragment.setArguments(bundle);
        }
        if (null != animIn && null != animOut) {
            fragmentTransaction.setCustomAnimations(animIn, animOut);
        }
        fragmentTransaction.replace(containerViewId, fragment, tag);
        if (isSupportBackButton) {
            fragmentTransaction.addToBackStack(stackTag);
            fragmentTransaction.commit();
            isAddStack = true;
        } else {
            removeChildFragment();
            isAddStack = false;
        }
    }

    private void removeChildFragment() {
        fragmentManager.popBackStackImmediate();
        List<Fragment> childFragments = fragmentManager.getFragments();
        if (null != childFragments) {
            for (Fragment stackFragment : fragmentManager.getFragments()) {
                if (null != stackFragment) {
                    fragmentTransaction.remove(stackFragment);
                }
            }
        }
        fragmentTransaction.commit();
    }

    public void removeSupportFragment(BaseCompatFragment fragment) {
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.remove(fragment);
        fragmentTransaction.commit();
    }

    public void removeAllFragment() {
        int backStackEntryCount = fragmentManager.getBackStackEntryCount();
        if (backStackEntryCount > 0) {
            fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        }
    }

    public void hideSupportFragment(BaseCompatFragment fragment) {
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.hide(fragment);
        fragmentTransaction.commit();
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (isDebugMode) {
            Log.d(TAG, "isAddStack: " + isAddStack + " |BackStackEntryCount: " + fragmentManager.getBackStackEntryCount());
        }
        if (!isAddStack || FINISH_BACK_STACK_THRESHOLD == fragmentManager.getBackStackEntryCount()) {
            finish();
        }
        //TODO of synchronized way
        synchronized (this) {
        }
    }

    /**
     * show toast by string
     *
     * @param string toast string
     */
    protected void showToast(String string) {
        showToast(string, ToastBuilder.DEFAULT_TOAST_SINGLE);
    }


    /**
     * show toast by res
     *
     * @param string string resource id
     * @param tag    {@link ToastBuilder#DEFAULT_TOAST} or other
     */
    protected void showToast(String string, int tag) {
        ToastBuilder.make(app, string, tag);
    }

    /**
     * show toast by res
     *
     * @param strID string resource id
     */
    protected void showToast(int strID) {
        showToast(strID, ToastBuilder.DEFAULT_TOAST_SINGLE);
    }

    /**
     * show toast by res
     *
     * @param strID string resource id
     * @param tag   {@link ToastBuilder#DEFAULT_TOAST} or other
     */
    protected void showToast(int strID, int tag) {
        ToastBuilder.make(app, strID, tag);
    }
}
