package com.dinect.checker;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;

import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugins.GeneratedPluginRegistrant;

public class MainActivity extends FlutterActivity {

    private static final int START_SCANNER_REQUEST_CODE = 2017;
    private static final String FLUTTER_CHANNEL_NAME = "com.dinect.checker/instance_id";
    private static final String ERROR_MESSAGE = "message";

    static final String PREF_API_URL = "url";
    static final String PREF_APP_TOKEN = "appToken";
    static final String PREF_POS_TOKEN = "token";
    static final String PREF_APP_BAR_COLOR = "color";

    private MethodChannel mChannel;
    private Map mScannerArgs;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GeneratedPluginRegistrant.registerWith(this);
        mChannel = new MethodChannel(getFlutterView(), FLUTTER_CHANNEL_NAME);
        mChannel.setMethodCallHandler(this::callMethod);
    }

    private void callMethod(MethodCall call, Result result) {
        switch (call.method) {
            case "getLocale":
                result.success(getLanguage());
                break;
            case "getFlavor":
                result.success(BuildConfig.flavor);
                break;
            case "getCurrency":
                result.success(BuildConfig.currency);
                break;
            case "startScanner":
                startScannerActivity(call);
                break;
            case "isOnline":
                checkInternetConnection(result);
                break;
            case "getSupportPhone":
                result.success(BuildConfig.supportPhone);
                break;
            case "getSupportUrl":
                result.success(BuildConfig.supportUrl);
                break;
            case "getEndpoint":
                result.success(BuildConfig.endpoint);
                break;
            case "getAppToken":
                result.success(BuildConfig.appToken);
                break;
            case "getAppTitle":
                result.success(BuildConfig.appTitle);
                break;
            case "showBonus":
                result.success(BuildConfig.showBonus);
                break;
            case "finish":
                finish();
                break;
            case "getVersionName":
                result.success(getVersion());
                break;
            default:
                result.notImplemented();
                break;
        }
    }

    private String getVersion() {
        try {
            PackageInfo pInfo = this.getPackageManager().getPackageInfo(getPackageName(), 0);
            return pInfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return "";
        }
    }

    private String getLanguage() {
        if (Arrays.asList("ru", "en").contains(Locale.getDefault().getLanguage())) {
            return Locale.getDefault().getLanguage();
        } else {
            return BuildConfig.locale;
        }
    }

    private void checkInternetConnection(Result result) {
        boolean connected = isOnline(this);
        if (!connected) {
            Toast.makeText(this, "Проверьте интернет соединение", Toast.LENGTH_SHORT).show();
        }
        result.success(connected);
    }

    private void setLocale(String locale) {
        locale = locale != null ? locale : getLanguage();
        Resources res = getResources();
        Configuration configuration = new Configuration(res.getConfiguration());
        configuration.locale = new Locale(locale);
        Locale.setDefault(configuration.locale);
        res.updateConfiguration(configuration, res.getDisplayMetrics());
    }

    private void startScannerActivity(MethodCall call) {
        mScannerArgs = call.arguments();
        startScannerActivity();
    }

    private void startScannerActivity() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 101);
        } else {
            openScanner();
        }
    }

    private void openScanner() {
        Intent cameraIntent = new Intent(MainActivity.this, ScannerActivity.class);

        for (Object key : mScannerArgs.keySet()) {
            if (key.equals("color")) {
                cameraIntent.putExtra((String) key,
                        Long.parseLong((String) mScannerArgs.get(key)));
            } else {
                cameraIntent.putExtra((String) key, (String) mScannerArgs.get(key));
            }
        }

        setLocale((String) mScannerArgs.get("localeCode"));
        startActivityForResult(cameraIntent, START_SCANNER_REQUEST_CODE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
            String permissions[], int[] grantResults) {
        openScanner();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == START_SCANNER_REQUEST_CODE) {
            if (resultCode == RESULT_CANCELED) {
                finish();
            } else if (resultCode == RESULT_OK) {
                if (data != null && data.getExtras() != null) {
                    String user = data.getExtras().getString("user", null);
                    if (user != null) {
                        String card = data.getExtras().getString("card", null);
                        ArrayList<String> args = new ArrayList<>(2);
                        args.add(user);
                        args.add(card);
                        mChannel.invokeMethod("purchase", args);
                    } else {
                        String menuItem = data.getExtras().getString("item", null);
                        if (menuItem != null) {
                            if (menuItem.equals("exit")) {
                                finish();
                            } else {
                                mChannel.invokeMethod(menuItem, null);
                            }
                        }
                    }
                } else {
                    startScannerActivity();
                }
            }
        }
    }

    private static boolean isOnline(Context context) {
        NetworkInfo netInfo = getConnectivityManager(context).getActiveNetworkInfo();
        return netInfo != null && netInfo.isConnected();
    }

    private static ConnectivityManager getConnectivityManager(Context context) {
        return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    }
}
