package kz.arta.synergy.workflow.mobile.android.common.activities;

import android.Manifest;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.devspark.appmsg.AppMsg;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.firebase.iid.FirebaseInstanceId;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

import kz.arta.synergy.workflow.mobile.android.AlarmManagerPosition;
import kz.arta.synergy.workflow.mobile.android.AlarmManagerSync;
import kz.arta.synergy.workflow.mobile.android.R;
import kz.arta.synergy.workflow.mobile.android.authorization.SynergyAccount;
import kz.arta.synergy.workflow.mobile.android.authorization.activities.AuthorizationActivity;
import kz.arta.synergy.workflow.mobile.android.authorization.activities.AuthorizationPasswordActivity;
import kz.arta.synergy.workflow.mobile.android.common.ActivityConst;
import kz.arta.synergy.workflow.mobile.android.common.SettingsConst;
import kz.arta.synergy.workflow.mobile.android.common.components.CustomImageView;
import kz.arta.synergy.workflow.mobile.android.common.models.CreateDefaults;
import kz.arta.synergy.workflow.mobile.android.common.models.Person;
import kz.arta.synergy.workflow.mobile.android.common.models.settings.DialogItem;
import kz.arta.synergy.workflow.mobile.android.common.models.settings.PriorityItem;
import kz.arta.synergy.workflow.mobile.android.common.models.settings.ProcessItem;
import kz.arta.synergy.workflow.mobile.android.common.models.settings.Settings;
import kz.arta.synergy.workflow.mobile.android.common.models.settings.WorkLoadItem;
import kz.arta.synergy.workflow.mobile.android.common.offline.get.SettingsTable;
import kz.arta.synergy.workflow.mobile.android.common.requests.RestClient;
import kz.arta.synergy.workflow.mobile.android.common.requests.SendGetRequest;
import kz.arta.synergy.workflow.mobile.android.common.utils.ActionUtils;
import kz.arta.synergy.workflow.mobile.android.common.utils.Const;
import kz.arta.synergy.workflow.mobile.android.common.utils.Fonts;
import kz.arta.synergy.workflow.mobile.android.common.utils.FragmentBackPressedListener;
import kz.arta.synergy.workflow.mobile.android.common.utils.FragmentConst;
import kz.arta.synergy.workflow.mobile.android.common.utils.Logger;
import kz.arta.synergy.workflow.mobile.android.common.utils.MyApplication;
import kz.arta.synergy.workflow.mobile.android.common.utils.Utils;
import kz.arta.synergy.workflow.mobile.android.common.utils.Wrapper;
import kz.arta.synergy.workflow.mobile.android.documents.DocumentConst;
import kz.arta.synergy.workflow.mobile.android.documents.common.activities.DocumentInfoActivity;
import kz.arta.synergy.workflow.mobile.android.documents.common.fragments.FragmentDocuments;
import kz.arta.synergy.workflow.mobile.android.documents.common.fragments.FragmentFiltersDocuments;
import kz.arta.synergy.workflow.mobile.android.documents.favorite.FavoritesConsts;
import kz.arta.synergy.workflow.mobile.android.documents.favorite.activities.Favorite;
import kz.arta.synergy.workflow.mobile.android.documents.favorite.activities.FavoriteItemListener;
import kz.arta.synergy.workflow.mobile.android.documents.favorite.activities.FavoritesActivity;
import kz.arta.synergy.workflow.mobile.android.documents.favorite.models.FavoriteItem;
import kz.arta.synergy.workflow.mobile.android.files.FilesConst;
import kz.arta.synergy.workflow.mobile.android.files.activities.SearchFilesActivity;
import kz.arta.synergy.workflow.mobile.android.files.fragments.FragmentFilesList;
import kz.arta.synergy.workflow.mobile.android.files.fragments.FragmentFilesTree;
import kz.arta.synergy.workflow.mobile.android.files.manager.DownloadFile;
import kz.arta.synergy.workflow.mobile.android.files.models.Node;
import kz.arta.synergy.workflow.mobile.android.forms.general.activities.FormPlayer;
import kz.arta.synergy.workflow.mobile.android.registry.FragmentRegistryList;
import kz.arta.synergy.workflow.mobile.android.registry.FragmentRegistryTree;
import kz.arta.synergy.workflow.mobile.android.works.activities.WorkInfoActivity;
import kz.arta.synergy.workflow.mobile.android.works.activities.create.CreateWorkActivity;
import kz.arta.synergy.workflow.mobile.android.works.activities.create.CreateWorkCustomActivity;
import kz.arta.synergy.workflow.mobile.android.works.fragments.FragmentCreateWork;
import kz.arta.synergy.workflow.mobile.android.works.fragments.FragmentFiltersWorks;
import kz.arta.synergy.workflow.mobile.android.works.fragments.FragmentWorks;

/**
 * Created by neox on 14.03.14.
 * Активити содержащее основные фрагменты (работы, документы, файлы)
 */
public class MainActivity extends FragmentActivity {

    /**
     * Поиск файлов
     */
    private static int SEARCH_FILES = 16;
    /**
     * fragmentBackPressedListener
     */
    protected FragmentBackPressedListener fragmentBackPressedListener;
    /**
     * Текущий модуль
     *
     * @see Const#WORKS
     * @see Const#DOCUMENTS
     * @see Const#FILES
     */
    private int typeModule;
    /**
     * Настройки
     */
    private SharedPreferences settings;
    /**
     * Активити
     */
    private Activity activity;

    /**
     * Данные для авторизированного пользователя
     */
    private Person person;

    /**
     * Боковая навигация фильтров
     */
    private SlidingMenu filtersSlidingMenu;

    /**
     * Открыт ли режим выбора модуля
     */
    private boolean showedChooseModule = false;

    /**
     * Фрагмент со списком работ
     */
    private FragmentWorks fragmentWorks;

