package com.qianmi.hardwarekit.sunmi.dsd;

import android.content.Intent;
import android.os.Build;
import android.os.Environment;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;

import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import sunmi.ds.DSKernel;
import sunmi.ds.FilesManager;
import sunmi.ds.SF;
import sunmi.ds.callback.IConnectionCallback;
import sunmi.ds.callback.IReceiveCallback;
import sunmi.ds.callback.ISendCallback;
import sunmi.ds.callback.QueryCallback;
import sunmi.ds.data.DSData;
import sunmi.ds.data.DSFile;
import sunmi.ds.data.DSFiles;
import sunmi.ds.data.DataPacket;


/**
 * Created by cyz.aoj on 2017/1/16.
 */
public class DsdModule extends ReactContextBaseJavaModule {

    private FilesManager mFilesManager = FilesManager.getInstance();
    private String model = SystemProperties.get("ro.product.model");


    private IConnectionCallback connectionCallback = new IConnectionCallback() {
        private boolean isRestart = false;

        @Override
        public void onDisConnect() {
            create();
            isRestart = true;
            // Toast.makeText(getCurrentActivity(), "断开连接!", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onConnected(ConnState arg0) {
            switch (arg0) {
                case AIDL_CONN:
                    // Toast.makeText(getCurrentActivity(), "与本地service连接正常!", Toast.LENGTH_LONG).show();
                    break;
                case VICE_SERVICE_CONN:
                    // Toast.makeText(getCurrentActivity(), "与副屏service连接正常!", Toast.LENGTH_LONG).show();
                    break;
                case VICE_APP_CONN:
                    // Toast.makeText(getCurrentActivity(), "与副屏APP连接正常!", Toast.LENGTH_LONG).show();
                    DataPacket packet2 = UPacketFactory.remove_folders(DSKernel.getDSDPackageName(), Environment.getExternalStorageDirectory().getAbsolutePath() + "/HCService/" + getReactApplicationContext().getPackageName().replace(".", "_"), new ISendCallback() {
                        @Override
                        public void onSendSuccess(long taskId) {
                            if (isRestart) {
                                startDsdWebApp();
                                isRestart = false;
                            }
                        }

                        @Override
                        public void onSendFail(int errorId, String errorInfo) {
                            if (isRestart) {
                                startDsdWebApp();
                                isRestart = false;
                            }
                        }

                        @Override
                        public void onSendProcess(long totle, long sended) {
                        }
                    });

                    mDSKernel.sendCMD(packet2);


                    break;
                default:
                    break;
            }
        }
    };

    private IReceiveCallback receiveCallback = new IReceiveCallback() {
        @Override
        public void onReceiveData(DSData data) {
        }

        @Override
        public void onReceiveFile(DSFile file) {
        }

        @Override
        public void onReceiveFiles(DSFiles files) {
        }

        @Override
        public void onReceiveCMD(DSData cmd) {
        }
    };

    private DSKernel mDSKernel;


    DsdModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Override
    public String getName() {
        return "DsdModule";
    }

    @ReactMethod
    public void create() {
        if ("t1host".equalsIgnoreCase(model)) {
            mDSKernel = DSKernel.newInstance();
            mDSKernel.init(getReactApplicationContext(), connectionCallback);
            mDSKernel.addReceiveCallback(receiveCallback);//添加监听
        }

    }

    @ReactMethod
    protected void destroy() {
        if ("t1host".equalsIgnoreCase(model)) {
            if (null != mDSKernel) {
                mDSKernel.onDestroy();
            }
        }

    }

    /**
     * 2.设备的model；可以为'V1'，'M1-L'等。
     *
     * @return
     */
    @ReactMethod
    public void model(Promise promise) {
        WritableMap map = Arguments.createMap();
        map.putString("value", SystemProperties.get("ro.product.model"));
        promise.resolve(map);
    }

    /**
     * 设备的brand值；通常为'SUNMI'。
     *
     * @return
     */
    @ReactMethod
    public void brand(Promise promise) {
        WritableMap map = Arguments.createMap();
        map.putString("value", SystemProperties.get("ro.product.brand"));
        promise.resolve(map);
    }

    /**
     * 获取设备SN号；
     */
    @ReactMethod
    public void getSN(Promise promise) {
        String SN;
        if (Build.VERSION.SDK_INT >= 26) {
        // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // SN = Build.getSerial();
            SN = ""; // rn 0.46.4 之前无法调试; 这里先注释掉
        } else {
            SN = Build.SERIAL;
        }
        Log.d("QianmiPrint:getSN", SN);
        WritableMap map = Arguments.createMap();
        map.putString("value", SN);
        promise.resolve(map);
    }

