package com.xypower.mpapp;

import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.FileObserver;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.StrictMode;

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.SystemClock;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;

import com.dev.devapi.api.SysApi;
import com.xypower.common.CameraUtils;
import com.xypower.common.MicroPhotoContext;
import com.xypower.mpapp.databinding.ActivityMainBinding;
import com.xypower.mpapp.utils.LocationUtil;
import com.xypower.mpapp.utils.RandomReader;


import java.io.File;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity extends AppCompatActivity {
    public static final String TAG = "MPLOG";
    private static int MY_PERMISSIONS_REQUEST_FOREGROUND_SERVICE = 100;

    // Used to load the 'microphoto' library on application startup.

    private ActivityMainBinding binding;

    private Messenger mMessenger = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            int activeSubId = SubscriptionManager.getActiveDataSubscriptionId();
            if (activeSubId == -1) {
                MicroPhotoContext.selectSimCard(getApplicationContext(), 1);
            }
        }

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        // getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

        ActionBar actionBar = getSupportActionBar();

        Date date = new Date(BuildConfig.BUILD_TIMESTAMP);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        actionBar.setTitle(actionBar.getTitle().toString() + " v" + MicroPhotoContext.getVersionName(getApplicationContext()) + "  " + sdf.format(date));

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        initListener();

        Context appContext = getApplicationContext();
        String appPath = MicroPhotoContext.buildMpAppDir(appContext);
        File appPathFile = new File(appPath);
        if (!appPathFile.exists()) {
            try {
                appPathFile.mkdirs();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        if (!MicroPhotoContext.hasMpAppConfig(appContext)) {

            String mstPath = MicroPhotoContext.buildMasterAppDir(appContext);
            File mstPathFile = new File(mstPath);
            File mpdataFile = new File(mstPathFile, "mpdata");

            if (mpdataFile.exists()) {
                File dataFile = new File(appPathFile, "data");
                if (dataFile.exists()) {
                    try {
                        dataFile.delete();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }

                try {
                    mpdataFile.renameTo(dataFile);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }

        Intent intent = getIntent();
        final int noDelay = intent.getIntExtra("noDelay", 0);
        int rebootFlag = intent.getIntExtra("reboot", 0);
        String reason = intent.getStringExtra("reason");
        if (!TextUtils.isEmpty(reason)) {
            Log.w(TAG, "App Started with reason: " + reason);
        }
        if (rebootFlag == 1) {
            Log.i(TAG, "After Reboot");
        }

        Log.d(TAG, "MainActivity: reboot=" + rebootFlag + " noDelay=" + noDelay);



        final MicroPhotoContext.AppConfig appConfig = MicroPhotoContext.getMpAppConfig(appContext);
        if (TextUtils.isEmpty(appConfig.cmdid)) {
            appConfig.cmdid = MicroPhotoService.getSerialNumber();
            binding.cmdid.setText(appConfig.cmdid);
        } else {
            binding.cmdid.setText(appConfig.cmdid);
        }
        binding.server.setText(appConfig.server);
        binding.port.setText(appConfig.port != 0 ? Integer.toString(appConfig.port) : "");
        String protocolStr = appConfig.protocol + "-";
        for (int idx = 0; idx < binding.protocol.getCount(); idx++) {
            String item = binding.protocol.getItemAtPosition(idx).toString();
            if (item.startsWith(protocolStr)) {
                binding.protocol.setSelection(idx);
                break;
            }
        }

        if (appConfig.networkProtocol < binding.networkProtocol.getCount()) {
            binding.networkProtocol.setSelection(appConfig.networkProtocol);
        }
        if (appConfig.encryption < binding.encryptions.getCount()) {
            binding.encryptions.setSelection(appConfig.encryption);
        }
        binding.heartbeat.setText((appConfig.heartbeat > 0) ? Integer.toString(appConfig.heartbeat) : "");
        binding.packetSize.setText((appConfig.packetSize > 0) ? Integer.toString(appConfig.packetSize) : "");

        if (appConfig.network < binding.network.getCount()) {
            binding.network.setSelection(appConfig.network);
        }

        binding.btnStartServ.setEnabled(!MicroPhotoService.isRunning);
        binding.btnStopServ.setEnabled(MicroPhotoService.isRunning);

        if (MicroPhotoService.isRunning) {
            Intent intent2 = new Intent(MainActivity.this, MicroPhotoService.class);
            try {
                stopService(intent2);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }



        if (MicroPhotoContext.hasMpAppConfig(appContext)) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {

                    if (!MicroPhotoService.isRunning && !TextUtils.isEmpty(appConfig.cmdid) && !TextUtils.isEmpty(appConfig.server) && appConfig.port != 0) {
                        if (binding.btnStartServ.isEnabled()) {
                            binding.btnStartServ.performClick();
                        }
                    }
                }
            };

            Handler handler = new Handler();
            long boottime = SystemClock.elapsedRealtime();
            Log.i(TAG, "System boot time =" + boottime );
            if(boottime <= 60000)
                handler.postDelayed(runnable, 15000);
            else
                handler.postDelayed(runnable, 500);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    protected void initListener() {

        this.binding.btnStartServ.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String[] accessPermissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.FOREGROUND_SERVICE, Manifest.permission.READ_PHONE_STATE,
                        /*Manifest.permission.PACKAGE_USAGE_STATS,*/
                        /*Manifest.permission.SET_TIME,*/};
                boolean needRequire = false;
                for (String access : accessPermissions) {
                    int curPermission = ActivityCompat.checkSelfPermission(MainActivity.this, access);
                    if (curPermission != PackageManager.PERMISSION_GRANTED) {
                        needRequire = true;
                        break;
                    }
                }
                if (needRequire) {
                    ActivityCompat.requestPermissions(MainActivity.this, accessPermissions, MY_PERMISSIONS_REQUEST_FOREGROUND_SERVICE);
                    // return;
                }

                Context appContext = getApplicationContext();
                MicroPhotoContext.AppConfig curAppConfig = MicroPhotoContext.getMpAppConfig(appContext);

                if (TextUtils.isEmpty(curAppConfig.cmdid)) {
                    curAppConfig.cmdid = MicroPhotoService.getSerialNumber();
                }

                startMicroPhotoService(appContext, curAppConfig, mMessenger);

                binding.btnStartServ.setEnabled(false);
                binding.btnStopServ.setEnabled(true);
            }
        });

        this.binding.btnSaveCfg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View view) {

                MicroPhotoContext.AppConfig appCfg =  MicroPhotoContext.getMpAppConfig(getApplicationContext());

                String protocolStr = MainActivity.this.binding.protocol.getSelectedItem().toString();
                int protocol = MicroPhotoContext.DEFAULT_PROTOCOL;
                String[] parts = protocolStr.split("-");
                if (parts != null) {
                    protocol = Integer.parseInt(parts[0]);
                }

                if (appCfg.protocol != protocol) {

                    AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
                    builder.setTitle(R.string.confirm_change_protocol);
                    builder.setMessage(R.string.confirm_change_protocol_text);
                    builder.setCancelable(true);
                    builder.setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();

                            retrieveAndSaveAppConfig();
                            MicroPhotoContext.removeMpConfigFiles(getApplicationContext());
                            MicroPhotoService.updateConfigs(MainActivity.this.getApplicationContext());
                        }
                    });
                    builder.setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();
                        }
                    });
                    builder.show();
                } else {
                    retrieveAndSaveAppConfig();
                    MicroPhotoService.updateConfigs(MainActivity.this.getApplicationContext());
                }

            }
        });

        this.binding.btnTakePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                takePhoto(1, 255, true);
            }
        });
        this.binding.btnTakePhoto2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                takePhoto(2, 255, true);
            }
        });
        this.binding.btnTakePhoto3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                takePhoto(3, 255, true);
            }
        });
        this.binding.btnTakePhoto4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                takePhoto(4, 255, true);
            }
        });

        this.binding.takeVideoBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                takePhoto(1, 255, false);
            }
        });
        this.binding.takeVideoBtn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                takePhoto(2, 255, false);
            }
        });
        this.binding.takeVideoBtn3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                takePhoto(3, 255, false);
            }
        });
        this.binding.takeVideoBtn4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                takePhoto(4, 255, false);
            }
        });

        this.binding.btnStopServ.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                MicroPhotoService.stopTerminalService(getApplicationContext());

                binding.btnStartServ.setEnabled(true);
                binding.btnStopServ.setEnabled(false);
            }
        });

        binding.btnChannels.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, ChannelActivity.class);
                startActivity(intent);
            }
        });

        binding.btnLogs.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, LogActivity.class);
                startActivity(intent);
            }
        });

        binding.btnSendHb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MicroPhotoService.sendHeartbeat(getApplicationContext());
            }
        });

        binding.btnRestartApp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Context context = v.getContext().getApplicationContext();
                MicroPhotoService.restartApp(context, context.getPackageName(), "Manual Restart From MainActivity");
            }
        });

        binding.btnReboot.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(final View v) {
                AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
                builder.setTitle(R.string.confirm_reboot);
                builder.setMessage(R.string.text_confirm_reboot);
                builder.setCancelable(true);
                builder.setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        dialogInterface.dismiss();
                        SysApi.reboot(v.getContext().getApplicationContext());
                    }
                });
                builder.setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        dialogInterface.dismiss();
                    }
                });
                builder.show();
            }
        });

        binding.btnCameraInfo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                MicroPhotoService.setCam3V3Enable(true);

                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        String cameraInfo = CameraUtils.getAllCameraInfo(view.getContext());

                        Log.d(TAG, cameraInfo);

                        MicroPhotoService.setCam3V3Enable(false);
                        
                        MicroPhotoService.infoLog(cameraInfo);
                        Toast.makeText(view.getContext(), cameraInfo, Toast.LENGTH_LONG).show();
                    }
                };

                Handler handler = new Handler();
                handler.postDelayed(runnable, 1500);
            }
        });

    }

    public static void startMicroPhotoService(Context context, MicroPhotoContext.AppConfig curAppConfig, Messenger messenger) {

        if (TextUtils.isEmpty(curAppConfig.cmdid) || TextUtils.isEmpty(curAppConfig.server) || curAppConfig.port == 0) {
            return;
        }
        Intent intent = new Intent(context, MicroPhotoService.class);
        intent.setAction(MicroPhotoService.ACTION_START);
        intent.putExtra("cmdid", curAppConfig.cmdid);
        intent.putExtra("server", curAppConfig.server);
        intent.putExtra("port", curAppConfig.port);
        intent.putExtra("protocol", curAppConfig.protocol);
        intent.putExtra("networkProtocol", curAppConfig.networkProtocol);
        intent.putExtra("encryption", curAppConfig.encryption);
        intent.putExtra("network", curAppConfig.network);
        if (messenger != null) {
            intent.putExtra("messenger", messenger);
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(intent);
        } else {
            context.startService(intent);
        }
    }

    private void takePhoto(int channel, int preset, boolean photoOrVideo) {
        if (binding.btnStartServ.isEnabled()) {
            String appPath = MicroPhotoContext.buildMpAppDir(getApplicationContext());
            File file = new File(appPath);
            File tempFile = new File(file, "tmp");
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
            Date dt = new Date();

            File photoFile = new File(tempFile, "IMG-" + Integer.toString(channel) + "-" + simpleDateFormat.format(dt) + (photoOrVideo ? ".jpg" : ".mp4"));
            if (photoFile.exists()) {
                photoFile.delete();
            }

            File configFile = new File(appPath);
            configFile = new File(configFile, "data/channels/" + Integer.toString(channel) + ".json");

            MicroPhotoService.takePhoto(channel, preset, photoOrVideo, configFile.getAbsolutePath(), photoFile.getAbsolutePath());
        } else {
            MicroPhotoService.takePhoto(this.getApplicationContext(), channel, preset, photoOrVideo);
        }
    }

    protected void TakeAndThrowPhoto(int channel, int preset) {
        String appPath = MicroPhotoContext.buildMpAppDir(getApplicationContext());
        File configFile = new File(appPath);
        configFile = new File(configFile, "data/channels/" + Integer.toString(channel) + ".json");

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        Date dt = new Date();

        File tmpPath = new File(appPath, "tmp");
        if (!tmpPath.exists()) {
            tmpPath.mkdirs();
        }
        File photoFile = new File(tmpPath, "IMG-" + Integer.toString(channel) + "-" + sdf.format(dt) + ".jpg");
        if (photoFile.exists()) {
            photoFile.delete();
        }

        MicroPhotoService.takePhoto(channel, preset, true, configFile.getAbsolutePath(), photoFile.getAbsolutePath());
    }

    private MicroPhotoContext.AppConfig retrieveAndSaveAppConfig() {
        MicroPhotoContext.AppConfig appConfig = new MicroPhotoContext.AppConfig();

        appConfig.cmdid = MainActivity.this.binding.cmdid.getText().toString();
        appConfig.server = MainActivity.this.binding.server.getText().toString();
        String portStr = MainActivity.this.binding.port.getText().toString();
        appConfig.port = TextUtils.isEmpty(portStr) ? 0 : Integer.parseInt(portStr);
        String protocolStr = MainActivity.this.binding.protocol.getSelectedItem().toString();
        appConfig.protocol = MicroPhotoContext.DEFAULT_PROTOCOL;
        String[] parts = protocolStr.split("-");
        if (parts != null) {
            appConfig.protocol = Integer.parseInt(parts[0]);
        }
        appConfig.networkProtocol = MainActivity.this.binding.networkProtocol.getSelectedItemPosition();
        appConfig.encryption = MainActivity.this.binding.encryptions.getSelectedItemPosition();

        appConfig.heartbeat = TextUtils.isEmpty(binding.heartbeat.getText().toString()) ? 0 : Integer.parseInt(binding.heartbeat.getText().toString());
        appConfig.packetSize = TextUtils.isEmpty(binding.packetSize.getText().toString()) ? 0 : Integer.parseInt(binding.packetSize.getText().toString());

        appConfig.network = MainActivity.this.binding.network.getSelectedItemPosition();

        saveAppConfig(appConfig);

        return appConfig;
    }

    private MicroPhotoContext.AppConfig getAppConfig() {
        return MicroPhotoContext.getMpAppConfig(getApplicationContext());
    }

    private void saveAppConfig(MicroPhotoContext.AppConfig appConfig) {
        MicroPhotoContext.saveMpAppConfig(getApplicationContext(), appConfig);
    }

    private int getDefaultDataSubId() {
        SubscriptionManager subscriptionManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
        try {
            Method method = subscriptionManager.getClass().getDeclaredMethod("getDefaultDataSubscriptionId");
            return (int) method.invoke(subscriptionManager);
        } catch (Exception e) {
            Log.e(TAG, "wjz debug getDefaultDataSubId: error is " + e.getMessage());
        }
        return 0;
    }

    LocationListener locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            // 处理位置更新事件
            double latitude = location.getLatitude();
            double longitude = location.getLongitude();
            // ...

            Log.e("xyh", "定位方式：" + location.getProvider());
            Log.e("xyh", "纬度：" + location.getLatitude());
            Log.e("xyh", "经度：" + location.getLongitude());
            Log.e("xyh", "海拔：" + location.getAltitude());
            Log.e("xyh", "时间：" + location.getTime());
            Log.e("xyh", "国家：" + LocationUtil.getCountryName(MainActivity.this, location.getLatitude(), location.getLongitude()));
            Log.e("xyh", "获取地理位置：" + LocationUtil.getAddress(MainActivity.this, location.getLatitude(), location.getLongitude()));
            Log.e("xyh", "所在地：" + LocationUtil.getLocality(MainActivity.this, location.getLatitude(), location.getLongitude()));
            Log.e("xyh", "所在街道：" + LocationUtil.getStreet(MainActivity.this, location.getLatitude(), location.getLongitude()));

        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            // 处理位置状态变化事件
        }

        @Override
        public void onProviderEnabled(String provider) {
            // 处理位置提供者启用事件

        }

        @Override
        public void onProviderDisabled(String provider) {
            // 处理位置提供者禁用事件
        }
    };

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            // Back pressed
            return true; // disable it
        }

        return super.onKeyDown(keyCode, event);
    }


}