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

import android.Manifest;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
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.widget.SwipeRefreshLayout;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;

import com.devspark.appmsg.AppMsg;
import com.pnikosis.materialishprogress.ProgressWheel;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import kz.arta.synergy.workflow.mobile.android.R;
import kz.arta.synergy.workflow.mobile.android.attachments.adapters.AdapterAttachments;
import kz.arta.synergy.workflow.mobile.android.attachments.models.AllAttachmentsItem;
import kz.arta.synergy.workflow.mobile.android.attachments.models.AttachmentItem;
import kz.arta.synergy.workflow.mobile.android.authorization.activities.QrCodeActivity;
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.components.OpenFileDialog;
import kz.arta.synergy.workflow.mobile.android.common.models.ErrorCode;
import kz.arta.synergy.workflow.mobile.android.common.models.Person;
import kz.arta.synergy.workflow.mobile.android.common.models.offline.OfflineAttachment;
import kz.arta.synergy.workflow.mobile.android.common.offline.add.AddAttachment;
import kz.arta.synergy.workflow.mobile.android.common.offline.add.AddRemoveAttachment;
import kz.arta.synergy.workflow.mobile.android.common.offline.get.WorkAttachmentsTable;
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.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.offline.DocumentAttachmentsTable;
import kz.arta.synergy.workflow.mobile.android.documents.offline.actions.DocumentAddAttachmentTable;
import kz.arta.synergy.workflow.mobile.android.documents.offline.actions.DocumentRemoveAttachmentTable;
import kz.arta.synergy.workflow.mobile.android.files.FilesConst;
import kz.arta.synergy.workflow.mobile.android.files.activities.FilesTreeActivity;
import kz.arta.synergy.workflow.mobile.android.files.manager.DownloadFile;
import kz.arta.synergy.workflow.mobile.android.files.manager.FilesManager;
import kz.arta.synergy.workflow.mobile.android.files.manager.UploadFile;
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.forms.mobile.activities.FormPlayerNative;

/**
 * Created by neox on 10.04.14.
 * Экран со списком всех вложений
 */
public class AllAttachmentsActivity extends Activity {

    private static final int PHOTO = 1;

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

    /**
     * Активити
     */
    private Activity activity;

    /**
     * Главный контейнер (ScrollView with PullToRefresh)
     */
    private SwipeRefreshLayout mainContent;

    /**
     * Прогрессбар
     */
    private ProgressWheel progressBar;

    /**
     * Настройки
     */
    private SharedPreferences settings;

    /**
     * UUID работы для которой получаются вложения
     */
    private String workID;

    /**
     * UUID документа для которого получаются вложения
     */
    private String documentID;

    /**
     * Имя работы для которой получаются комментарии (нужен для оффлайн режима)
     */
    private String name;

    /**
     * Вложения
     */
    private List<AttachmentItem> generalArray = new ArrayList<>();

    /**
     * Прочие
     */
    private List<AttachmentItem> othersArray = new ArrayList<>();

    /**
     * Адаптер для вложений
     */
    private AdapterAttachments adapterGeneralList;

    /**
     * Адаптер для прочих
     */
    private AdapterAttachments adapterOthersList;

    /**
     * Список "Вложения"
     */
    private ListView generalList;

    /**
     * Список "Прочие"
     */
    private ListView othersList;

    /**
     * Лейбл к списку "Вложения"
     */
    private TextView attachmentTitle;

    /**
     * Лейбл к списку "Прочие"
     */
    private TextView othersTitle;

    /**
     * UUID выделенного ф айла
     */
    private String fileUUID;

    /**
     * Имя выделенного файла
     */
    private String fileName;

    /**
     * Имя снимка сделанного с камеры
     */
    private long photoFileName;

    /**
     * Версия синерджи
     */
    private float versionSynergy;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

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

        activity = this;

        Intent intent = getIntent();
        person = (Person) intent.getSerializableExtra(ActivityConst.PERSON);
        documentID = intent.getStringExtra(ActivityConst.DOCUMENT_ID);
        workID = intent.getStringExtra(ActivityConst.WORK_ID);
        name = intent.getStringExtra(ActivityConst.WORK_NAME);

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