    //===================================web view========================================

    /**
     * 启动副屏幕为一个webView activity
     */
    @ReactMethod
    public void startDsdWebApp() {
        Intent intent = new Intent(getReactApplicationContext(), DsdWebActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getReactApplicationContext().startActivity(intent);
    }

    //===================================web view========================================

    /**
     * 启动app
     *
     * @param packageName
     */
    @ReactMethod
    public void startDsdApp(final String packageName) {
        if ("t1host".equalsIgnoreCase(model)) {
            DataPacket dsPacket = UPacketFactory.buildOpenApp(packageName, null);
            Log.d(getClass().getSimpleName(), "startDsdApp:" + packageName);
            mDSKernel.sendCMD(dsPacket);
        }
    }

    /**
     * 检查是否正常
     */
    @ReactMethod
    public void checkConnection() {
        mDSKernel.checkConnection();
    }

    /**
     * 发送文本
     *
     * @param packageName package
     * @param text        内容
     */
    @ReactMethod
    public void sendText(String packageName, String text) {

        if ("t1host".equalsIgnoreCase(model)) {
            DataPacket packet = UPacketFactory.buildShowText(packageName, text, null);
            Log.d(getClass().getSimpleName(), "packageName:" + packageName + "   text:" + text);
            mDSKernel.sendData(packet);
        }

    }

    /**
     * 发送文件到副屏幕
     *
     * @param packageName
     * @param filePath
     * @param promise
     */
    @ReactMethod
    public void sendFile(final String packageName, final String filePath, final Promise promise) {
        if ("t1host".equalsIgnoreCase(model)) {
            DataPacket dsPacket = UPacketFactory.buildFilePacket(packageName, filePath, new ISendCallback() {
                @Override
                public void onSendSuccess(long taskId) {
                    Log.d(getClass().getSimpleName(), "sendFile.onSendSuccess -> packageName:" + packageName + "   text:" + filePath + "    taskId:" + String.valueOf(taskId));
                    WritableMap map = Arguments.createMap();
                    map.putString("taskId", String.valueOf(taskId));
                    promise.resolve(map);
                }

                @Override
                public void onSendFail(int errorId, String errorInfo) {
                    Log.d(getClass().getSimpleName(), "sendFile.onSendFail -> packageName:" + packageName + "   errorId:" + errorId + "    errorInfo:" + errorInfo);
                    promise.reject(String.valueOf(errorId), errorInfo);
                }

                @Override
                public void onSendProcess(long totle, long sended) {
                    Log.d(getClass().getSimpleName(), "sendFile.onSendProcess -> packageName:" + packageName + "   totle:" + totle + "    sended:" + sended);
                }
            });
            mDSKernel.sendCMD(dsPacket);
        } else {
            promise.reject("-1");

        }

    }

    /**
     * 文件写入sd卡
     *
     * @param text
     * @param promise
     */
    @ReactMethod
    public void toFile(String text, Promise promise) {
        if (TextUtils.isEmpty(text)) {
            promise.reject("-1", "text is empty!!!");
            return;
        }
        if ("t1host".equalsIgnoreCase(model)) {
            if (isSdCardExist()) {
                WritableMap map = Arguments.createMap();
                File file = new File(getReactApplicationContext().getExternalFilesDir("dsd"), "index.html");
                try {
                    if (!file.exists()) {
                        if (!file.createNewFile()) {
                            Log.d(getClass().getSimpleName(), "File createNewFile failure!!!");
                            promise.reject("-1", "File createNewFile failure!!!");
                            return;
                        }
                    }

                    FileOutputStream fos = new FileOutputStream(file);
                    byte[] buffer = text.getBytes();
                    fos.write(buffer, 0, buffer.length);
                    fos.flush();
                    fos.close();
                    map.putString("value", file.getAbsolutePath());
                    promise.resolve(map);
                } catch (IOException e) {
                    Log.d(getClass().getSimpleName(), e.getLocalizedMessage());
                    promise.reject("-1", e.getLocalizedMessage());
                }
            }
        } else {
            promise.reject("-1", "text is empty!!!");
        }

    }

    private boolean isSdCardExist() {
        return Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED);
    }
}
