package com.live;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.Field;

public class LiveTT {

    private final Context mContext;
    private final String TAG = "LiveTT";

    private final Handler mainHandler;
    private static final int SHOW = 0;
    private static final int HIDE = 1;
    private TNHandler tnHandler;

    private class TNHandler extends Handler {

        public TNHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SHOW:
//                    ALog.d(TAG, "toast show!");
                    break;
                case HIDE:
//                    ALog.d(TAG, "toast hide!");
                    show();
                    break;
            }
        }
    }


    private LiveTT(Context context) {
        mContext = context.getApplicationContext();
        mainHandler = new Handler(Looper.getMainLooper());
    }

    public static LiveTT makeTT(Context context) {
        return new LiveTT(context);
    }

    private final Runnable toastRun = new Runnable() {
        @Override
        public void run() {
            Toast toast = generatorToast();
            if (null != toast) {
                try {
                    toast.show();
                } catch (Throwable throwable) {
//                    ALog.e(TAG, "generatorToast E :" + Log.getStackTraceString(throwable));
                }
            }
        }
    };

    public void show() {
        if (mContext == null) {
            return;
        }

        if (!KpUtil.getInstance().isStartKpLive()) {
//            ALog.d(TAG, "KpLive isStartKpLive = false");
            KpUtil.getInstance().setStartLive(false);
            mainHandler.removeCallbacksAndMessages(null);
            tnHandler = null;
            nextTextView = null;
            return;
        }
        if (!KpUtil.getInstance().isStartKpLiveInScreenOnOrInScreenOff()) {
            if (!KpUtil.getInstance().isStartKpLiveInScreenOn(mContext)) {
                mainHandler.removeCallbacksAndMessages(null);
                tnHandler = null;
                nextTextView = null;
//                ALog.d(TAG, "KpLive startKpLive in ScreenOn but isScreenOn = false");
                return;
            }
        }
        mainHandler.removeCallbacksAndMessages(null);
        mainHandler.postDelayed(toastRun, 1000L);
    }

    public void show2() {
        if (mContext == null) {
            return;
        }

        if (!KpUtil.getInstance().isStartKpLive()) {
//            ALog.d(TAG, "KpLive isStartKpLive = false");
            KpUtil.getInstance().setStartLive(false);
            mainHandler.removeCallbacksAndMessages(null);
            tnHandler = null;
            nextTextView = null;
            return;
        }
        if (!KpUtil.getInstance().isStartKpLiveInScreenOnOrInScreenOff()) {
            if (!KpUtil.getInstance().isStartKpLiveInScreenOn(mContext)) {
                mainHandler.removeCallbacksAndMessages(null);
                tnHandler = null;
                nextTextView = null;
//                ALog.d(TAG, "KpLive startKpLive in ScreenOn but isScreenOn = false");
                return;
            }
        }
        mainHandler.removeCallbacksAndMessages(null);
        mainHandler.post(toastRun);
    }

    public void setError(boolean error) {
        isError = error;
    }

    boolean isError = false;

    private Toast generatorToast() {
        Toast toast = null;
        try {
            toast = new Toast(mContext);
            hookToastText(toast);
            hookToastDuration(toast);
            hookToastTNHandler(toast);
        } catch (Throwable e) {
            String s = Log.getStackTraceString(e);
//            ALog.e(TAG, "generatorToast E :" + s);
            isError = true;
        }
        if (isError) {
            return null;
        }
        return toast;
    }

    private static final String FIELD_M_TEXTVIEW = "mNextView";
    private static final String FIELD_M_TEXT= "mText";
    private static final String TOAST_CONTENT = "m";

    private TextView nextTextView;
    private void hookToastText(Toast toast) {
        try {
            if (Build.VERSION.SDK_INT <= 29) {
                if (nextTextView == null) {
                    nextTextView = new TextView(mContext);
                }
                nextTextView.setText(TOAST_CONTENT);
                @SuppressLint("SoonBlockedPrivateApi") Field textView = Toast.class.getDeclaredField(FIELD_M_TEXTVIEW);
                textView.setAccessible(true);
                textView.set(toast, nextTextView);
            } else {
                @SuppressLint("BlockedPrivateApi") Field text = Toast.class.getDeclaredField(FIELD_M_TEXT);
                text.setAccessible(true);
                text.set(toast, TOAST_CONTENT);
            }
        } catch (Exception e) {
//            ALog.e(TAG, "hookToastText e :" + e);
            isError = true;
        }
    }

    private static final String FIELD_M_DURA = "mDuration";
    private void hookToastDuration(Toast toast) {
        try {
            Field duration = Toast.class.getDeclaredField(FIELD_M_DURA);
            duration.setAccessible(true);
            duration.set(toast, Toast.LENGTH_LONG);
        } catch (Exception e) {
//            ALog.e(TAG, "hookToastDuration e :" + e);
            isError = true;
        }
    }

    private final Runnable showR = new Runnable() {
        @Override
        public void run() {
//            ALog.d(TAG, "toast show !");
        }
    };

    private final Runnable hideR = new Runnable() {
        @Override
        public void run() {
//            ALog.d(TAG, "toast hide!");
            show();
        }
    };

    private static final String FIELD_MTN = "mTN";
    private static final String CLASS_TOAST = "android.widget.Toast$TN";
    private static final String FIELD_MSHOW = "mShow";
    private static final String FIELD_MHIDE = "mHide";
    private static final String FIELD_MHANDLER = "mHandler";

    private void hookToastTNHandler(Toast toast) {
        try {
            @SuppressLint("SoonBlockedPrivateApi") Field mTnField = Toast.class.getDeclaredField(FIELD_MTN);
            mTnField.setAccessible(true);
            Object mTn = mTnField.get(toast);
            Class tnClass = Class.forName(CLASS_TOAST);
            if (Build.VERSION.SDK_INT < 25) {
                Field mShowField = tnClass.getDeclaredField(FIELD_MSHOW);
                mShowField.setAccessible(true);
                mShowField.set(mTn, showR);

                Field mHideField = tnClass.getDeclaredField(FIELD_MHIDE);
                mHideField.setAccessible(true);
                mHideField.set(mTn, hideR);
            } else {
                @SuppressLint("SoonBlockedPrivateApi") Field mHandlerField = tnClass.getDeclaredField(FIELD_MHANDLER);
                mHandlerField.setAccessible(true);

                if (null == tnHandler) {
                    tnHandler = new TNHandler(Looper.myLooper());
                }
                mHandlerField.set(mTn, tnHandler);
            }
        } catch (Exception e) {
//            ALog.e(TAG, "hookToastTNHandler e :" + e);
            isError = true;
        }
    }
}
