package org.deke.risk.riskahead.helper;

import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.LayoutInflaterCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.maps.model.LatLng;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.iconics.context.IconicsLayoutInflater;
import com.mikepenz.materialdrawer.AccountHeader;
import com.mikepenz.materialdrawer.AccountHeaderBuilder;
import com.mikepenz.materialdrawer.Drawer;
import com.mikepenz.materialdrawer.DrawerBuilder;
import com.mikepenz.materialdrawer.model.DividerDrawerItem;
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;

import org.deke.risk.riskahead.LoginActivity;
import org.deke.risk.riskahead.MainActivity;
import org.deke.risk.riskahead.MapsActivity;
import org.deke.risk.riskahead.R;
import org.deke.risk.riskahead.ProfileActivity;
import org.deke.risk.riskahead.ReportWFActivity;
import org.deke.risk.riskahead.SettingsActivity;
import org.deke.risk.riskahead.SubscriptionsActivity;
import org.deke.risk.riskahead.ViewReportActivity;

import java.util.HashMap;

public abstract class BaseActivity extends AppCompatActivity {

    public final static String EXTRA_MESSAGE = "org.deke.risk.riskahead.MESSAGE";
    private final static String TAG = BaseActivity.class.getSimpleName();

    public final static int mainAvtivityID = 1;
    public final static int reportAvtivityID = 2;
    public final static int mapAvtivityID = 3;
    public final static int userstatsAvtivityID = 4;
    public final static int settingsAvtivityID = 5;
    public final static int subscriptionsAvtivityID = 6;
    public final static int logoutAvtivityID = 7;

    public SessionManager session;
    public HashMap<String, String> user;
    public ProgressDialog pDialog;

    GoogleApiClient mGoogleApiClient;
    private final static int INTERVAL = 1000 * 300; //300 seconds
    InterstitialAd mInterstitialAd;

    private AccountHeader headerResult = null;
    public Drawer navDrawer = null;
    public Toolbar mToolbar;

    public LocationManager locationManager;
    public LatLng myPosition;


    public void userHasToBeLoggedIn(){
        if (!session.isLoggedIn()) {
            logout();
        }
        isNetworkAvailable();
    }

    public HashMap<String, String> getUser(){
        user = session.getUserDetails();
        return user;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        LayoutInflaterCompat.setFactory(getLayoutInflater(), new IconicsLayoutInflater(getDelegate()));
        super.onCreate(savedInstanceState);
        setContentView(getLayoutResourceId());

        initAds();
        initProgressDialog();

        session = new SessionManager(getApplicationContext());
        user = session.getUserDetails();

        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
        initNavigationDrawer(savedInstanceState);

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        LocationListener locationListener = new MyLocationListener();
        locationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER, 5000, 10, locationListener);

        overridePendingTransition(R.anim.fade_in_anim, R.anim.fade_out_anim);

