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

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.devspark.appmsg.AppMsg;
import com.google.gson.JsonSyntaxException;
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.models.AllAttachmentsItem;
import kz.arta.synergy.workflow.mobile.android.attachments.models.AttachmentItem;
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.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.Fonts;
import kz.arta.synergy.workflow.mobile.android.common.utils.ImageLoader;
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.common.models.DocumentItem;
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.manager.DownloadFile;
import kz.arta.synergy.workflow.mobile.android.forms.general.activities.FormPlayer;
import kz.arta.synergy.workflow.mobile.android.forms.mobile.activities.FormPlayerNative;
import kz.arta.synergy.workflow.mobile.android.works.models.WorkItem;

/**
 * Created by neox on 21.07.14.
 * Неполный список вложений
 */
public class AttachmentList extends AsyncTask<Void, Void, String> {

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

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

    /**
     * Объект "Работа"
     */
    private WorkItem work;

    /**
     * Объект "Документ"
     */
    private DocumentItem document;

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

    /**
     * Загрузчик изображений
     */
    private ImageLoader imageLoader;

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

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

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

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

    public AttachmentList(Activity activity, Person person, WorkItem work, ProgressWheel progressBar) {
        this.work = work;
        init(activity, person, progressBar);
    }

    public AttachmentList(Activity activity, Person person, DocumentItem document, ProgressWheel progressBar) {
        this.document = document;
        init(activity, person, progressBar);
    }

    private void init(Activity activity, Person person, ProgressWheel progressBar) {
        this.activity = activity;
        this.person = person;
        this.progressBar = progressBar;
        imageLoader = new ImageLoader(activity, person);
        settings = activity.getSharedPreferences(SettingsConst.DEFAULT_NAME_SETTINGS, Context.MODE_PRIVATE);
        versionSynergy = settings.getFloat(SettingsConst.SYNERGY_VERSION, 0);
    }