        settings = getSharedPreferences(SettingsConst.DEFAULT_NAME_SETTINGS, Context.MODE_PRIVATE);

        versionSynergy = settings.getFloat(SettingsConst.SYNERGY_VERSION, 0);

        progressBar = (ProgressWheel) findViewById(R.id.all_attachments_progress_bar);

        mainContent = (SwipeRefreshLayout) findViewById(R.id.all_attachments_refresh);
        mainContent.setColorSchemeResources(R.color.color1_update_list, R.color.color2_update_list,
                R.color.color3_update_list, R.color.color4_update_list);
        mainContent.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                mainContent.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        updateList();
                    }
                }, 0);
            }
        });

        CustomImageView addButton = (CustomImageView) findViewById(R.id.all_attachments_add_button);
        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showActionsDialog();
            }
        });

        adapterGeneralList = new AdapterAttachments(activity, generalArray, person);
        adapterOthersList = new AdapterAttachments(activity, othersArray, person);

        generalList = (ListView) findViewById(R.id.general_attachments);
        othersList = (ListView) findViewById(R.id.others_attachments);

        generalList.setAdapter(adapterGeneralList);
        othersList.setAdapter(adapterOthersList);

        progressBar.setVisibility(View.VISIBLE);

        generalList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                if (generalArray.get(i).getDataUUID() != null) {
                    if (versionSynergy < 3.7) {
                        openFile(generalArray.get(i).getName(), generalArray.get(i).getUuid());
                        return;
                    }
                    // если есть мобильное представление
                    if (generalArray.get(i).getMobile().equals("true")) {
                        Intent intent = new Intent(activity, FormPlayerNative.class);
                        intent.putExtra(ActivityConst.DATA_UUID, generalArray.get(i).getDataUUID());
                        intent.putExtra(ActivityConst.PERSON, person);
                        intent.putExtra(ActivityConst.CAN_EDIT, generalArray.get(i).getIs_editable());
                        activity.startActivityForResult(intent, ActionUtils.SAVE_FORM);
                    } else {
                        Intent intent = new Intent(activity, FormPlayer.class);
                        intent.putExtra(ActivityConst.DATA_UUID, generalArray.get(i).getDataUUID());
                        intent.putExtra(ActivityConst.PERSON, person);
                        intent.putExtra(ActivityConst.CAN_EDIT, generalArray.get(i).getIs_editable());
                        activity.startActivityForResult(intent, ActionUtils.SAVE_FORM);
                    }
                } else {
                    openFile(generalArray.get(i).getName(), generalArray.get(i).getUuid());
                }
            }
        });

        generalList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> adapterView, View view, final int i, long l) {
                AlertDialog.Builder builder = new AlertDialog.Builder(activity);
                builder.setTitle(getString(R.string.actions));
                final List<String> items = new ArrayList<>();
                if (generalArray.get(i).getIs_editable().equals("true")) {
                    items.add(activity.getString(R.string.delete));
                }
                builder.setItems(items.toArray(new String[items.size()]), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int item) {
                        if (generalArray.get(i).getDate() != null) {
                            removeOfflineAttachmentDialog(generalArray.get(i));
                        } else {
                            removeAttachmentDialog(generalArray.get(i));
                        }
                    }
                });
                builder.setCancelable(true);
                if (!items.isEmpty()) {
                    builder.show();
                }
                return true;
            }
        });

        othersList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                if (othersArray.get(i).getDataUUID() != null) {
                    if (versionSynergy < 3.7) {
                        openFile(generalArray.get(i).getName(), generalArray.get(i).getUuid());
                        return;
                    }
                    // если есть мобильное представление
                    if (othersArray.get(i).getMobile().equals("true")) {
                        Intent intent = new Intent(activity, FormPlayerNative.class);
                        intent.putExtra(ActivityConst.DATA_UUID, othersArray.get(i).getDataUUID());
                        intent.putExtra(ActivityConst.PERSON, person);
                        intent.putExtra(ActivityConst.CAN_EDIT, othersArray.get(i).getIs_editable());
                        activity.startActivityForResult(intent, ActionUtils.SAVE_FORM);
                    } else {
                        Intent intent = new Intent(activity, FormPlayer.class);
                        intent.putExtra(ActivityConst.DATA_UUID, othersArray.get(i).getDataUUID());
                        intent.putExtra(ActivityConst.PERSON, person);
                        intent.putExtra(ActivityConst.CAN_EDIT, othersArray.get(i).getIs_editable());
                        activity.startActivityForResult(intent, ActionUtils.SAVE_FORM);
                    }
                } else {
                    openFile(othersArray.get(i).getName(), othersArray.get(i).getUuid());
                }
            }
        });

        othersList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> adapterView, View view, final int i, long l) {
                AlertDialog.Builder builder = new AlertDialog.Builder(activity);
                builder.setTitle(getString(R.string.actions));
                final List<String> items = new ArrayList<>();
                if (othersArray.get(i).getIs_editable().equals("true")) {
                    items.add(activity.getString(R.string.delete));
                }
                builder.setItems(items.toArray(new String[items.size()]), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int item) {
                        if (othersArray.get(i).getDate() != null) {
                            removeOfflineAttachmentDialog(othersArray.get(i));
                        } else {
                            removeAttachmentDialog(othersArray.get(i));
                        }
                    }
                });
                builder.setCancelable(true);
                if (!items.isEmpty()) {
                    builder.show();
                }
                return true;
            }
        });

        attachmentTitle = (TextView) findViewById(R.id.attachment_text);
        othersTitle = (TextView) findViewById(R.id.others_text);

        updateList();
    }

    /**
     * Метод отображает диалог с пунктами добавления чего-либо к работе/документу
     */
    private void showActionsDialog() {
        if (Utils.isOnline(getBaseContext(), person.getHost())) {
            String[] items = {
                    getString(R.string.file_from_storage),
                    getString(R.string.file_from_camera),
                    getString(R.string.photo)
            };
            AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
            dialog.setTitle(R.string.add);
            dialog.setItems(items, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, final int pos) {
                    switch (pos) {
                        case 0: {
                            addFileFromStorage();
                            break;
                        }
                        case 1: {
                            addFileFromDevice();
                            break;
                        }
                        case 2: {
                            addFileFromCamera();
                            break;
                        }
                    }
                }
            });
            dialog.setCancelable(true);
            dialog.show();
        } else {
            String[] items = {
                    getString(R.string.file_from_camera),
                    getString(R.string.photo)
            };
            AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
            dialog.setTitle(R.string.add);
            dialog.setItems(items, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, final int pos) {
                    switch (pos) {
                        case 0: {
                            addFileFromDevice();
                            break;
                        }
                        case 1: {
                            addFileFromCamera();
                            break;
                        }
                    }
                }
            });
            dialog.setCancelable(true);
            dialog.show();
        }
    }

    /**
     * Метод используется для проверки разрешений к Камере
     */
    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;
        }
    }

    /**
     * Метод используется для добавления нового файла к работе/документу с камеры
     */
    private void addFileFromCamera() {
        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) {
            photoFileName = 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 + photoFileName + Const.DEFAULT_FILE_FORMAT));
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);

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

    /**
     * Метод используется для добавления нового файла к работе/документу с устройства
     */
    private void addFileFromDevice() {
        final OpenFileDialog fileDialog = new OpenFileDialog(activity);
        fileDialog.setOpenDialogListener(new OpenFileDialog.OpenDialogListener() {
            @Override
            public void OnSelectedFile(String fileName) {
                if (Utils.isOnline(activity, person.getHost())) {
                    AddFile addFile = new AddFile();
                    addFile.setFileName(new File(fileName).getName());
                    addFile.setFilePath(fileName);
                    addFile.setUuid(workID);
                    addFile.execute();
                } else if (Utils.checkSyncEnables(settings)) {
                    if (documentID != null) {
                        DocumentAddAttachmentTable add = new DocumentAddAttachmentTable(activity);
                        add.add(documentID, fileName, String.valueOf(System.currentTimeMillis()), name, new File(fileName).getName());
                    } else if (workID != null) {
                        AddAttachment addAttachmentInTable = new AddAttachment(activity);
                        addAttachmentInTable.add(workID, fileName, String.valueOf(System.currentTimeMillis()), name, new File(fileName).getName());
                    }
                    updateList();
                }
            }
        });
        fileDialog.show();
    }

    /**
     * Метод используется для открытия экрана добавления нового файла к работе/документу из хранилища
     */
    private void addFileFromStorage() {
        Intent intent = new Intent(activity, FilesTreeActivity.class);
        intent.putExtra(FilesConst.SHOW_FILES, true);
        intent.putExtra(ActivityConst.PERSON, person);
        startActivityForResult(intent, ActionUtils.UPLOAD_FILE_FROM_STORAGE);
    }

    /**
     * Диалог вызывается при удалении вложения
     *
     * @param item пункт вложения
     */
    private void removeAttachmentDialog(final AttachmentItem item) {
        fileUUID = item.getUuid();
        fileName = item.getName();
        if (item.getIs_editable() != null && item.getIs_editable().equals("true")) {
            AlertDialog.Builder ad = new AlertDialog.Builder(activity);
            ad.setTitle(getString(R.string.deleting_file));
            ad.setMessage(getString(R.string.are_u_sure_deleting_file_question) + "?");
            ad.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int arg1) {
                    progressBar.setVisibility(View.VISIBLE);
                    RemoveAttachmentRequest removeAttachmentRequest = new RemoveAttachmentRequest();
                    removeAttachmentRequest.execute();
                }
            });
            ad.setNegativeButton(getString(R.string.no), null);
            ad.setCancelable(true);
            ad.show();
        }
    }

    /**
     * Диалог вызывается при удалении вложения (для оффлайн режима)
     *
     * @param item пункт вложения
     */
    private void removeOfflineAttachmentDialog(final AttachmentItem item) {
        if (item.getDate() != null) {
            AlertDialog.Builder ad = new AlertDialog.Builder(activity);
            ad.setTitle(getString(R.string.deleting_file));
            ad.setMessage(getString(R.string.are_u_sure_deleting_file_question) + "?");
            ad.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int arg1) {
                    new AddAttachment(activity).removeAttachmentByDate(item.getDate());
                    updateList();
                }
            });
            ad.setNegativeButton(getString(R.string.no), null);
            ad.setCancelable(true);
            ad.show();
        }
    }

    /**
     * Используется для открытия файла
     *
     * @param fileName - имя файла
     * @param uuid     - uuid файла
     */
    private void openFile(String fileName, String uuid) {
        if (Utils.isOnline(activity, person.getHost())) {
            DownloadFile downloadFile = new DownloadFile(activity, person);
            downloadFile.setFileName(fileName);
            downloadFile.setUrl(person.getHost() + "rest/api/storage/pdf/get?identifier=" + uuid);
            downloadFile.execute();
        } else if (Utils.checkSyncEnables(settings)) {
            String filePath = new WorkAttachmentsTable(activity).getFilePathByUUID(uuid);
            if (filePath != null) {
                String mime = Utils.getMimeByFilename(filePath);
                Intent intent = new Intent();
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setAction(Intent.ACTION_VIEW);
                intent.setDataAndType(Uri.fromFile(new File(filePath)), mime);
                try {
                    activity.startActivity(intent);
                } catch (ActivityNotFoundException e) {
                    AppMsg.makeText(activity, activity.getString(R.string.unknown_file), AppMsg.STYLE_ALERT).show();
                }
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_CANCELED) {
            if (requestCode == PHOTO) {
                final String filePath = Environment.getExternalStorageDirectory() + File.separator +
                        Const.DIRECTORY_PHOTOS_NAME + File.separator + photoFileName + Const.DEFAULT_FILE_FORMAT;
                final String fileName = Utils.getNewPhotoName(photoFileName, getBaseContext());
                if (Utils.isOnline(activity, person.getHost())) {
                    AddFile addFile = new AddFile();
                    addFile.setFileName(fileName);
                    addFile.setFilePath(filePath);
                    addFile.setUuid(workID);
                    addFile.execute();
                } else if (Utils.checkSyncEnables(settings) && workID != null) {
                    AddAttachment addAttachmentInTable = new AddAttachment(activity);
                    addAttachmentInTable.add(workID, filePath, String.valueOf(System.currentTimeMillis()), name, fileName);
                    updateList();
                }
            } else if (requestCode == ActionUtils.UPLOAD_FILE_FROM_STORAGE) {
                Node node = (Node) data.getSerializableExtra(FilesConst.NODE);
                if (node != null) {
                    addFileFromStorage(node.getIdentifier(), UploadFile.INBOX_FILE);
                }
            }
        }
    }

    /**
     * Метод используется для добавления нового файла в работу из хранилища
     *
     * @param uuid идентификатор файла
     */
    private void addFileFromStorage(final String uuid, final String container) {
        new AsyncTask<Void, Void, String>() {
            @Override
            protected void onPostExecute(String result) {
                if (result == null) {
                    AppMsg.makeText(activity, getString(R.string.error_to_copy_file), AppMsg.STYLE_ALERT).show();
                }
                try {
                    ErrorCode errorCode = RestClient.getGson().fromJson(result, ErrorCode.class);
                    if (errorCode.getErrorCode().equals(Wrapper.ERROR)) {
                        AppMsg.makeText(activity, errorCode.getErrorMessage(), AppMsg.STYLE_ALERT).show();
                    } else if (errorCode.getErrorCode().equals(Wrapper.NO_ACCESS)) {
                        addFileFromStorage(uuid, UploadFile.WORK_FILE);
                    }
                } catch (Exception exc) {
                    updateList();
                }
                super.onPostExecute(result);
            }

            @Override
            protected String doInBackground(Void... voids) {
                try {
                    if (documentID == null) {
                        return new FilesManager(person).copy(RestClient.getGson().fromJson(new SendGetRequest(person).requestGET(person.getHost() +
                                "rest/api/workflow/work/" + workID + "/document"), DocumentID.class).documentID, uuid, container);
                    } else {
                        return new FilesManager(person).copy(documentID, uuid, container);
                    }
                } catch (Exception exc) {
                    return null;
                }
            }
        }.execute();
    }

    private void updateList() {
        new GetAttach().execute();
    }

    @Override
    public void onBackPressed() {
        Intent intent = new Intent();
        setResult(RESULT_OK, intent);
        finish();
    }

    class DocumentID {
        String documentID;
    }

    class GetAttach extends AsyncTask<Void, Void, String> {

        @Override
        protected void onPreExecute() {
            generalArray.clear();
            othersArray.clear();
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String result) {
            mainContent.setRefreshing(false);
            progressBar.setVisibility(View.GONE);
            if (result != null) {
                try {
                    if (documentID != null) {
                        AllAttachmentsItem attachments = RestClient.getGson().fromJson(result, AllAttachmentsItem.class);
                        if (attachments != null) {
                            // ------ приложения ------ //
                            if (!attachments.getAttachments().isEmpty()) {
                                List<AttachmentItem> general = attachments.getAttachments();
                                for (AttachmentItem attachmentItem : general) {
                                    generalArray.add(attachmentItem);
                                }
                                Utils.setListViewHeightBasedOnChildren(generalList);
                                adapterOthersList.notifyDataSetChanged();
                                generalList.setVisibility(View.VISIBLE);
                                attachmentTitle.setVisibility(View.VISIBLE);
                            } else {
                                generalList.setVisibility(View.GONE);
                                attachmentTitle.setVisibility(View.GONE);
                            }
                            // ------ прочие ------ //
                            if (!attachments.getWork_files().isEmpty()) {
                                List<AttachmentItem> others = attachments.getWork_files();
                                for (AttachmentItem attachmentItem : others) {
                                    othersArray.add(attachmentItem);
                                }
                                Utils.setListViewHeightBasedOnChildren(othersList);
                                adapterGeneralList.notifyDataSetChanged();
                                othersList.setVisibility(View.VISIBLE);
                                othersTitle.setVisibility(View.VISIBLE);
                            } else {
                                othersList.setVisibility(View.GONE);
                                othersTitle.setVisibility(View.GONE);
                            }
                        }
                    } else if (workID != null) {
                        AllAttachmentsItem[] attachments = RestClient.getGson().fromJson(result, AllAttachmentsItem[].class);
                        if (attachments != null) {
                            // ------ приложения ------ //
                            if (!attachments[0].getAttachments().isEmpty()) {
                                List<AttachmentItem> general = attachments[0].getAttachments();
                                for (AttachmentItem attachmentItem : general) {
                                    generalArray.add(attachmentItem);
                                }
                                Utils.setListViewHeightBasedOnChildren(generalList);
                                adapterOthersList.notifyDataSetChanged();
                                generalList.setVisibility(View.VISIBLE);
                                attachmentTitle.setVisibility(View.VISIBLE);
                            } else {
                                generalList.setVisibility(View.GONE);
                                attachmentTitle.setVisibility(View.GONE);
                            }
                            // ------ прочие ------ //
                            if (!attachments[1].getWork_files().isEmpty()) {
                                List<AttachmentItem> others = attachments[1].getWork_files();
                                for (AttachmentItem attachmentItem : others) {
                                    othersArray.add(attachmentItem);
                                }
                                Utils.setListViewHeightBasedOnChildren(othersList);
                                adapterGeneralList.notifyDataSetChanged();
                                othersList.setVisibility(View.VISIBLE);
                                othersTitle.setVisibility(View.VISIBLE);
                            } else {
                                othersList.setVisibility(View.GONE);
                                othersTitle.setVisibility(View.GONE);
                            }
                        }
                    }
                } catch (Exception exc) {
                    AppMsg.makeText(activity, exc.getLocalizedMessage(), AppMsg.STYLE_ALERT).show();
                }
            } else if (Utils.checkSyncEnables(settings)) {
                if (workID != null) {
                    List<AttachmentItem> allAttachments = new ArrayList<>();
                    List<OfflineAttachment> offlineAttachments = new AddAttachment(activity).getByWorkID(workID);
                    for (OfflineAttachment offlineAttachment : offlineAttachments) {
                        AttachmentItem attach = new AttachmentItem();
                        attach.setName(new File(offlineAttachment.getFilepath()).getName());
                        attach.setType("attachments");
                        attach.setActionID(offlineAttachment.getActionID());
                        attach.setDate(offlineAttachment.getDate());
                        attach.setIs_editable("true");
                        allAttachments.add(attach);
                    }
                    // добавляем остальные вложения
                    List<AttachmentItem> current = new WorkAttachmentsTable(activity).get(workID);
                    for (AttachmentItem aCurrent : current) {
                        allAttachments.add(aCurrent);
                    }
                    // -------- приложения -------- //
                    generalArray.clear();
                    for (AttachmentItem attach : allAttachments) {
                        if (attach.getType().equals("attachments")) {
                            generalArray.add(attach);
                        }
                    }
                    Utils.setListViewHeightBasedOnChildren(generalList);
                    adapterGeneralList.notifyDataSetChanged();
                    if (generalArray.isEmpty()) {
                        generalList.setVisibility(View.GONE);
                        attachmentTitle.setVisibility(View.GONE);
                    } else {
                        generalList.setVisibility(View.VISIBLE);
                        attachmentTitle.setVisibility(View.VISIBLE);
                    }
                    // -------- прочие -------- //
                    othersArray.clear();
                    for (AttachmentItem attach : allAttachments) {
                        if (attach.getType().equals("workfiles")) {
                            othersArray.add(attach);
                        }
                    }
                    Utils.setListViewHeightBasedOnChildren(othersList);
                    adapterOthersList.notifyDataSetChanged();
                    if (othersArray.isEmpty()) {
                        othersList.setVisibility(View.GONE);
                        othersTitle.setVisibility(View.GONE);
                    } else {
                        othersList.setVisibility(View.VISIBLE);
                        othersTitle.setVisibility(View.VISIBLE);
                    }
                } else if (documentID != null) {
                    DocumentAttachmentsTable documentAttachmentsTable = new DocumentAttachmentsTable(activity.getBaseContext());
                    String attachmentsStr = documentAttachmentsTable.get(documentID);
                    AllAttachmentsItem attachments = RestClient.getGson().fromJson(attachmentsStr, AllAttachmentsItem.class);
                    if (attachments != null) {
                        List<OfflineAttachment> offlineAttachments = new DocumentAddAttachmentTable(activity).getByDocumentID(documentID);
                        for (OfflineAttachment offlineAttachment : offlineAttachments) {
                            AttachmentItem attach = new AttachmentItem();
                            attach.setName(new File(offlineAttachment.getFilepath()).getName());
                            attach.setType("attachments");
                            attach.setActionID(offlineAttachment.getActionID());
                            attach.setDate(offlineAttachment.getDate());
                            attach.setIs_editable("true");
                            generalArray.add(attach);
                        }
                        // ------ приложения ------ //
                        if (attachments.getAttachments().size() + generalArray.size() != 0) {
                            List<AttachmentItem> general = attachments.getAttachments();
                            for (AttachmentItem attachmentItem : general) {
                                generalArray.add(attachmentItem);
                            }
                            Utils.setListViewHeightBasedOnChildren(generalList);
                            adapterOthersList.notifyDataSetChanged();
                            generalList.setVisibility(View.VISIBLE);
                            attachmentTitle.setVisibility(View.VISIBLE);
                        } else {
                            generalList.setVisibility(View.GONE);
                            attachmentTitle.setVisibility(View.GONE);
                        }
                        // ------ прочие ------ //
                        if (!attachments.getWork_files().isEmpty()) {
                            List<AttachmentItem> others = attachments.getWork_files();
                            for (AttachmentItem attachmentItem : others) {
                                othersArray.add(attachmentItem);
                            }
                            Utils.setListViewHeightBasedOnChildren(othersList);
                            adapterGeneralList.notifyDataSetChanged();
                            othersList.setVisibility(View.VISIBLE);
                            othersTitle.setVisibility(View.VISIBLE);
                        } else {
                            othersList.setVisibility(View.GONE);
                            othersTitle.setVisibility(View.GONE);
                        }
                    }
                }
            } else {
                AppMsg.makeText(activity, getString(R.string.error_download_attachments), AppMsg.STYLE_ALERT).show();
            }
            super.onPostExecute(result);
        }

        @Override
        protected String doInBackground(Void... voids) {
            if (workID != null) {
                return new SendGetRequest(person).requestGET(person.getHost()
                        + "rest/api/workflow/work/" + workID + "/attachments" + "?locale=" + MyApplication.getLang());
            } else {
                return new SendGetRequest(person).requestGET(person.getHost()
                        + "rest/api/docflow/doc/attachments?documentID=" + documentID + "&locale=" + MyApplication.getLang());
            }
        }
    }

    /**
     * Удаление вложения
     */
    class RemoveAttachmentRequest extends AsyncTask<Void, Void, String> {

        @Override
        protected void onPostExecute(String result) {
            if (result != null) {
                try {
                    ErrorCode errorCode = RestClient.getGson().fromJson(result, ErrorCode.class);
                    // если файл успешно удален - обновляем список
                    if (errorCode.getErrorCode().equals(Wrapper.NO_ERROR)) {
                        updateList();
                    } else {
                        AppMsg.makeText(activity, errorCode.getErrorMessage(), AppMsg.STYLE_ALERT).show();
                    }
                } catch (Exception exc) {
                    AppMsg.makeText(activity, getString(R.string.error_delete_attachment), AppMsg.STYLE_ALERT).show();
                }
            } else if (Utils.checkSyncEnables(settings)) {
                if (documentID != null) {
                    // говорим что вложение будет удалено при последующей синхронизации
                    DocumentRemoveAttachmentTable documentRemoveAttachmentTable = new DocumentRemoveAttachmentTable(activity.getBaseContext());
                    documentRemoveAttachmentTable.add(documentID, fileUUID, name, fileName);
                    // удаляем вложение из списка вложений
                    DocumentAttachmentsTable documentAttachmentsTable = new DocumentAttachmentsTable(activity.getBaseContext());
                    documentAttachmentsTable.remove(fileUUID);
                } else if (workID != null) {
                    // говорим что вложение будет удалено при последующей синхронизации
                    AddRemoveAttachment addRemoveAttachment = new AddRemoveAttachment(activity.getBaseContext());
                    addRemoveAttachment.add(workID, fileUUID, name, fileName);
                    // удаляем вложение из списка вложений
                    WorkAttachmentsTable workAttachmentsTable = new WorkAttachmentsTable(activity.getBaseContext());
                    workAttachmentsTable.deleteAttachment(fileUUID);
                }
                updateList();
            } else {
                AppMsg.makeText(activity, getString(R.string.error_delete_attachment), AppMsg.STYLE_ALERT).show();
            }
            super.onPostExecute(result);
        }

        @Override
        protected String doInBackground(Void... voids) {
            if (workID != null) {
                return new SendGetRequest(person).requestGET(person.getHost() + "rest/api/workflow/work/remove_file?nodeUUID="
                        + fileUUID + "&locale=" + MyApplication.getLang());
            } else {
                return new SendGetRequest(person).requestGET(person.getHost() + "rest/api/docflow/doc/attachment/remove?fileUUID="
                        + fileUUID + "&locale=" + MyApplication.getLang());
            }
        }
    }

    /**
     * Добавление файла
     */
    class AddFile extends AsyncTask<Void, Void, String> {

        String filePath;
        String fileName;
        String uuid;
        ProgressDialog progressDialog;

        public void setUuid(String uuid) {
            this.uuid = uuid;
        }

        public void setFilePath(String filePath) {
            this.filePath = filePath;
        }

        public void setFileName(String fileName) {
            this.fileName = fileName;
        }

        @Override
        protected void onPreExecute() {
            progressDialog = new ProgressDialog(activity);
            progressDialog.setMessage(getString(R.string.please_wait));
            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progressDialog.setCancelable(false);
            progressDialog.show();
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String result) {
            if (result == null) {
                AppMsg.makeText(activity, getString(R.string.error_add_file), AppMsg.STYLE_ALERT).show();
                return;
            }
            try {
                ErrorCode errorCode = RestClient.getGson().fromJson(result, ErrorCode.class);
                if (workID != null) {
                    if (errorCode.getResult().equals(Wrapper.NO_ERROR)) {
                        updateList();
                    } else {
                        AppMsg.makeText(activity, errorCode.getMessage(), AppMsg.STYLE_ALERT).show();
                    }
                } else {
                    if (errorCode.getErrorCode().equals(Wrapper.NO_ERROR)) {
                        updateList();
                    } else {
                        AppMsg.makeText(activity, errorCode.getErrorMessage(), AppMsg.STYLE_ALERT).show();
                    }
                }
            } catch (Exception exc) {
                Logger.v(exc.getLocalizedMessage());
            }
            progressDialog.dismiss();
            super.onPostExecute(result);
        }

        @Override
        protected String doInBackground(Void... voids) {
            UploadFile uploadFile = new UploadFile(person, false, UploadFile.INBOX_FILE);
            try {
                if (workID != null) {
                    return uploadFile.uploadFile(workID, fileName, filePath, true);
                } else {
                    return uploadFile.uploadFile(documentID, fileName, filePath, false);
                }
            } catch (Exception exc) {
                return null;
            }
        }
    }
}