        if(!isMyNotificationServiceRunning()){
            Log.d(TAG,"onCreate: NotificationService not running. Starting service...");
            startService(new Intent(this, NotificationService.class));
        }else{
            Log.d(TAG,"onCreate: NotificationService already running. Not starting more services.");
        }
    }

    private class MyLocationListener implements LocationListener {

        @Override
        public void onLocationChanged(Location loc) {
            String longitude = "Longitude: " + loc.getLongitude();
            Log.v(TAG, longitude);
            String latitude = "Latitude: " + loc.getLatitude();
            Log.v(TAG, latitude);

            if(session.isGPSForNotificationsEnabled()) {
                Log.d(TAG,"Save GPS as new location...");
                session.setLocation(Double.doubleToRawLongBits(loc.getLatitude()), Double.doubleToRawLongBits(loc.getLongitude()));
            }else{
                Log.d(TAG,"Don't Save GPS as new location because GPS for notifications is disabled...");
            }
        }

        @Override
        public void onProviderDisabled(String provider) {}

        @Override
        public void onProviderEnabled(String provider) {}

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    }

    private void initProgressDialog() {
        pDialog = new ProgressDialog(this);
        pDialog.setCancelable(false);
        pDialog.setTitle(getString(R.string.progress_getdata_title));
        pDialog.setMessage(getString(R.string.progress_getdata_text));
    }

    private void initAds() {
        mInterstitialAd = new InterstitialAd(getApplicationContext());
        mInterstitialAd.setAdUnitId(getString(R.string.banner_ad_unit_id));

        mInterstitialAd.setAdListener(new AdListener() {
            @Override
            public void onAdClosed() {
                requestNewInterstitial();
            }
        });

        requestNewInterstitial();
    }

    private void initNavigationDrawer(Bundle savedInstanceState) {
        PrimaryDrawerItem item1 = new PrimaryDrawerItem()
                .withName(R.string.navigation_start)
                .withIdentifier(mainAvtivityID)
                .withIcon(GoogleMaterial.Icon.gmd_home);

        PrimaryDrawerItem item2 = new PrimaryDrawerItem()
                .withName(R.string.navigation_report)
                .withIdentifier(reportAvtivityID)
                .withIcon(GoogleMaterial.Icon.gmd_room);

        PrimaryDrawerItem item3 = new PrimaryDrawerItem()
                .withName(R.string.navigation_incident_map)
                .withIdentifier(mapAvtivityID)
                .withIcon(GoogleMaterial.Icon.gmd_map);

        PrimaryDrawerItem item4 = new PrimaryDrawerItem()
                .withName(R.string.navigation_user_stats)
                .withIdentifier(userstatsAvtivityID)
                .withIcon(GoogleMaterial.Icon.gmd_speaker_notes);

        PrimaryDrawerItem item5 = new PrimaryDrawerItem()
                .withName(R.string.navigation_acc_settings)
                .withIdentifier(settingsAvtivityID)
                .withIcon(GoogleMaterial.Icon.gmd_settings);

        PrimaryDrawerItem item6 = new PrimaryDrawerItem()
                .withName(R.string.navigation_subscriptions)
                .withIdentifier(subscriptionsAvtivityID)
                .withIcon(GoogleMaterial.Icon.gmd_star);

        PrimaryDrawerItem item7 = new PrimaryDrawerItem()
                .withName(R.string.navigation_logout)
                .withIdentifier(logoutAvtivityID)
                .withIcon(GoogleMaterial.Icon.gmd_remove_circle);

        headerResult = new AccountHeaderBuilder()
                .withActivity(this)
                .withHeaderBackground(R.drawable.header2)
                .addProfiles(
                        new ProfileDrawerItem().withName(user.get("username")).withEmail(user.get("email")).withIcon(getResources().getDrawable(R.drawable.logo_riskahead_header))
                )
                .build();

        navDrawer = new DrawerBuilder()
                .withActivity(this)
                .withAccountHeader(headerResult)
                .withTranslucentStatusBar(true)
                .withHasStableIds(true)
                .withToolbar(mToolbar)
                .withOnDrawerListener(new Drawer.OnDrawerListener() {
                    @Override
                    public void onDrawerOpened(View drawerView) {
                        getSupportActionBar().setTitle("Navigate to...");
                    }

                    @Override
                    public void onDrawerClosed(View drawerView) {
                        getSupportActionBar().setTitle(getActivityName());
                    }

                    @Override
                    public void onDrawerSlide(View drawerView, float slideOffset) {

                    }
                })
                .withSavedInstance(savedInstanceState)
                .withSelectedItem(-1)
                .addDrawerItems(
                        item1,
                        item2,
                        item3,
                        new DividerDrawerItem(),
                        item4,
                        item5,
                        new DividerDrawerItem(),
                        item6,
                        item7).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
            @Override
            public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
                Intent intent = null;
                switch (drawerItem.getIdentifier()) {
                    case 1:
                        intent = new Intent(BaseActivity.this, MainActivity.class);
                        break;
                    case 2:
                        intent = new Intent(BaseActivity.this, ReportWFActivity.class);
                        break;
                    case 3:
                        intent = new Intent(BaseActivity.this, MapsActivity.class);
                        break;
                    case 4:
                        intent = new Intent(BaseActivity.this, ProfileActivity.class);
                        break;
                    case 5:
                        intent = new Intent(BaseActivity.this, SettingsActivity.class);
                        break;
                    case 6:
                        intent = new Intent(BaseActivity.this, SubscriptionsActivity.class);
                        break;
                    case 7:
                        logoutUser();
                        break;
                    default:
                        Log.d("Unknown switch page: ", Integer.toString(position));
                        break;
                }
                session.setNotificationPositionRequest(false);
                if(intent != null) BaseActivity.this.startActivity(intent);
                return false;
            }
        }).build();



    }

    private void requestNewInterstitial() {
        AdRequest adRequest = new AdRequest.Builder()
                .addTestDevice("1C182703CED1D65AE86F9E51E94ECDE7")
                .build();

        mInterstitialAd.loadAd(adRequest);
    }

    public void showAd(){
        if (mInterstitialAd.isLoaded()) {
            //TODO: ACTIVATE WHEN NEEDED
           //mInterstitialAd.show();
        }
    }

    public void isNetworkAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        if(activeNetworkInfo == null){
            new AlertDialog.Builder(this)
                    .setTitle(getString(R.string.alert_internetconnection_title))
                    .setMessage(getString(R.string.alert_internetconnection_text))
                    .setNeutralButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            logoutUser();
                        }
                    })
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .show();
        }
    }

    public void logoutUser() {
        session.removeUser();
        logout();
    }

    public void logout() {
        session.setLogin(false);

        Intent intent = new Intent(BaseActivity.this, LoginActivity.class);
        intent.putExtra(EXTRA_MESSAGE, "login");
        BaseActivity.this.startActivity(intent);
        finish();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_common, menu);

        return true;
    }

    public void gotoMainActivity(){
        Intent intent;
        intent = new Intent(getApplicationContext(), MainActivity.class);
        startActivity(intent);
    }

    public void gotoReportActivity(){
        Intent intent;
        intent = new Intent(getApplicationContext(), ReportWFActivity.class);
        startActivity(intent);
    }

    public void gotoReportActivity(String position){
        Intent intent;
        intent = new Intent(getApplicationContext(), ReportWFActivity.class);
        intent.putExtra(EXTRA_MESSAGE, position);
        startActivity(intent);
    }

    public void gotoMapActivity(){
        Intent intent;
        intent = new Intent(BaseActivity.this, MapsActivity.class);
        BaseActivity.this.startActivity(intent);
    }

    public void gotoMapActivity(String position){
        Intent intent;
        intent = new Intent(getApplicationContext(), MapsActivity.class);
        intent.putExtra(EXTRA_MESSAGE, position);
        startActivity(intent);
    }

    public void gotoProfileActivity(){
        Intent intent;
        intent = new Intent(getApplicationContext(), ProfileActivity.class);
        startActivity(intent);
    }

    public void gotoSettingsActivity(){
        Intent intent;
        intent = new Intent(getApplicationContext(), SettingsActivity.class);
        startActivity(intent);
    }

    public void gotoSubscriptionsActivity(){
        Intent intent;
        intent = new Intent(getApplicationContext(), SubscriptionsActivity.class);
        startActivity(intent);
    }

    public void gotoViewReportActivity(Integer uid){
        Intent intent;
        intent = new Intent(getApplicationContext(), ViewReportActivity.class);
        intent.putExtra(EXTRA_MESSAGE, uid);
        startActivity(intent);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if((id == R.id.menu_action_exit)){
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_HOME);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        }else if((id == R.id.menu_action_about)){
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.riskahead.net/about/"));
            startActivity(browserIntent);
        }else if((id == R.id.menu_action_help)){
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.riskahead.net/contact/"));
            startActivity(browserIntent);
        }

        return super.onOptionsItemSelected(item);
    }

    public void showMessage(String statusText){
        Toast.makeText(this, statusText, Toast.LENGTH_LONG).show();
    }

    protected abstract int getLayoutResourceId();

    protected abstract String getActivityName();

    public void showDialog() {
        if (!pDialog.isShowing())
            pDialog.show();
    }

    public void hideDialog() {
        if (pDialog.isShowing())
            pDialog.dismiss();
    }

    private boolean isMyNotificationServiceRunning() {
        ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (NotificationService.class.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }
}
