package com.sheep.jiuyan.samllsheep.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;

import com.sheep.gamegroup.model.entity.AppUsage;
import com.sheep.gamegroup.model.util.AutoTaskListUtil;
import com.sheep.gamegroup.usage.AppUsageManager;
import com.sheep.gamegroup.util.LogUtil;
import com.sheep.gamegroup.util.TestUtil;
import com.sheep.gamegroup.util.TimeUtil;
import com.sheep.jiuyan.samllsheep.R;
import com.sheep.jiuyan.samllsheep.SheepApp;
import com.sheep.jiuyan.samllsheep.utils.SpUtils;

import java.util.Locale;
import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

/**
 * Created by realicing on 2018/5/8.
 * realicing@sina.com
 */
public class FloatService extends Service {
    private void stopTimer() {
        if (subscription != null) {
            subscription.unsubscribe();
        }
        subscription = null;
    }

    private Subscription subscription;

    private void startTimer() {
        if (subscription == null)
            subscription = Observable.interval(1_000L, TimeUnit.MILLISECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Action1<Long>() {
                        @Override
                        public void call(Long count) {
                            LogUtil.println("FloatService", "count", "=", count);

                            if (!TextUtils.isEmpty(SpUtils.getToken(SheepApp.getInstance())) &&!AutoTaskListUtil.getInstance().isEmpty()) {//登录情况下并且有应用自动审核任务才会记录
                                if(count % 60 == 0){
                                    AppUsageManager.getInstance().tryOpenLookAppUsageStatsPermisson(false);
                                }
                                try {
                                    AppUsageManager.getInstance().recordCurrentAppUsage();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                                if(isShowFloat) {
                                    Message message = handler.obtainMessage(1);
                                    message.obj = count;
                                    handler.sendMessage(message);
                                    LogUtil.println("FloatService", 1);
                                }
                            } else {
                                if(isShowFloat) {
                                    removeMessages();
                                    mHandler.sendEmptyMessage(OPERATION_HIDE);
                                    LogUtil.println("FloatService", 2);
                                }
                            }

                        }
                    }, new Action1<Throwable>() {
                        @Override
                        public void call(Throwable throwable) {
                            LogUtil.println("FloatService", "Throwable", "=", throwable.getMessage());
                        }
                    });
    }


    //不与Activity进行绑定.
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if(isShowFloat)
            createFloatView();
        startTimer();
    }
    private Handler handler = new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(Message msg) {
            if(isShowFloat) {
                try {
                    switch (msg.what) {
                        case 1:
                            onHandleMessage1();
                            break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    LogUtil.println("FloatService", 4);
                }
            }
        }

        private void onHandleMessage1() {
            LogUtil.println("FloatService", 3);
            AppUsage appUsage = new AppUsage();
            //更新悬浮窗
            long totalTimeInForeground = AppUsageManager.getInstance().getTotalTimeInForeground(appUsage);
            if(!AutoTaskListUtil.getInstance().hasTask(appUsage.getPackageName())){
                FloatService.this.removeMessages();
                mHandler.sendEmptyMessage(OPERATION_HIDE);
                LogUtil.println("FloatService", 5);
                return;
            }
            LogUtil.println("FloatService", 6);
            if(!isAdded){
                windowManager.addView(floatView, params);
                isAdded = true;
                LogUtil.println("FloatService", 7);
            }
            btn_floatView.setText(String.format(Locale.CHINA,"约运行%s",TimeUtil.getHours(totalTimeInForeground)));
            windowManager.updateViewLayout(floatView, params);
            LogUtil.println("FloatService", 8);
        }

    };
    @Override
    public void onDestroy() {
        super.onDestroy();
        removeMessages();
        if (floatView != null) {
            try {
                if(isAdded)
                    windowManager.removeViewImmediate(floatView);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        stopTimer();
    }

//    public static final String OPERATION = "operation";
    public static final int OPERATION_SHOW = 100;
    public static final int OPERATION_HIDE = 101;

    private static final int HANDLE_CHECK_ACTIVITY = 200;

    private boolean isAdded = false; // 是否已增加悬浮窗
    private WindowManager windowManager;
    private WindowManager.LayoutParams params;
    private View floatView;
    private TextView btn_floatView;


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(isShowFloat) {
            if (intent != null) {
                if (intent.getBooleanExtra("isShow", true)) {
                    mHandler.sendEmptyMessageDelayed(OPERATION_SHOW, 1000L);
                } else {
                    removeMessages();
                    mHandler.sendEmptyMessage(OPERATION_HIDE);
                }
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }
    private void removeMessages(){
        if(isShowFloat) {
            mHandler.removeMessages(OPERATION_HIDE);
            mHandler.removeMessages(OPERATION_SHOW);
        }
    }

    private Handler mHandler = new TwHandler(this);

    static class TwHandler extends Handler {
        TwHandler(FloatService service) {
            this.service = service;
        }

        FloatService service;

        @Override
        public void handleMessage(Message msg) {
            if(service.isShowFloat) {
                switch (msg.what) {
                    case OPERATION_SHOW:
                        if (!service.isAdded) {
                            try {
//                            service.floatView.setAlpha(1.0f);
//                            windowManager.updateViewLayout(service.floatView, params);
                                service.windowManager.addView(service.floatView, service.params);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            service.isAdded = true;
                        }
                        break;
                    case OPERATION_HIDE:
                    case HANDLE_CHECK_ACTIVITY:
                        if (service.isAdded) {
                            try {
//                            service.floatView.setAlpha(0.0f);
//                            windowManager.updateViewLayout(service.floatView, params);
                                service.windowManager.removeViewImmediate(service.floatView);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            service.isAdded = false;
                        }
                        break;
                }
            }
        }
    }
    private boolean canTouchWindow = false;//是否可以操作悬浮窗
    private boolean isShowFloat = TestUtil.isTest();//是否显示悬浮窗

    public void setCanTouchWindow(boolean canTouchWindow) {
        this.canTouchWindow = canTouchWindow;
    }

    /**
     * 创建悬浮窗
     */
    private void createFloatView() {
        LayoutInflater inflater = LayoutInflater.from(getApplication());
//        //获取浮动窗口视图所在布局.
        floatView = inflater.inflate(R.layout.float_window, null);
        btn_floatView = floatView.findViewById(R.id.float_tv);

        windowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
        params = new WindowManager.LayoutParams();

        // 设置window type
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){//6.0
//            params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
//        }else {
//            params.type =  WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
//        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //  大于等于 24 即为 7.0 及以上执行内容
            Log.e("qx", "7.0");
            params.type = WindowManager.LayoutParams.TYPE_PHONE; // 7.1
        } else {
            //  低于 24 即为 7.0 以下执行内容
            params.type = WindowManager.LayoutParams.TYPE_TOAST;   // 4.4
            Log.e("qx", "4.4");

        }
        /*
         * 如果设置为params.type = WindowManager.LayoutParams.TYPE_PHONE; 那么优先级会降低一些,
         * 即拉下通知栏不可见
         */

        params.format = PixelFormat.RGBA_8888; // 设置图片格式，效果为背景透明

        if(canTouchWindow) {
            // 设置Window flag
            params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
            // 设置悬浮窗的Touch监听
            floatView.setOnTouchListener(new View.OnTouchListener() {
                int lastX, lastY;
                int paramX, paramY;
                private boolean isMove = false;
                private long downTime = 0;

                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            isMove = false;
                            downTime = System.currentTimeMillis();
                            lastX = (int) event.getRawX();
                            lastY = (int) event.getRawY();
                            paramX = params.x;
                            paramY = params.y;
                            break;
                        case MotionEvent.ACTION_MOVE:
                            int dx = (int) event.getRawX() - lastX;
                            int dy = (int) event.getRawY() - lastY;
                            params.x = paramX + dx;
                            params.y = paramY + dy;
                            // 更新悬浮窗位置
                            windowManager.updateViewLayout(floatView, params);
                            isMove = true;
                            break;
                        case MotionEvent.ACTION_UP:
                            if(!isMove && System.currentTimeMillis()-downTime < 1000L){//没有移动过并且小于1秒就弹起来就点击
                                v.performClick();
                            }
                            isMove = false;
                            break;
                    }
                    return false;
                }
            });
        } else {
            /*
             * 下面的flags属性的效果形同“锁定”。 悬浮窗不可触摸，不接受任何事件,同时不影响后面的事件响应。
             */
            params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
        }

        // 设置悬浮窗的长得宽
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.gravity = Gravity.START | Gravity.BOTTOM;
    }
}