    @Override
    protected void onPostExecute(final String result) {

        progressBar.setVisibility(View.GONE);

        // леяут с комментариями
        LinearLayout attachmentsLayout = (LinearLayout) activity.findViewById(R.id.attachments);
        LayoutInflater ltInflater = activity.getLayoutInflater();
        attachmentsLayout.removeAllViews();

        // кнопка "перейти к вложениями"
        RelativeLayout goToAttachments = (RelativeLayout) activity.findViewById(R.id.go_to_attachments_button);
        goToAttachments.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(activity, AllAttachmentsActivity.class);
                if (work != null) {
                    intent.putExtra(ActivityConst.WORK_ID, work.getActionID());
                    // имя работы
                    intent.putExtra(ActivityConst.WORK_NAME, work.getName());
                } else {
                    intent.putExtra(ActivityConst.DOCUMENT_ID, document.getDocumentID());
                    // имя документа
                    intent.putExtra(ActivityConst.WORK_NAME, document.getName());
                }
                intent.putExtra(ActivityConst.PERSON, person);
                activity.startActivityForResult(intent, ActionUtils.ATTACHMENT);
            }
        });

        ((TextView) activity.findViewById(R.id.go_to_attachments_label)).setTypeface(Fonts.getMedium(activity));

        TextView attachCount = (TextView) activity.findViewById(R.id.go_to_attachments_count_label);
        attachCount.setTypeface(Fonts.getRoman(activity));

        if (result != null) {
            try {
                AttachmentItem attachmentItem = RestClient.getGson().fromJson(result, AttachmentItem.class);
                if (!attachmentItem.getList().isEmpty()) {
                    // сколько всего вложений на кнопке "перейти ко вложениям"
                    attachCount.setText(String.valueOf(attachmentItem.getList().size()));
                    for (AttachmentItem currentAttachment : attachmentItem.getList()) {
                        getAttachmentListData(attachmentsLayout, ltInflater, currentAttachment);
                    }
                    showAttachments(attachmentsLayout, goToAttachments);
                } else {
                    hideAttachments(attachmentsLayout, goToAttachments);
                }
                attachCount.setText(attachmentItem.getCount());
            } catch (Exception exc) {
                Logger.v(exc.getLocalizedMessage());
            }
        } else if (Utils.checkSyncEnables(settings)) {
            if (work != null) {
                List<AttachmentItem> allAttachments = new ArrayList<>();
                List<OfflineAttachment> offlineAttachments = new AddAttachment(activity).getByWorkID(work.getActionID());
                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");
                    attach.setFilepath(offlineAttachment.getFilepath());
                    allAttachments.add(attach);
                }
                WorkAttachmentsTable workAttachmentsTable = new WorkAttachmentsTable(activity);
                List<AttachmentItem> current = workAttachmentsTable.get(work.getActionID());
                for (AttachmentItem aCurrent : current) {
                    allAttachments.add(aCurrent);
                }
                if (!allAttachments.isEmpty()) {
                    attachCount.setText(String.valueOf(allAttachments.size()));
                    if (allAttachments.size() <= 3) {
                        for (AttachmentItem currentAttachment : allAttachments) {
                            getAttachmentListData(attachmentsLayout, ltInflater, currentAttachment);
                        }
                    } else {
                        for (int i = 0; i < 3; i++) {
                            getAttachmentListData(attachmentsLayout, ltInflater, allAttachments.get(i));
                        }
                    }
                    showAttachments(attachmentsLayout, goToAttachments);
                } else {
                    hideAttachments(attachmentsLayout, goToAttachments);
                }
            } else if (document != null) {
                DocumentAttachmentsTable documentAttachmentsTable = new DocumentAttachmentsTable(activity.getBaseContext());
                String attachmentsStr = documentAttachmentsTable.get(document.getDocumentID());
                AllAttachmentsItem attachments = RestClient.getGson().fromJson(attachmentsStr, AllAttachmentsItem.class);
                List<AttachmentItem> lastAttachments = new ArrayList<>();
                // добавляем добавленные оффлайн вложения
                List<OfflineAttachment> offlineAttachments = new DocumentAddAttachmentTable(activity).getByDocumentID(document.getDocumentID());
                if (offlineAttachments != null && !offlineAttachments.isEmpty()) {
                    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");
                        attach.setFilepath(offlineAttachment.getFilepath());
                        lastAttachments.add(attach);
                    }
                }
                for (AttachmentItem attachmentItem : attachments.getAttachments()) {
                    lastAttachments.add(attachmentItem);
                }
                for (AttachmentItem attachmentItem : attachments.getWork_files()) {
                    lastAttachments.add(attachmentItem);
                }
                if (!lastAttachments.isEmpty()) {
                    attachCount.setText(String.valueOf(lastAttachments.size()));
                    if (lastAttachments.size() <= 3) {
                        for (AttachmentItem currentAttachment : lastAttachments) {
                            getAttachmentListData(attachmentsLayout, ltInflater, currentAttachment);
                        }
                    } else {
                        for (int i = 0; i < 3; i++) {
                            getAttachmentListData(attachmentsLayout, ltInflater, lastAttachments.get(i));
                        }
                    }
                    showAttachments(attachmentsLayout, goToAttachments);
                } else {
                    hideAttachments(attachmentsLayout, goToAttachments);
                }
            }
        }

        super.onPostExecute(result);
    }

    /**
     * Метод отвечает за отображение итема для списка с вложениями
     *
     * @param commentsLayout - леяут с вложениями
     * @param inflater       - inflate
     * @param attach         - объект "вложение"
     */
    private void getAttachmentListData(LinearLayout commentsLayout, LayoutInflater inflater, final AttachmentItem attach) {
        View item = inflater.inflate(R.layout.item_attachment, commentsLayout, false);
        if (item != null) {
            // текст вложения
            TextView attachmentName = (TextView) item.findViewById(R.id.text_attach);
            attachmentName.setTypeface(Fonts.getMedium(activity));
            attachmentName.setText(attach.getName());
            // икнока вложения
            ImageView iconAttachment = (ImageView) item.findViewById(R.id.image_attach);
            try {
                imageLoader.displayImage(Utils.parseUrlToIcon(person.getHost() + attach.getIcon()), iconAttachment);
            } catch (Exception ignored) {
            }
            item.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(activity);
                    builder.setTitle(activity.getString(R.string.actions));
                    final List<String> items = new ArrayList<>();
                    if (attach.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 (attach.getDate() != null) {
                                removeOfflineAttachmentDialog(attach);
                            } else {
                                removeAttachmentDialog(attach);
                            }
                        }
                    });
                    builder.setCancelable(true);
                    if (!items.isEmpty()) {
                        builder.show();
                    }
                    return true;
                }
            });
            item.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (attach.getDataUUID() != null) {
                        // если версия синерджи меньше чем 7
                        if (versionSynergy < 3.7) {
                            openFile(attach);
                            return;
                        }
                        // если есть мобильное представление
                        if (attach.getMobile().equals("true")) {
                            Intent intent = new Intent(activity, FormPlayerNative.class);
                            intent.putExtra(ActivityConst.DATA_UUID, attach.getDataUUID());
                            intent.putExtra(ActivityConst.PERSON, person);
                            intent.putExtra(ActivityConst.CAN_EDIT, attach.getIs_editable());
                            activity.startActivityForResult(intent, ActionUtils.SAVE_FORM);
                        } else {
                            Intent intent = new Intent(activity, FormPlayer.class);
                            intent.putExtra(ActivityConst.DATA_UUID, attach.getDataUUID());
                            intent.putExtra(ActivityConst.PERSON, person);
                            intent.putExtra(ActivityConst.CAN_EDIT, attach.getIs_editable());
                            activity.startActivityForResult(intent, ActionUtils.SAVE_FORM);
                        }
                    } else {
                        openFile(attach);
                    }
                }
            });
            commentsLayout.addView(item);
        }
    }

    /**
     * Используется для открытия файла
     * @param attachment            вложение
     */
    private void openFile(AttachmentItem attachment) {
        if (Utils.isOnline(activity, person.getHost())) {
            DownloadFile downloadFile = new DownloadFile(activity, person);
            downloadFile.setFileName(attachment.getName());
            downloadFile.setUrl(person.getHost() + "rest/api/storage/pdf/get?identifier=" + attachment.getUuid());
            downloadFile.execute();
        } else if (Utils.checkSyncEnables(settings)) {
            String filePath;
            if (attachment.getUuid() == null) {
                filePath = attachment.getFilepath();
            } else {
                filePath = new WorkAttachmentsTable(activity).getFilePathByUUID(attachment.getUuid());
            }
            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();
                }
            }
        }
    }

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

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

    @Override
    protected String doInBackground(Void... voids) {
        if (work != null) {
            return new SendGetRequest(person).requestGET(person.getHost() + "rest/api/workflow/work/"
                    + work.getActionID() + "/last_attachments?count=3&getCounters=true" + "&locale=" + MyApplication.getLang());
        } else {
            return new SendGetRequest(person).requestGET(person.getHost() + "rest/api/docflow/doc/last_attachments?documentID="
                    + document.getDocumentID() + "&count=3&getCounters=true" + "&locale=" + MyApplication.getLang());
        }
    }

    /**
     * Метод загружает вложения
     */
    private void getAttachments() {
        if (work != null) {
            new AttachmentList(activity, person, work, progressBar).execute();
        } else {
            new AttachmentList(activity, person, document, progressBar).execute();
        }
    }

    /**
     * Отображение вложений
     *
     * @param attachment - список комментариев
     * @param button     - кнопка "перейти ко вложениям"
     */
    private void showAttachments(LinearLayout attachment, RelativeLayout button) {
        attachment.setVisibility(View.VISIBLE);
        button.setVisibility(View.VISIBLE);
    }

    /**
     * Скрытие вложений
     *
     * @param attachment - список комментариев
     * @param button     - кнопка "перейти ко вложениям"
     */
    private void hideAttachments(LinearLayout attachment, RelativeLayout button) {
        attachment.setVisibility(View.GONE);
        button.setVisibility(View.GONE);
    }

    /**
     * Класс отвечает за отправку запроса удаления вложения
     * В случае успешного выполнения - обновляем список вложений
     */
    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)) {
                        getAttachments();
                    } else {
                        AppMsg.makeText(activity, errorCode.getErrorMessage(), AppMsg.STYLE_ALERT).show();
                    }
                } catch (JsonSyntaxException exc) {
                    AppMsg.makeText(activity, activity.getString(R.string.error_delete_attachment), AppMsg.STYLE_ALERT).show();
                }
            } else if (Utils.checkSyncEnables(settings)) {
                if (work != null) { // вызывается для работ модуле потоки работ
                    // говорим что вложение будет удалено при последующей синхронизации
                    AddRemoveAttachment addRemoveAttachment = new AddRemoveAttachment(activity);
                    addRemoveAttachment.add(work.getActionID(), nodeUUID, work.getName(), fileName);
                    // удаляем вложение из списка вложений
                    WorkAttachmentsTable workAttachmentsTable = new WorkAttachmentsTable(activity);
                    workAttachmentsTable.deleteAttachment(nodeUUID);
                } else if (document != null) { // вызывается для документов в модуле документы
                    // говорим что вложение будет удалено при последующей синхронизации
                    DocumentRemoveAttachmentTable documentRemoveAttachmentTable = new DocumentRemoveAttachmentTable(activity);
                    documentRemoveAttachmentTable.add(document.getDocumentID(), nodeUUID, document.getName(), fileName);
                    // удаляем вложение из списка вложений
                    DocumentAttachmentsTable documentAttachmentsTable = new DocumentAttachmentsTable(activity.getBaseContext());
                    documentAttachmentsTable.remove(nodeUUID);
                }
                getAttachments();
            } else {
                AppMsg.makeText(activity, activity.getString(R.string.error_delete_attachment), AppMsg.STYLE_ALERT).show();
            }
            super.onPostExecute(result);
        }

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