    /**
     * Фрагмент со списком документов
     */
    private FragmentDocuments fragmentDocuments;

    /**
     * Фрагмент со списком файлов
     */
    private FragmentFilesList fragmentFiles;

    /**
     * Дерево папок
     */
    private FragmentFilesTree fragmentFilesTree;

    /**
     * Фрагмент списка реестров
     */
    private FragmentRegistryList fragmentRegistryList;

    /**
     * Компоненты верхней панели
     */
    private ImageView iconActionBar;
    private RelativeLayout shadow;
    private LinearLayout chooseModule;

    private CustomImageView filtersButton;
    private CustomImageView searchButton;
    private CustomImageView addWorkButton;

    private ImageView headChooseModuleIcon;

    /**
     * Контейнер, в котором находится диалог
     */
    private LinearLayout parentDialogLayout;

    /**
     * Класс для работы с диалогом "Избранное"
     */
    private Favorite favorite;

    /**
     * Пункты для создания документов
     */
    private FavoriteItem[] favoriteItems;

    /**
     * Имя файла с камеры
     */
    private long photoName;

    /**
     * Идентификатор созданного документа
     */
    private String documentID;

    protected MyApplication mMyApp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        ActionBar actionBar = getActionBar();
        if (actionBar != null) {
            actionBar.hide();
        }

        mMyApp = (MyApplication) this.getApplicationContext();

        activity = this;

        // аккаунты в системе
        AccountManager accountManager = AccountManager.get(this);

        // настройки
        settings = getSharedPreferences(SettingsConst.DEFAULT_NAME_SETTINGS, Context.MODE_PRIVATE);

        parentDialogLayout = (LinearLayout) findViewById(R.id.create_menu_dialog_layout);

        final Intent intent = getIntent();
        if (intent == null) {
            return;
        }

        typeModule = intent.getIntExtra(Const.TYPE_MODULE, -1);

        // если используется авторизация через файл
        Uri data = getIntent().getData();
        if (data != null) {
            getIntent().setData(null);
            importData(data);
            return;
        }

        // если аккаунта синерджи нет в системе - открываем первый экран авторизации
        if (accountManager.getAccountsByType(SynergyAccount.TYPE).length == 0) {
            Intent i = new Intent(activity, AuthorizationActivity.class);
            startActivity(i);
            finish();
        } else {
            // получение списка аккаунтов в системе
            Account[] accounts = accountManager.getAccounts();
            for (Account account : accounts) {
                if (!account.type.equals(SynergyAccount.TYPE)) {
                    continue;
                }
                // если нет сохраненного пароля у найденного аккаунта - значит пользователь еще не ввел его
                // в итоге перебрасываем его на второй экран авторизации
                if (accountManager.getPassword(account) == null || accountManager.getPassword(account).isEmpty()) {
                    Intent i = new Intent(activity, AuthorizationPasswordActivity.class);
                    startActivity(i);
                    finish();
                } else {
                    // объект пользователь
                    person = new Person();
                    person.setPassword(accountManager.getPassword(account));
                    person.setLogin(accountManager.getUserData(account, SynergyAccount.LOGIN));
                    person.setHost(accountManager.getUserData(account, SynergyAccount.HOST));
                    person.setShortHost(accountManager.getUserData(account, SynergyAccount.SHORT_HOST));
                    person.setUuid(accountManager.getUserData(account, SynergyAccount.USER_ID));
                    person.setFirstname(accountManager.getUserData(account, SynergyAccount.FIRSTNAME));
                    person.setLastname(accountManager.getUserData(account, SynergyAccount.LASTNAME));

                    person.setSettings(RestClient.getGson().fromJson(settings.getString(SettingsConst.SETTINGS, ""), Settings.class));
                    person.setDefaults(RestClient.getGson().fromJson(settings.getString(SettingsConst.DEFAULTS, ""), CreateDefaults.class));
                    person.setProcesses(RestClient.getGson().fromJson(settings.getString(SettingsConst.PROCESSES, ""), ProcessItem[].class));
                    person.setWorkLoads(RestClient.getGson().fromJson(settings.getString(SettingsConst.WORK_LOADS, ""), WorkLoadItem[].class));

                    //UPD: 2023-06-03 - Если очистить память приложения через настройки
                    // долгим нажатием на иконке приложения вызвать меню - выбрать “о приложении”
                    // нажать “очистить” - “очистить всё” - “ок”
                    // то приложение перестает работать из-за ошикбки NullPointerException: Settings.getSystemName
                    // поэтому написана проверка которая вначале смотрит есть ли системные настройки приложения,
                    // если их нет, то направляем на страницу авторизации где они будут созданы при успешном входе.
                    if (person.getSettings() == null) {
                        Intent i = new Intent(activity, AuthorizationActivity.class);
                        startActivity(i);
                        finish();
                    }
                    // записываем имя сервера
                    accountManager = AccountManager.get(activity);
                    accountManager.setUserData(SynergyAccount.getSynergyAccount(person), SynergyAccount.SERVER_NAME, person.getSettings().getSystemName());

                    // инициализация приоритетов
                    initPriorityHashMap();

                    // инициализация фрагментов
                    initFragments();

                    // смотрим на версию синерджи
                    getVersion();

                    // загрузка фотографии
                    getPhoto();

                    // получаем настройки для оффлайн режима
                    if (Utils.checkSyncEnables(settings)) {
                        person.setSettings(RestClient.getGson().fromJson(new SettingsTable(activity).get(), Settings.class));
                        initPriorityHashMap();
                    }
                }
                break;
            }
        }

        // если период синхронизации не равен 0 - включаем синхронизацию по таймеру
        if (Utils.checkSyncEnables(settings) && settings.contains(SettingsConst.PERIOD_MILLISECONDS_SYNC)
                && !settings.getString(SettingsConst.PERIOD_MILLISECONDS_SYNC, "").equals("")) {
            new AlarmManagerSync().setAlarm(activity);
        }

