package com.github.marlowww.hidemocklocation;

import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SwitchCompat;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import butterknife.BindColor;
import butterknife.BindString;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnCheckedChanged;


public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getName();

    @BindView(R.id.toolbar)
    Toolbar toolbarView;
    @BindView(R.id.app_list)
    RecyclerView appListView;
    @BindView(R.id.list_type)
    SwitchCompat listSwitch;
    @BindView(R.id.xposed_disabled)
    TextView xposedDisabledView;
    @BindView(R.id.xposed_disabled_sub)
    TextView xposedDisabledSubView;
    @BindView(R.id.switch_layout)
    RelativeLayout switchLayout;
    @BindView(R.id.apps_count)
    TextView appsCountView;

    @BindString(R.string.whitelist)
    String whitelistStr;
    @BindString(R.string.blacklist)
    String blacklistStr;
    @BindString(R.string.donate_url)
    String donateUrlStr;
    @BindColor(R.color.colorAccent)
    int accentColor;
    @BindColor(R.color.colorPrimaryDark)
    int primaryDarkColor;
    @BindColor(R.color.colorDark)
    int darkColor;

    public static SharedPreferences prefs;

    private AppsAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Load settings
        prefs = getSharedPreferences(Common.PACKAGE_PREFERENCES, MODE_WORLD_READABLE);

        final Common.ListType listType = getListType();
        final Set<String> checkedApps = prefs.getStringSet(listType.toString(), new HashSet<String>());


        // Get information about apps
        final PackageManager pm = getPackageManager();
        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);

        final List<ResolveInfo> infoList = new ArrayList<>(pm.queryIntentActivities(mainIntent, 0));
        Collections.sort(infoList, new ResolveInfo.DisplayNameComparator(pm));

        final ArrayList<AppItem> apps = new ArrayList<>(infoList.size());

        int checked = 0; // Checked apps counter
        for (ResolveInfo info : infoList) {
            if (info.activityInfo != null) {
                final CharSequence label = info.loadLabel(pm);
                final Drawable icon = info.loadIcon(pm);

                if (checkedApps.contains(info.activityInfo.packageName)) {
                    apps.add(new AppItem(label, icon, info.activityInfo.packageName, true));
                    checked++;
                } else
                    apps.add(new AppItem(label, icon, info.activityInfo.packageName));
            }
        }

        // End of splash screen
        setTheme(R.style.AppTheme);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        setSupportActionBar(toolbarView);
        setListSwitch(listType);

        adapter = new AppsAdapter(apps);
        adapter.setOnCheckChangedListener(new OnAppCheckChangedListener() {
            @Override
            public void appsItemCheckChanged(AppItem item) {
                Common.ListType listType = getListType();
                Set<String> checkedApps = adapter.getCheckedAppsPackageNames();

                appsCountView.setText(getString(R.string.checked, checkedApps.size()));

                SharedPreferences.Editor editor = prefs.edit();
                editor.putStringSet(listType.toString(), checkedApps);
                editor.apply();
            }
        });

        appListView.setHasFixedSize(true);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        appListView.setLayoutManager(layoutManager);
        appListView.setAdapter(adapter);


        appsCountView.setText(getString(R.string.checked, checked));
        appsCountView.setTextColor(listType.equals(Common.ListType.WHITELIST)
                ? accentColor : darkColor);
    }


    private Common.ListType getListType() {
        String listTypeStr = prefs.getString(Common.PREF_LIST_TYPE,
                Common.ListType.BLACKLIST.toString());
        return listTypeStr.equals(Common.ListType.BLACKLIST.toString())
                ? Common.ListType.BLACKLIST : Common.ListType.WHITELIST;
    }

    private void setListSwitch(Common.ListType listType) {
        listSwitch.setText(listType.equals(Common.ListType.WHITELIST) ? whitelistStr : blacklistStr);
        listSwitch.setTextColor(listType.equals(Common.ListType.WHITELIST) ? accentColor : darkColor);
        listSwitch.setChecked(listType.equals(Common.ListType.WHITELIST));
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (!isModuleEnabled()) {
            appListView.setVisibility(View.GONE);
            switchLayout.setVisibility(View.GONE);
            xposedDisabledView.setVisibility(View.VISIBLE);
            xposedDisabledSubView.setVisibility(View.VISIBLE);
        }
        else {
            appListView.setVisibility(View.VISIBLE);
            switchLayout.setVisibility(View.VISIBLE);
            xposedDisabledView.setVisibility(View.GONE);
            xposedDisabledSubView.setVisibility(View.GONE);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        File prefsDir = new File(getApplicationInfo().dataDir, "shared_prefs");
        File prefsFile = new File(prefsDir, Common.PACKAGE_PREFERENCES + ".xml");
        if (prefsFile.exists()) {
            prefsFile.setReadable(true, false);
        }
    }

    @OnCheckedChanged(R.id.list_type)
    public void changeListType(boolean isChecked) {
        if (adapter != null) {
            Common.ListType listType = isChecked ? Common.ListType.WHITELIST : Common.ListType.BLACKLIST;
            setListSwitch(listType);
            appsCountView.setTextColor(listType.equals(Common.ListType.WHITELIST) ? accentColor : darkColor);

            List<AppItem> apps = adapter.getApps();
            List<AppItem> allApps = adapter.getAllApps();

            SharedPreferences.Editor editor = prefs.edit();
            editor.putString(Common.PREF_LIST_TYPE, listType.toString());
            editor.apply();

            Set<String> checkedApps = prefs.getStringSet(listType.toString(), new HashSet<String>());

            // Count again to prevent situation when in prefs are uninstalled apps
            // Change all apps in adapter
            int checked = 0;
            for (AppItem app : allApps) {
                if (checkedApps.contains(app.getPackageName())) {
                    app.setChecked(true);
                    checked++;
                } else app.setChecked(false);
            }
            // Change currently viewed apps
            for (AppItem app : apps) {
                if (checkedApps.contains(app.getPackageName())) {
                    app.setChecked(true);
                } else app.setChecked(false);
            }
            adapter.notifyDataSetChanged();
            appsCountView.setText(getString(R.string.checked, checked));
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.action_menu, menu);

        final MenuItem searchItem = menu.findItem(R.id.action_search);
        final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
        // Resize searchView
        searchView.setMaxWidth(Integer.MAX_VALUE);

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                adapter.filter(query);
                searchView.clearFocus();
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                adapter.filter(newText);
                return true;
            }
        });
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_donate:
                Uri uri = Uri.parse(donateUrlStr);
                Intent browserIntent = new Intent(Intent.ACTION_VIEW, uri);
                startActivity(browserIntent);
                break;
            case R.id.action_settings:
                Intent i = new Intent(this, SettingsActivity.class);
                startActivity(i);
                break;
            default:
                return super.onOptionsItemSelected(item);
        }
        return true;
    }

    // Self-hook method
    // Logging and Boolean object are present to avoid ART optimization
    @SuppressWarnings("all")
    private static boolean isModuleEnabled() {
        Log.i(TAG, "Xposed part not active.");
        return Boolean.valueOf(false);
    }
}