package uz.aloqabank.mobilebank.activities;

import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.design.widget.TabLayout;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.SearchView;
import android.widget.TextView;
import com.ssd.aloqamobile.glide.GlideApp;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import io.realm.Realm;
import uz.aloqabank.mobilebank.AloqaApplication;
import uz.aloqabank.mobilebank.BuildConfig;
import uz.aloqabank.mobilebank.R;
import uz.aloqabank.mobilebank.activities.drawermenu.NotificationsActivity;
import uz.aloqabank.mobilebank.activities.drawermenu.ProfileActivity;
import uz.aloqabank.mobilebank.activities.drawermenu.SettingsActivity;
import uz.aloqabank.mobilebank.adapters.MainMenuViewPagerAdapter;
import uz.aloqabank.mobilebank.components.CountDrawable;
import uz.aloqabank.mobilebank.database.PersonalAuthData;
import uz.aloqabank.mobilebank.database.PersonalInfo;
import uz.aloqabank.mobilebank.fragments.*;
import uz.aloqabank.mobilebank.objects.server.requests.NotifyListRequest;
import uz.aloqabank.mobilebank.objects.server.responses.NotifyListResponse;
import uz.aloqabank.mobilebank.objects.server.responses.PersonalInfoV2Response;
import uz.aloqabank.mobilebank.utils.Consts;

import static uz.aloqabank.mobilebank.activities.MainActivity.ARG_FLAG;