        // включаем отправку геоданных
        if (settings.contains(SettingsConst.POSITION_CHECKBOX) && settings.getBoolean(SettingsConst.POSITION_CHECKBOX, false)) {
            new AlarmManagerPosition().setAlarm(activity);
        }

        if (getIntent().getStringExtra(ActivityConst.WORK_ID) != null){
            if (getIntent().getStringExtra(ActivityConst.WORK_ID).length() > 0){
                openWorkActivity(getIntent().getStringExtra(ActivityConst.WORK_ID));
            }
        }else {
            if (getIntent().getExtras() != null) {
                if (getIntent().getExtras().get("workID") != null){
                    openWorkActivity(String.valueOf(getIntent().getExtras().get("workID")));
                }

            }
        }

    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
    }

    private void openWorkActivity(String workID){
        Intent intent = new Intent(activity.getApplicationContext(), WorkInfoActivity.class);
        intent.putExtra(ActivityConst.WORK_ID, workID);
        intent.putExtra(ActivityConst.PERSON, person);
        startActivityForResult(intent, FragmentConst.UPDATE_WORK_LIST);
    }

    /**
     * Авторизация по файлу
     *
     * @param uri uri
     */
    private void importData(Uri uri) {
        String filePath;
        if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
            Cursor cursor = getContentResolver().query(uri,
                    new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
            cursor.moveToFirst();
            filePath = cursor.getString(0);
            cursor.close();
        } else {
            filePath = uri.getPath();
        }
        try {
            StringBuilder buf = new StringBuilder();
            BufferedReader reader = new BufferedReader(new FileReader(filePath));
            String str;
            while ((str = reader.readLine()) != null) {
                buf.append(str);
            }
            FileAuth auth = RestClient.getGson().fromJson(buf.toString(), FileAuth.class);
            Intent intent = new Intent(activity, AuthorizationActivity.class);
            intent.putExtra(SynergyAccount.FILE_AUTH, true);
            intent.putExtra(SynergyAccount.LOGIN, auth.value.login);
            intent.putExtra(SynergyAccount.HOST, auth.value.host);
            startActivity(intent);
        } catch (Exception exc) {
            Logger.v(exc.getLocalizedMessage());
        }
    }

    /**
     * Инициализация фрагментов
     */
    private void initFragments() {

        Bundle bundle = new Bundle();
        bundle.putSerializable(ActivityConst.PERSON, person);

        fragmentWorks = new FragmentWorks();
        fragmentWorks.setArguments(bundle);

        FragmentFiltersWorks fragmentFiltersWorks = new FragmentFiltersWorks();
        fragmentFiltersWorks.setArguments(bundle);

        fragmentDocuments = new FragmentDocuments();
        fragmentDocuments.setArguments(bundle);

        FragmentFiltersDocuments fragmentFiltersDocuments = new FragmentFiltersDocuments();
        fragmentFiltersDocuments.setArguments(bundle);
        fragmentFiltersDocuments.setFragmentDocuments(fragmentDocuments);

        fragmentFiles = new FragmentFilesList();
        fragmentFiles.setArguments(bundle);

        fragmentFilesTree = new FragmentFilesTree();
        fragmentFilesTree.setArguments(bundle);

        fragmentFilesTree.setFragmentList(fragmentFiles);
        fragmentFiles.setFragmentTree(fragmentFilesTree);

        fragmentRegistryList = new FragmentRegistryList();
        fragmentRegistryList.setArguments(bundle);

        FragmentRegistryTree fragmentRegistryTree = new FragmentRegistryTree();
        fragmentRegistryTree.setArguments(bundle);

        fragmentRegistryTree.setFragmentRegistryList(fragmentRegistryList);
        fragmentRegistryList.setFragmentRegistryTree(fragmentRegistryTree);

        FragmentTransaction fTrans = getFragmentManager().beginTransaction();

        // добавление нужных фрагментов в зависимости от типа модуля
        switch (typeModule) {
            case Const.WORKS: {
                fTrans.add(R.id.work_filters_container, fragmentFiltersWorks);
                fTrans.add(R.id.work_list_container, fragmentWorks);
                break;
            }
            case Const.DOCUMENTS: {
                fTrans.add(R.id.work_filters_container, fragmentFiltersDocuments);
                fTrans.add(R.id.work_list_container, fragmentDocuments);
                break;
            }
            case Const.FILES: {
                fTrans.add(R.id.work_filters_container, fragmentFilesTree);
                fTrans.add(R.id.work_list_container, fragmentFiles);
                break;
            }
            case Const.REGISTRY: {
                fTrans.add(R.id.work_filters_container, fragmentRegistryTree);
                fTrans.add(R.id.work_list_container, fragmentRegistryList);
                break;
            }
            case -1: {
                switch (settings.getInt(SettingsConst.DEFAULT_MODULE, Const.WORKS)) {
                    case Const.WORKS: {
                        fTrans.add(R.id.work_filters_container, fragmentFiltersWorks);
                        fTrans.add(R.id.work_list_container, fragmentWorks);
                        typeModule = Const.WORKS;
                        break;
                    }
                    case Const.DOCUMENTS: {
                        fTrans.add(R.id.work_filters_container, fragmentFiltersDocuments);
                        fTrans.add(R.id.work_list_container, fragmentDocuments);
                        typeModule = Const.DOCUMENTS;
                        break;
                    }
                    case Const.FILES: {
                        fTrans.add(R.id.work_filters_container, fragmentFilesTree);
                        fTrans.add(R.id.work_list_container, fragmentFiles);
                        typeModule = Const.FILES;
                        break;
                    }
                    case Const.REGISTRY: {
                        fTrans.add(R.id.work_filters_container, fragmentRegistryTree);
                        fTrans.add(R.id.work_list_container, fragmentRegistryList);
                        typeModule = Const.REGISTRY;
                        break;
                    }
                }
                break;
            }
        }

        fTrans.commit();

        // создаем боковую навигацию для фильтров
        initSlidingMenu();

        // создаем верхнюю панель
        createEventActionBar();

        // доступность кнопки "создать"
        checkAddWorkButton();

        // регистрируемся в гугловском облаке для получения пуш уведомлений
        if (checkPlayServices()) {
            regToken();
        }

    }

    /**
     * Создание ActionBar
     */
    public void createEventActionBar() {

        // сам actionbar
        final RelativeLayout actionBar = (RelativeLayout) findViewById(R.id.general_actionbar);

        // кнопка "боковая навигация"
        filtersButton = (CustomImageView) actionBar.findViewById(R.id.icon_show_filters);
        filtersButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!showedChooseModule) {
                    filtersSlidingMenu.toggle();
                }
            }
        });

        // кнопка "на уровень выше" (только дл модуля файлы)
        searchButton = (CustomImageView) actionBar.findViewById(R.id.icon_search);
        searchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!Utils.isOnline(getBaseContext(), person.getHost())) {
                    return;
                }
                Intent intent = new Intent(activity, SearchFilesActivity.class);
                intent.putExtra(ActivityConst.PERSON, person);
                intent.putExtra(FilesConst.NODE, fragmentFiles.getNode());
                startActivityForResult(intent, SEARCH_FILES);
            }
        });

        if (typeModule == Const.FILES) {
            searchButton.setVisibility(View.VISIBLE);
        }

        // кнопка "добавить"
        addWorkButton = (CustomImageView) actionBar.findViewById(R.id.icon_add_work);
        addWorkButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FragmentCreateWork.hasUsers = false;
                if (person.getSettings() == null) {
                    return;
                }
                if (!Utils.isOnline(getBaseContext(), person.getHost())) {
                    return;
                }
                checkItems();

            }
        });

        // заголовок
        final TextView titleActionBar = (TextView) actionBar.findViewById(R.id.title_action_bar_choose_module);

        // в зависимости от текущего модуля - изменяется заголовок экрана
        switch (typeModule) {
            case Const.WORKS: {
                titleActionBar.setText(getResources().getString(R.string.works));
                break;
            }
            case Const.DOCUMENTS: {
                titleActionBar.setText(getResources().getString(R.string.documents));
                break;
            }
            case Const.FILES: {
                titleActionBar.setText(getResources().getString(R.string.files));
                break;
            }
            case Const.REGISTRY: {
                titleActionBar.setText(R.string.registries);
                break;
            }
        }

        // иконка заголовка экрана (стрелочка вниз-вверх)
        iconActionBar = (ImageView) actionBar.findViewById(R.id.icon_action_bar_choose_module);

        // затемнение списка работ
        shadow = (RelativeLayout) findViewById(R.id.general_shadow_layout);
        shadow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                closePanel();
            }
        });

        // иконка, которая находится в самом верху панели выбора модуля (треугольничек)
        headChooseModuleIcon = (ImageView) findViewById(R.id.head_choose_panel_icon);

        // панель "Выбор модуля"
        chooseModule = (LinearLayout) findViewById(R.id.choose_module);

        // контейнер иконки и лейбла (Работы)
        final LinearLayout worksContainer = (LinearLayout) chooseModule.findViewById(R.id.works_container_choose_module);
        worksContainer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openActivity(Const.WORKS);
            }
        });
        ((TextView) worksContainer.findViewById(R.id.module_chooser_item_works_title)).setTypeface(Fonts.getRoman(activity));

        // контейнер иконки и лейбла (Документы)
        final LinearLayout documentsContainer = (LinearLayout) chooseModule.findViewById(R.id.documents_container_choose_module);
        documentsContainer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openActivity(Const.DOCUMENTS);
            }
        });

        // контейнер иконки и лейбла (Файлы)
        final LinearLayout filesContainer = (LinearLayout) chooseModule.findViewById(R.id.files_container_choose_module);
        filesContainer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openActivity(Const.FILES);
            }
        });

        // контейнер иконки и лейбла (Файлы)
        final LinearLayout registryContainer = (LinearLayout) chooseModule.findViewById(R.id.registry_container_choose_module);
        registryContainer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openActivity(Const.REGISTRY);
            }
        });

        // контейнер, в котором находится заголовок и иконка
        final RelativeLayout container = (RelativeLayout) actionBar.findViewById(R.id.container_action_bar_choose_module);
        container.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showedChooseModule = !showedChooseModule;
                if (showedChooseModule) {
                    openCloseModulePanel(chooseModule, shadow, headChooseModuleIcon, iconActionBar, false);
                    hideButtons();
                } else {
                    openCloseModulePanel(chooseModule, shadow, headChooseModuleIcon, iconActionBar, true);
                    showButtons();
                }
            }
        });

        ((TextView) worksContainer.findViewById(R.id.module_chooser_item_works_title)).setTypeface(Fonts.getMedium(activity));
        ((TextView) documentsContainer.findViewById(R.id.module_chooser_item_documents_title)).setTypeface(Fonts.getMedium(activity));
        ((TextView) filesContainer.findViewById(R.id.module_chooser_item_files_title)).setTypeface(Fonts.getMedium(activity));
        ((TextView) registryContainer.findViewById(R.id.module_chooser_item_registry_title)).setTypeface(Fonts.getMedium(activity));
    }

    /**
     * Метод скрывает все кнопки находящиеся в верхней панели
     */
    private void showButtons() {
        filtersButton.setVisibility(View.VISIBLE);
        addWorkButton.setVisibility(View.VISIBLE);
        if (typeModule == Const.FILES) {
            searchButton.setVisibility(View.VISIBLE);
            fragmentFiles.hidePath(false);
        }
    }

    /**
     * Метод отображает все кнопки находящиеся в верхней панели
     */
    private void hideButtons() {
        filtersButton.setVisibility(View.GONE);
        addWorkButton.setVisibility(View.GONE);
        searchButton.setVisibility(View.GONE);
        if (typeModule == Const.FILES) {
            fragmentFiles.hidePath(true);
        }
    }

    /**
     * Метод открывает активити с указаным модулем
     *
     * @param type модуль, который открываем
     * @see Const#WORKS
     * @see Const#DOCUMENTS
     * @see Const#FILES
     */
    private void openActivity(int type) {
        Intent intent = new Intent(activity, MainActivity.class);
        intent.putExtra(ActivityConst.PERSON, person);
        intent.putExtra(Const.TYPE_MODULE, type);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        overridePendingTransition(0, 0);
    }

    /**
     * Метод загружает избранные пункты
     */
    private void getFavorite() {
        final MainActivity parent = this;
        new SendGetRequest("rest/api/registry/favorite?bookmarks=true&locale=" + MyApplication.getLang(), person) {
            @Override
            protected void onPostExecute(String result) {
                favorite = new Favorite(person, activity);
                favorite.setFavoriteItemListener(new FavoriteItemListener() {
                    @Override
                    public void newFolder() {
                        filtersSlidingMenu.setSlidingEnabled(true);
                        parent.newFolder();
                    }

                    @Override
                    public void showFavoriteActivity() {
                        filtersSlidingMenu.setSlidingEnabled(true);
                        parent.showFavoriteActivity();
                    }

                    @Override
                    public void createWork() {
                        filtersSlidingMenu.setSlidingEnabled(true);
                        parent.createWork();
                    }

                    @Override
                    public void createCustomWork(DialogItem item) {
                        filtersSlidingMenu.setSlidingEnabled(true);
                        parent.createCustomWork(item);
                    }

                    @Override
                    public void fromDevice() {
                        filtersSlidingMenu.setSlidingEnabled(true);
                        parent.fromDevice();
                    }

                    @Override
                    public void fromCamera() {
                        filtersSlidingMenu.setSlidingEnabled(true);
                        parent.fromCamera();
                    }

                    @Override
                    public void createDocument(FavoriteItem item) {
                        filtersSlidingMenu.setSlidingEnabled(true);
                        parent.createDocument(item);
                    }

                    @Override
                    public void newRecord() {
                        filtersSlidingMenu.setSlidingEnabled(true);
                        parent.newRecord();
                    }
                });
                favoriteItems = null;
                try {
                    favoriteItems = RestClient.getGson().fromJson(result, FavoriteItem[].class);
                    favorite.setFavoriteItems(favoriteItems);
                    favorite.setAll(false);
                } catch (Exception exc) {
                    AppMsg.makeText(activity, getString(R.string.favorites_not_found), AppMsg.STYLE_ALERT).show();
                }
                super.onPostExecute(result);
            }
        }.execute();
    }

    /**
     * Создание новой записи реестра
     */
    private void newRecord() {
        fragmentRegistryList.createNewRecord();
    }

    /**
     * Добавление файла с устройства
     */
    public void fromDevice() {
        fragmentFiles.fromDevice();
    }

    /**
     * Метод используется для проверки разрешений к Камере
     */
    public boolean isCameraPermissionGranted() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 101);
                return false;
            }
        } else {
            return true;
        }
    }

    /**
     * Добавление файла с камеры
     */
    public void fromCamera() {
        File folder = new File(Environment.getExternalStorageDirectory() +
                File.separator + Const.DIRECTORY_PHOTOS_NAME + File.separator);
        boolean createdDir = true;
        if (!folder.exists()) {
            createdDir = folder.mkdir();
        }
        if (createdDir) {
            photoName = System.currentTimeMillis();
            Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            Uri uriSavedImage = Uri.fromFile(new File(Environment.getExternalStorageDirectory() +
                    File.separator + Const.DIRECTORY_PHOTOS_NAME + File.separator + photoName + Const.DEFAULT_FILE_FORMAT));
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);

            //UPD: 2023-11-11 - добавил проверку разрешений, иначе приложение крашится
            if (isCameraPermissionGranted()) {
                startActivityForResult(cameraIntent, ActionUtils.PHOTO);
            }
        }
    }

    /**
     * Метод вызывается для создания новой папки в хранилище
     */
    public void newFolder() {
        fragmentFiles.showFolderDialog();
    }

    /**
     * Метод вызывается при нажатии на "Еще" - открывает экран со списком избранных документов
     */
    public void showFavoriteActivity() {
        Intent intent = new Intent(activity, FavoritesActivity.class);
        intent.putExtra(ActivityConst.PERSON, person);
        activity.startActivity(intent);
    }

    /**
     * Метод используется для создания работы используя старый диалог
     */
    public void createWork() {
        for (DialogItem item : person.getSettings().getDialogs()) {
            if (item.getType().equals(ActivityConst.WORK) && item.getDef().equals("true")) {
                Intent intent = new Intent(activity, (item.getSpecial().equals("true") ? CreateWorkCustomActivity.class : CreateWorkActivity.class));
                intent.putExtra(ActivityConst.DIALOG_NAME, item.getName());
                intent.putExtra(ActivityConst.DIALOG_UUID, item.getUuid());
                intent.putExtra(ActivityConst.PERSON, person);
                getFragment().startActivityForResult(intent, FragmentConst.UPDATE_WORK_LIST);
                break;
            }
        }
    }

    /**
     * Метод используется для создания работы используя новый диалог
     *
     * @param item описание текущего диалога
     */
    public void createCustomWork(DialogItem item) {
        Intent intent = new Intent(activity, (item.getSpecial().equals("true") ? CreateWorkCustomActivity.class : CreateWorkActivity.class));
        intent.putExtra(ActivityConst.DIALOG_NAME, item.getName());
        intent.putExtra(ActivityConst.DIALOG_UUID, item.getUuid());
        intent.putExtra(ActivityConst.PERSON, person);
        getFragment().startActivityForResult(intent, FragmentConst.UPDATE_WORK_LIST);
    }

    /**
     * Метод использутся для создания документа
     *
     * @param item описание текущего элемента
     */
    public void createDocument(final FavoriteItem item) {
        // сначала создаем документ
        new SendGetRequest("rest/api/registry/create_doc?registryID=" + item.getRegistryID(), person) {
            @Override
            protected void onPostExecute(String result) {
                try {
                    JSONObject jsonObject = new JSONObject(result);
                    String errorCode = jsonObject.getString("errorCode");
                    if (errorCode.equals(Wrapper.NO_ERROR)) {
                        documentID = jsonObject.getString("documentID");
                        final String dataUUID = jsonObject.getString("dataUUID");

                        Intent intent = new Intent(activity, FormPlayer.class);
                        intent.putExtra(ActivityConst.DATA_UUID, dataUUID);
                        intent.putExtra(ActivityConst.PERSON, person);
                        intent.putExtra(ActivityConst.EDIT, true);
                        intent.putExtra(ActivityConst.CAN_EDIT, "true");
                        startActivityForResult(intent, ActionUtils.SAVE_FORM);

//                        // затем смотрим есть ли у формы для данного документа мобильное представление
//                        new SendGetRequest("rest/api/asforms/form/" + item.getFormID() + "?isMobile=true", person) {
//                            @Override
//                            protected void onPostExecute(String result) {
//                                try {
//                                    Intent intent = new Intent(activity, (result.equals("{}") ? FormPlayer.class : FormPlayerNative.class));
//                                    intent.putExtra(ActivityConst.DATA_UUID, dataUUID);
//                                    intent.putExtra(ActivityConst.PERSON, person);
//                                    intent.putExtra(ActivityConst.EDIT, true);
//                                    intent.putExtra(ActivityConst.CAN_EDIT, "true");
//                                    startActivityForResult(intent, ActionUtils.SAVE_FORM);
//                                } catch (Exception exc) {
//                                    AppMsg.makeText(activity, getString(R.string.error_to_create_document), AppMsg.STYLE_ALERT).show();
//                                }
//                                super.onPostExecute(result);
//                            }
//                        }.execute();

                    } else {
                        String errorMessage = jsonObject.getString("errorMessage");
                        AppMsg.makeText(activity, errorMessage, AppMsg.STYLE_ALERT).show();
                    }
                } catch (Exception exc) {
                    AppMsg.makeText(activity, getString(R.string.error_to_create_document), AppMsg.STYLE_ALERT).show();
                }
                super.onPostExecute(result);
            }
        }.execute();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_CANCELED) {
            return;
        }
        if (requestCode == ActionUtils.PHOTO) {
            fragmentFiles.fromCamera(photoName);
        } else if (requestCode == SEARCH_FILES) {
            Node node = (Node) data.getSerializableExtra(FilesConst.NODE);
            fragmentFilesTree.expandTree(node.getParents());
        } else if (requestCode == ActionUtils.SAVE_FORM) {
            openDocumentInfo();
        }
    }

    /**
     * Метод открывает экран с информацией о работе
     */
    private void openDocumentInfo() {
        if (documentID == null) {
            return;
        }
        // после успешного сохранения данных по форме - открывается экран с информацией о документе
        Intent intent = new Intent(activity, DocumentInfoActivity.class);
        intent.putExtra(ActivityConst.DOCUMENT_ID, documentID);
        intent.putExtra(ActivityConst.PERSON, person);
        intent.putExtra(DocumentConst.TYPE_ITEM_DOCUMENTS, DocumentConst.ALL);
        startActivityForResult(intent, FragmentConst.UPDATE_WORK_LIST);
        documentID = null;
    }

    /**
     * Метод используется для загрузки фотографии пользователя
     */
    private void getPhoto() {
        DownloadFile downloadFile = new DownloadFile(activity, person);
        downloadFile.setFileName(Const.USER_ICON_NAME);
        downloadFile.setOnlyGet(true);
        downloadFile.setUrl(person.getHost() + "rest/api/person/photo/load?userid=" + person.getUuid());
        downloadFile.execute();
    }

    /**
     * Метод смотрит какая версия синерджи стоит на сервере, если меньше нужной - отображается сообщение
     */
    private void getVersion() {
        new SendGetRequest("about", person) {
            @Override
            protected void onPostExecute(String result) {
                try {
                    if (result == null) {
                        return;
                    }
                    int position = -1;
                    String stable = "stable.";
                    String trunk = "trunk.";
                    int length = 0;
                    if (result.contains(stable)) {
                        position = result.indexOf(stable);
                        length = stable.length();
                    } else if (result.contains(trunk)) {
                        position = result.indexOf(trunk);
                        length = trunk.length();
                    }
                    if (position == -1) {
                        AppMsg.makeText(activity, getString(R.string.error_to_get_synergy_version), AppMsg.STYLE_CONFIRM).show();
                        return;
                    }
                    int indexOfTire = result.lastIndexOf("-");
                    if (indexOfTire == -1) {
                        AppMsg.makeText(activity, getString(R.string.error_to_get_synergy_version), AppMsg.STYLE_CONFIRM).show();
                        return;
                    }
                    String version = result.substring(position + length, indexOfTire);
                    SharedPreferences.Editor editor = settings.edit();
                    editor.putFloat(SettingsConst.SYNERGY_VERSION, Float.valueOf(version));
                    editor.apply();

                    // отображение сообщения об ошибке
                    if (Const.CURRENT_VERSION_SYNERGY.compareTo(new BigDecimal(version)) == 1) {
                        AppMsg.makeText(activity, "Внимание! На сервере " + person.getHost() + " используется версия ARTA Synergy ниже " + Const.CURRENT_VERSION_SYNERGY.setScale(2, RoundingMode.DOWN) + ". " +
                                "Возможна нестабильная работа приложения.", AppMsg.STYLE_CONFIRM).show();
                    }
                } catch (Exception exc) {
                    AppMsg.makeText(activity, "Внимание! На сервере " + person.getHost() + " используется версия ARTA Synergy ниже " + Const.CURRENT_VERSION_SYNERGY.setScale(2, RoundingMode.DOWN) + ". " +
                            "Возможна нестабильная работа приложения.", AppMsg.STYLE_CONFIRM).show();
                }
                super.onPostExecute(result);
            }
        }.execute();
    }

    /**
     * Метод проверяет нужно ли показывать диалог либо сразу открывать экран "Избранные"
     */
    private void checkItems() {
        switch (typeModule) {
            case Const.WORKS: {
                if (person.getSettings().getWorkItems() != null && person.getSettings().getWorkItems().length == 1 &&
                        person.getSettings().getWorkItems()[0].getId().equals(FavoritesConsts.ALL)) {
                    openFavoritesActivity();
                } else {
                    showDialog();
                }
                break;
            }
            case Const.DOCUMENTS: {
                if (person.getSettings().getDocumentItems() != null && person.getSettings().getDocumentItems().length == 1 &&
                        person.getSettings().getDocumentItems()[0].getId().equals(FavoritesConsts.ALL)) {
                    openFavoritesActivity();
                } else {
                    showDialog();
                }
                break;
            }
            case Const.FILES: {
                if (person.getSettings().getFileItems() != null && person.getSettings().getFileItems().length == 1 &&
                        person.getSettings().getFileItems()[0].getId().equals(FavoritesConsts.ALL)) {
                    openFavoritesActivity();
                } else {
                    showDialog();
                }
                break;
            }
            case Const.REGISTRY: {
                if (person.getSettings().getRegistryItems() != null && person.getSettings().getRegistryItems().length == 1) {
                    if (person.getSettings().getRegistryItems()[0].getId().equals(FavoritesConsts.ALL)) {
                        openFavoritesActivity();
                    } else if (person.getSettings().getRegistryItems()[0].getId().equals(FavoritesConsts.NEW_RECORD)) {
                        fragmentRegistryList.createNewRecord();
                    } else if (person.getSettings().getRegistryItems()[0].getId().equals(FavoritesConsts.DOCUMENTS)) {
                        showDialog();
                    }
                } else {
                    showDialog();
                }
                break;
            }
        }
    }

    /**
     * Метод отображает диалог при нажатии на кнопку "Создать"
     */
    private void showDialog() {
        filtersSlidingMenu.setSlidingEnabled(false);
        showedChooseModule = !showedChooseModule;
        shadow.setVisibility(View.VISIBLE);
        shadow.startAnimation(AnimationUtils.loadAnimation(activity, R.anim.start_animation_activity));
        if (fragmentFiles.getNode() == null) {
            favorite.initCreateMenuItems(getDialog(), typeModule, 0, fragmentRegistryList.getRegistry());
        } else {
            favorite.initCreateMenuItems(getDialog(), typeModule, fragmentFiles.getNode().getRight(), null);
        }
    }

    /**
     * Метод открыает экран со всеми избранными элементами
     */
    private void openFavoritesActivity() {
        Intent intent = new Intent(activity, FavoritesActivity.class);
        intent.putExtra(ActivityConst.PERSON, person);
        activity.startActivity(intent);
    }

    /**
     * Метод возвращает диалог
     *
     * @return linearLayout
     */
    private LinearLayout getDialog() {
        parentDialogLayout.setVisibility(View.VISIBLE);
        parentDialogLayout.startAnimation(AnimationUtils.loadAnimation(activity, R.anim.start_animation_activity));
        ((TextView) parentDialogLayout.findViewById(R.id.create_menu_dialog_title)).setTypeface(Fonts.getRoman(activity));
        LinearLayout dialogLayout = (LinearLayout) parentDialogLayout.findViewById(R.id.create_menu_dialog);
        dialogLayout.removeAllViews();
        dialogLayout.addView(favorite.getSplit());
        return dialogLayout;
    }

    /**
     * Метод скрывает/открывает панель выбора модулей
     *
     * @param chooseModule         - выбранный модуль
     * @param shadow               - затемнение
     * @param headChooseModuleIcon - треугольничек
     * @param iconActionBar        - иконка в actionbar'e
     */
    private void openCloseModulePanel(LinearLayout chooseModule, RelativeLayout shadow,
                                      ImageView headChooseModuleIcon, ImageView iconActionBar, boolean close) {
        if (close) {
            chooseModule.setVisibility(View.GONE);
            shadow.setVisibility(View.GONE);
            headChooseModuleIcon.setVisibility(View.GONE);
            iconActionBar.setBackgroundResource(R.drawable.modules_down);
            filtersSlidingMenu.setSlidingEnabled(true);
        } else {
            chooseModule.setVisibility(View.VISIBLE);
            chooseModule.startAnimation(AnimationUtils.loadAnimation(activity, R.anim.start_animation_activity));
            shadow.setVisibility(View.VISIBLE);
            shadow.startAnimation(AnimationUtils.loadAnimation(activity, R.anim.start_animation_activity));
            headChooseModuleIcon.setVisibility(View.VISIBLE);
            headChooseModuleIcon.startAnimation(AnimationUtils.loadAnimation(activity, R.anim.start_animation_activity));
            iconActionBar.setBackgroundResource(R.drawable.modules_up);
            filtersSlidingMenu.setSlidingEnabled(false);
        }
    }

    /**
     * Инициализация боковой навигации для фильтров
     */
    private void initSlidingMenu() {
        filtersSlidingMenu = new SlidingMenu(getApplicationContext());
        filtersSlidingMenu.setMode(SlidingMenu.LEFT);
        filtersSlidingMenu.attachToActivity(activity, SlidingMenu.SLIDING_CONTENT);
        filtersSlidingMenu.setMenu(R.layout.filters_works);
        filtersSlidingMenu.setBehindWidth(Utils.convertDpToPixel(Const.SLIDING_MENU_WIDTH, activity));
    }

    /**
     * Регистрируемся в гугловском облаке для получения пуш-уведомлений
     */
    public void regToken() {
        RegToken regToken = new RegToken();
        regToken.execute();
    }

    /**
     * Инициализация хешмапов приоритетов
     */
    private void initPriorityHashMap() {
        Map<String, PriorityItem> current = new HashMap<>();
        if (person.getSettings() == null) {
            return;
        }
        if (person.getSettings().getCurrentPriorities() != null) {
            for (PriorityItem item : person.getSettings().getCurrentPriorities()) {
                current.put(item.getId(), item);
            }
            person.setCurrentPriorityItemHashMap(current);
        }
        Map<String, PriorityItem> all = new HashMap<>();
        if (person.getSettings().getAllPriorities() != null) {
            for (PriorityItem item : person.getSettings().getAllPriorities()) {
                all.put(item.getId(), item);
            }
            person.setPriorityItemHashMap(all);
        }
    }

    /**
     * Проверка доступности получать пуш уведомления
     *
     * @return true/false
     */
    private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, this, SendGetRequest.TIMEOUT).show();
            } else {
                finish();
            }
            return false;
        }
        return true;
    }

    public void setFragmentBackPressedListener(FragmentBackPressedListener fragmentBackPressedListener) {
        this.fragmentBackPressedListener = fragmentBackPressedListener;
    }

    @Override
    public void onBackPressed() {
        // если открыт выбор модулей
        if (showedChooseModule) {
            closePanel();
        } else if (fragmentBackPressedListener != null) {
            fragmentBackPressedListener.doBack();
        } else {
            super.onBackPressed();
        }
    }

    /**
     * Метод закрывает панель выбора модулей
     */
    private void closePanel() {
        showedChooseModule = !showedChooseModule;
        iconActionBar.setBackgroundResource(R.drawable.modules_down);
        shadow.setVisibility(View.GONE);
        chooseModule.setVisibility(View.GONE);
        headChooseModuleIcon.setVisibility(View.GONE);
        filtersSlidingMenu.setSlidingEnabled(true);
        if (parentDialogLayout != null) {
            parentDialogLayout.setVisibility(View.GONE);
        }
        showButtons();
        checkAddWorkButton();
    }

    /**
     * Проверка доступности кнопки "Создать"
     */
    private void checkAddWorkButton() {
        switch (typeModule) {
            case Const.WORKS: {
                if (person.getSettings() != null && person.getSettings().getWorkItems() != null
                        && person.getSettings().getWorkItems().length == 0) {
                    addWorkButton.setVisibility(View.GONE);
                }
                break;
            }
            case Const.DOCUMENTS: {
                if (person.getSettings() != null && person.getSettings().getDocumentItems() != null
                        && person.getSettings().getDocumentItems().length == 0) {
                    addWorkButton.setVisibility(View.GONE);
                }
                break;
            }
            case Const.FILES: {
                if (person.getSettings() != null && person.getSettings().getFileItems() != null
                        && person.getSettings().getFileItems().length == 0) {
                    addWorkButton.setVisibility(View.GONE);
                }
                break;
            }
            case Const.REGISTRY: {
                if (person.getSettings() != null && person.getSettings().getRegistryItems() != null
                        && person.getSettings().getRegistryItems().length == 0) {
                    addWorkButton.setVisibility(View.GONE);
                }
                break;
            }
        }
    }

    /**
     * Метод возвращает текущий фрагмент
     *
     * @return фрагмент
     */
    public Fragment getFragment() {
        if (typeModule == Const.WORKS) {
            return fragmentWorks;
        } else if (typeModule == Const.DOCUMENTS) {
            return fragmentDocuments;
        } else if (typeModule == Const.FILES) {
            return fragmentFiles;
        } else if (typeModule == Const.REGISTRY) {
            return fragmentRegistryList;
        }
        return null;
    }

    @Override
    protected void onResumeFragments() {
        getFavorite();
        super.onResumeFragments();
    }

    public SlidingMenu getFiltersSlidingMenu() {
        return filtersSlidingMenu;
    }

    public RelativeLayout getShadow() {
        return shadow;
    }

    public LinearLayout getParentDialogLayout() {
        return parentDialogLayout;
    }

    public void setShowed() {
        showedChooseModule = !showedChooseModule;
    }

    /**
     * Класс для регистрации в гугловском сервисе для получения уведомлений
     */
    class RegToken extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... voids) {
            try {
                String registrationID = FirebaseInstanceId.getInstance().getToken();

                Log.e("newToken", registrationID);

                SharedPreferences.Editor editor = settings.edit();
                editor.putString(SettingsConst.TOKEN, registrationID);
                editor.apply();
                new SendGetRequest(person).requestGET(person.getHost() + "rest/api/mobile/utils/add_token?token=" + registrationID + "&type=android");
//                    FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener((Executor) this, new OnSuccessListener<InstanceIdResult>() {
//                        @Override
//                        public void onSuccess(InstanceIdResult instanceIdResult) {
//                            String registrationID = instanceIdResult.getToken();
//                            Log.e("newToken", registrationID);
//
//                            SharedPreferences.Editor editor = settings.edit();
//                            editor.putString(SettingsConst.TOKEN, registrationID);
//                            editor.apply();
//                            new SendGetRequest(person).requestGET(person.getHost() + "rest/api/mobile/utils/add_token?token=" + registrationID + "&type=android");
//                        }
//                    });
            } catch (Exception ignored) {
            }
            return null;
        }
    }

    /**
     * Авторизация через файл
     */
    class FileAuth {

        Value value;

        class Value {

            String host;

            String login;
        }
    }

    protected void onResume() {
        super.onResume();
        mMyApp.setCurrentActivity(this);
    }
}