public class DashboardActivity extends BaseActivity
        implements NavigationView.OnNavigationItemSelectedListener, View.OnClickListener {

    private MainMenuViewPagerAdapter adapter;
    private ImageView profileAvatar;
    private TextView tvUserName;
    private TextView tvUserPhone;
    private DrawerLayout drawer;

    private boolean paymentFragment = false;
    private String notificationCount = "";
    private MenuItem menuItem;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dashboard);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        setDisplayHomeAsUpEnable();

        setTitle(R.string.main);

        drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        ViewPager mainMenuViewPager = findViewById(R.id.viewPager);
        TabLayout tabs = findViewById(R.id.tabs);
        TextView tvAppVersion = findViewById(R.id.tvAppVersion);

        navigationView.setNavigationItemSelectedListener(this);

        adapter = new MainMenuViewPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(MainFragment.newInstance(), getString(R.string.main));
        adapter.addFragment(PaymentFragment.newInstance(), getString(R.string.pay_operations));
        adapter.addFragment(OperationsFragment.newInstance(), getString(R.string.operations));
        adapter.addFragment(HistoryFragment.newInstance(), getString(R.string.history));
        adapter.addFragment(ExchangeCurrencyFragment.newInstance(), getString(R.string.exchange));

        mainMenuViewPager.setOffscreenPageLimit(3);
        mainMenuViewPager.setAdapter(adapter);
        mainMenuViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                setTitle(adapter.getPageTitle(position));
                invalidateOptionsMenu();
                paymentFragment = position == 1;
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });

        tabs.setupWithViewPager(mainMenuViewPager);

        for (int i = 0; i < adapter.getCount(); i++) {
            TabLayout.Tab tabCall = tabs.getTabAt(i);
            if (tabCall != null)
                switch (i) {
                    case 0:
                        tabCall.setIcon(R.drawable.tab_main_selector);
                        break;
                    case 1:
                        tabCall.setIcon(R.drawable.tab_payment_selector);
                        break;
                    case 2:
                        tabCall.setIcon(R.drawable.tab_operations_selector);
                        break;
                    case 3:
                        tabCall.setIcon(R.drawable.tab_history_selector);
                        break;
                    case 4:
                        tabCall.setIcon(R.drawable.tab_exchange_selector);
                        break;
                }
        }

        View header = navigationView.getHeaderView(0);

        profileAvatar = header.findViewById(R.id.profileAva);
        profileAvatar.setOnClickListener(this);

        tvUserName = header.findViewById(R.id.userNameTV);
        tvUserPhone = header.findViewById(R.id.userPhoneTV);

        String appVersion = BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ") - " + BuildConfig.FLAVOR;
        tvAppVersion.setText(appVersion);

        getUserData();
        if (savedInstanceState == null) {
            Intent intent = getIntent();
            String flag = intent.getStringExtra(ARG_FLAG);
            if (flag == null) return;
            NotificationsActivity.start(this);
        }
    }

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

            SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();
            int searchPlateId = search.getContext().getResources().getIdentifier(
                    "android:id/search_plate", null, null);
            View searchPlate = search.findViewById(searchPlateId);
            if (searchPlate != null) {
                searchPlate.setBackgroundColor(Color.TRANSPARENT);
            }

            search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextSubmit(String query) {
                    return false;
                }

                @Override
                public boolean onQueryTextChange(String newText) {
                    ((PaymentFragment) (adapter.getItem(1))).searchQuery(newText);
                    return false;
                }
            });
            search.setOnCloseListener(() -> {
                ((PaymentFragment) (adapter.getItem(1))).refreshList();
                return false;
            });
        } else {
            getMenuInflater().inflate(R.menu.menu_notification, menu);
        }
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menuItem = menu.findItem(R.id.ic_notification);
        if (!paymentFragment) {
            if (notificationCount.isEmpty()) {
                setNotificationCount("0");
                getNotificationsCount();
            } else {
                setNotificationCount(notificationCount);
            }
        }
        return super.onPrepareOptionsMenu(menu);
    }

    private void setNotificationCount(String count) {
        if (menuItem == null) return;
        LayerDrawable icon = (LayerDrawable) menuItem.getIcon();

        CountDrawable badge;

        // Reuse drawable if possible
        Drawable reuse = icon.findDrawableByLayerId(R.id.ic_notifications_count);
        if (reuse instanceof CountDrawable) {
            badge = (CountDrawable) reuse;
        } else {
            badge = new CountDrawable(this);
        }

        badge.setCount(count);
        icon.mutate();
        icon.setDrawableByLayerId(R.id.ic_notifications_count, badge);
    }

    @Override
    public boolean onOptionsItemSelected(android.view.MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                drawer.openDrawer(GravityCompat.START);
                return true;
            case R.id.ic_notification:
                NotificationsActivity.start(this);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void setProfileData() {
        try (Realm realm = Realm.getDefaultInstance()) {
            PersonalInfo personalInfo = getPersonalInfo(realm);
            if (personalInfo != null) {
                String imageName = personalInfo.getImageURL();
                if (imageName != null) {
                    if (imageName.contains("/"))
                        imageName = imageName.substring(imageName.lastIndexOf("/") + 1);
                    GlideApp.with(this)
                            .load(Consts.imagesUrl + imageName)
                            .placeholder(R.drawable.mount_bg)
                            .into(profileAvatar);
                }
                String userName = getName(personalInfo.getFirstName()) + " " + getName(personalInfo.getLastName());
                tvUserName.setText(userName);
            } else {
                tvUserName.setText("-");
            }
            PersonalAuthData authData = getAuthData(realm);
            tvUserPhone.setText(authData.getPhoneNumber());
        }
    }

    private String getName(String name) {
        return TextUtils.isEmpty(name) ? "-" : name;
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

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

        if (id == R.id.nav_bank_call) {
            makeCall(Consts.BANK_PHONE);
        } else if (id == R.id.nav_settings) {
            Intent settingsIntent = new Intent(this, SettingsActivity.class);
            startActivity(settingsIntent);
        } else if (id == R.id.nav_instructions) {
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(Consts.linkInstruction));
            startActivity(browserIntent);
        } else if (id == R.id.nav_exit) {
            AloqaApplication myApp = (AloqaApplication) getApplication();
            myApp.isLoggedIn = false;
            EnterPinCodeActivity.openEnterPinCodeScreenOnNewTask(this);
        }

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.profileAva) {
            Intent intent = new Intent(this, ProfileActivity.class);
            startActivity(intent);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == NotificationsActivity.REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                notificationCount = "0";
                setNotificationCount(notificationCount);
            } else {
                getNotificationsCount();
            }
        }
    }

    private void getUserData() {
        AloqaApplication.getWebService()
                .getPersonalInfo()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<PersonalInfoV2Response>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(PersonalInfoV2Response response) {
                        try (Realm realm = Realm.getDefaultInstance()) {
                            PersonalInfo pi = getPersonalInfo(realm);
                            realm.beginTransaction();
                            if (pi == null) {
                                pi = realm.createObject(PersonalInfo.class, 1);
                            }
                            PersonalInfoV2Response.Data data = response.getData();
                            PersonalInfoV2Response.User user = data.user;
                            if (user.firstName != null)
                                pi.setFirstName(user.firstName);

                            if (user.lastName != null)
                                pi.setLastName(user.lastName);

                            if (user.birthDay != null)
                                pi.setDob(user.birthDay);

                            if (user.gender != null)
                                pi.setGender(user.gender);

                            if (user.imageUrl != null)
                                pi.setImageURL(user.imageUrl);
                            SharedPreferences preferences =
                                    PreferenceManager.getDefaultSharedPreferences(DashboardActivity.this);
                            preferences
                                    .edit()
                                    .putBoolean("monitoringSwitch", data.services.monitoring.subscribe)
                                    .apply();
                            if (data.services.referral != null) {
                                SharedPreferences preferencesReferral = getSharedPreferences("referral_pref", MODE_PRIVATE);
                                preferencesReferral.edit()
                                        .putBoolean("hide_add_referral_code", data.services.referral.subscribe)
                                        .apply();
                            }

                            realm.commitTransaction();
                            setProfileData();
                        }
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    private void getNotificationsCount() {
        AloqaApplication.getWebService()
                .getNotifications(new NotifyListRequest(0, 0).getHash())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<NotifyListResponse>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(NotifyListResponse response) {
                        if (response.getMessage().getCode().equals("0")) {
                            notificationCount = response.getData().getBadge();
                            setNotificationCount(notificationCount);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

}