package kz.arta.synergy.workflow.mobile.android.documents.favorite.activities;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import kz.arta.synergy.workflow.mobile.android.R;
import kz.arta.synergy.workflow.mobile.android.common.ActivityConst;
import kz.arta.synergy.workflow.mobile.android.common.activities.MainActivity;
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.MenuItem;
import kz.arta.synergy.workflow.mobile.android.common.requests.SendGetRequest;
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.Utils;
import kz.arta.synergy.workflow.mobile.android.documents.favorite.FavoritesConsts;
import kz.arta.synergy.workflow.mobile.android.documents.favorite.models.FavoriteItem;
import kz.arta.synergy.workflow.mobile.android.files.manager.FilesRights;
import kz.arta.synergy.workflow.mobile.android.registry.RegistryModel;

/**
 * Класс для работы с избранными пунктами
 */
public class Favorite implements FavoriteItemListener {

    /**
     * Пользователь
     */
    private Person person;

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

    /**
     * Пункты
     */
    private FavoriteItem[] favoriteItems;

    /**
     * Есть 2 режима, диалог и полноценный экран, если all = true, значит исопльзуется полноценный экран, иначе - диалог
     */
    private boolean all = false;

    /**
     * Используется ли поиск в данный момент
     */
    private boolean search = false;

    /**
     * Выделенный пункт
     */
    private Item selectedItem;

    private FavoriteItemListener favoriteItemListener;

    public Favorite(Person person, Activity activity) {
        this.person = person;
        this.activity = activity;
    }

    /**
     * Метод используется для инициализации пунктов диалога
     *
     * @param layout     леяут
     * @param typeModule текущий модуль
     * @see Const#WORKS
     * @see Const#DOCUMENTS
     * @see Const#FILES
     */
    public void initCreateMenuItems(LinearLayout layout, int typeModule, int right, RegistryModel registry) {
        switch (typeModule) {
            case Const.WORKS: {
                if (person.getSettings().getWorkItems() == null) {
                    initFavoriteDocuments(layout);
                } else {
                    for (MenuItem item : person.getSettings().getWorkItems()) {
                        if (item.getId().equals(FavoritesConsts.DOCUMENTS)) {
                            initFavoriteDocuments(layout);
                        } else if (item.getId().equals(FavoritesConsts.ALL)) {
                            initElement(layout, item.getName(), FavoritesConsts.ALL);
                        } else if (item.getId().equals(FavoritesConsts.WORK)) {
                            initWork(layout, item.getName());
                        } else if (item.getId().equals(FavoritesConsts.DIALOGS)) {
                            initFavoriteDialogs(layout);
                        }
                    }
                }
                break;
            }
            case Const.DOCUMENTS: {
                if (person.getSettings().getDocumentItems() == null) {
                    initFavoriteDocuments(layout);
                } else {
                    for (MenuItem item : person.getSettings().getDocumentItems()) {
                        if (item.getId().equals(FavoritesConsts.DOCUMENTS)) {
                            initFavoriteDocuments(layout);
                        } else if (item.getId().equals(FavoritesConsts.ALL)) {
                            initElement(layout, item.getName(), FavoritesConsts.ALL);
                        }
                    }
                }
                break;
            }
            case Const.FILES: {
                if (person.getSettings().getFileItems() == null) {
                    initFavoriteDocuments(layout);
                } else {
                    for (MenuItem item : person.getSettings().getFileItems()) {
                        if (item.getId().equals(FavoritesConsts.DOCUMENTS)) {
                            initFavoriteDocuments(layout);
                        } else if (item.getId().equals(FavoritesConsts.ALL)) {
                            initElement(layout, item.getName(), FavoritesConsts.ALL);
                        } else if (item.getId().equals(FavoritesConsts.UPLOAD_FILE) && FilesRights.checkRight(right, FilesRights.ADD)) {
                            // hardcode...
                            initElement(layout, item.getName(), FavoritesConsts.UPLOAD_FILE);
                            initElement(layout, "    " + activity.getResources().getString(R.string.from_android), FavoritesConsts.UPLOAD_FILE);
                            initElement(layout, "    " + activity.getResources().getString(R.string.do_photo), FavoritesConsts.UPLOAD_FILE);
                        } else if (item.getId().equals(FavoritesConsts.NEW_FOLDER) && FilesRights.checkRight(right, FilesRights.ADD)) {
                            initElement(layout, item.getName(), FavoritesConsts.NEW_FOLDER);
                        }
                    }
                }
                break;
            }
            case Const.REGISTRY: {
                if (person.getSettings().getRegistryItems() == null) {
                    initFavoriteDocuments(layout);
                } else {
                    for (MenuItem item : person.getSettings().getRegistryItems()) {
                        if (item.getId().equals(FavoritesConsts.DOCUMENTS)) {
                            initFavoriteDocuments(layout);
                        } else if (item.getId().equals(FavoritesConsts.ALL)) {
                            initElement(layout, item.getName(), FavoritesConsts.ALL);
                        } else if (item.getId().equals(FavoritesConsts.NEW_RECORD)) {
                            if (registry.getRights() != null && Arrays.asList(registry.getRights()).contains("rr_create")) {
                                initElement(layout, item.getName(), FavoritesConsts.NEW_RECORD);
                            }
                        }
                    }
                }
            }
        }
        if (layout.getChildCount() > 1) {
            layout.removeViewAt(layout.getChildCount() - 1);
        }
    }

    /**
     * Избранные пункты для создания документа
     *
     * @param layout контейнер
     */
    public void initFavoriteDocuments(LinearLayout layout) {
        getFavoriteItems(layout);
    }

    /**
     * Пункт "Еще"
     *
     * @param layout контейнер
     * @param label  имя пункта
     * @param type   тип события
     */
    private void initElement(LinearLayout layout, String label, String type) {
        Item i = new Item(activity, label, false, null, 0, type, null);
        layout.addView(i);
        layout.addView(getSplit());
    }

    /**
     * Стандартный диалог для создания работы
     *
     * @param layout контейнер
     * @param label  имя пункта
     */
    private void initWork(LinearLayout layout, String label) {
        if (person.getSettings().getDialogs() == null || person.getSettings().getDialogs().length == 0) {
            return;
        }
        for (DialogItem item : person.getSettings().getDialogs()) {
            if (item.getType().equals(ActivityConst.WORK) && item.getDef().equals("true")) {
                Item i = new Item(activity, label, false, null, 0, FavoritesConsts.WORK, null);
                layout.addView(i);
            }
        }
        layout.addView(getSplit());
    }

    /**
     * Диалоги создания работы
     *
     * @param layout контейнер
     */
    private void initFavoriteDialogs(LinearLayout layout) {
        if (person.getSettings().getDialogs() == null || person.getSettings().getDialogs().length == 0) {
            return;
        }
        for (DialogItem item : person.getSettings().getDialogs()) {
            if (item.getType().equals(ActivityConst.WORK) && item.getDef().equals("false")) {
                Item i = new Item(activity, item.getName(), false, null, 0, FavoritesConsts.DIALOGS, null);
                i.dialogItem = item;
                layout.addView(i);
            }
        }
        layout.addView(getSplit());
    }

    /**
     * Возвращает сплит
     *
     * @return view
     */
    public View getSplit() {
        View view = new View(activity);
        view.setLayoutParams(new LinearLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
                Utils.getPxFromDp(R.dimen.create_menu_dialog_big_split_height, activity)));
        view.setBackgroundColor(activity.getResources().getColor(R.color.create_menu_dialog_split_color));
        return view;
    }

    /**
     * Метод выполянется после получения данных о избранных пунктах (первый уровень)
     *
     * @param layout контейнер
     */
    private void getFavoriteItems(LinearLayout layout) {
        if (favoriteItems == null || favoriteItems.length == 0) {
            return;
        }
        for (FavoriteItem item : favoriteItems) {
            if (item.getParentID() == null) {
                layout.addView(getFavoriteItem(item, 0, true));
            }
        }
        if (!all) {
            layout.addView(getSplit());
        }
    }

    /**
     * Метод возвращает пункт для пунктов создания документа
     *
     * @param favoriteItem пункт, с которым работаем в данный момент
     * @return item
     */
    private Item getFavoriteItem(FavoriteItem favoriteItem, int level, boolean firstLevel) {
        boolean child = false;
        String parentID = null;
        for (FavoriteItem i : favoriteItems) {
            if (i.getParentID() != null && i.getParentID().equals(favoriteItem.getItemID())) {
                child = true;
                parentID = i.getParentID();
                break;
            }
        }
        return new Item(activity, favoriteItem.getName(), child, parentID,
                (firstLevel ? level : level + 1), FavoritesConsts.DOCUMENTS, favoriteItem);
    }

    /**
     * Метод используется для поиска пунктов
     *
     * @param search строк поиска
     * @param layout контейнер, в котором находится список
     */
    public void search(CharSequence search, LinearLayout layout) {
        layout.removeAllViews();
        if (search.length() > 0) {
            this.search = true;
            List<FavoriteItem> searchItems = new ArrayList<>();
            for (FavoriteItem item : favoriteItems) {
                if (item.getName().toLowerCase().contains(search.toString().toLowerCase()) && item.getGroup().equals("false")) {
                    searchItems.add(item);
                }
            }
            updateListSearch(searchItems, layout);
        } else {
            this.search = false;
            getFavoriteItems(layout);
        }
    }

    /**
     * Метод обновляет список, исходя из найденных пунктов
     *
     * @param items  список найденных пунктов
     * @param layout контейнер, в котором находится список
     */
    private void updateListSearch(List<FavoriteItem> items, LinearLayout layout) {
        for (FavoriteItem item : items) {
            layout.addView(getFavoriteItem(item, 0, true));
        }
    }

    /**
     * Метод строит путь до родительской группы
     *
     * @param favoriteItem пункт, с которым работаем в данный момент
     * @param name         путь
     * @return string
     */
    private String getSearchPath(FavoriteItem favoriteItem, String name) {
        if (favoriteItem.getParentID() == null) {
            return name;
        } else {
            for (FavoriteItem i : favoriteItems) {
                if (i.getItemID().equals(favoriteItem.getParentID())) {
                    name = name + i.getName() + "/";
                    return getSearchPath(i, name);
                }
            }
        }
        return "";
    }

    /**
     * Метод ревертит путь
     *
     * @param path исходный путь
     * @return результат
     */
    private String revertPath(String path) {
        StringBuilder result = new StringBuilder();
        String[] array = path.split("/");
        for (int i = array.length; i > 0; i--) {
            result.append(array[i - 1]);
            result.append("/");
        }
        if (result.toString().equals("/")) {
            return null;
        } else {
            return result.substring(0, result.length() - 1);
        }
    }

    /**
     * Закрытие диалога
     */
    private void dismiss() {
        MainActivity mainActivity = (MainActivity) activity;
        mainActivity.getParentDialogLayout().startAnimation(AnimationUtils.loadAnimation(activity, R.anim.end_animation_activity));
        mainActivity.getParentDialogLayout().setVisibility(View.GONE);
        mainActivity.getShadow().startAnimation(AnimationUtils.loadAnimation(activity, R.anim.end_animation_activity));
        mainActivity.getShadow().setVisibility(View.GONE);
        mainActivity.setShowed();
    }

    @Override
    public void newFolder() {
        favoriteItemListener.newFolder();
    }

    @Override
    public void showFavoriteActivity() {
        favoriteItemListener.showFavoriteActivity();
    }

    @Override
    public void createWork() {
        favoriteItemListener.createWork();
    }

    @Override
    public void createCustomWork(DialogItem item) {
        favoriteItemListener.createCustomWork(item);
    }

    @Override
    public void fromDevice() {
        favoriteItemListener.fromDevice();
    }

    @Override
    public void fromCamera() {
        favoriteItemListener.fromCamera();
    }

    @Override
    public void createDocument(FavoriteItem item) {
        favoriteItemListener.createDocument(item);
    }

    @Override
    public void newRecord() {
        favoriteItemListener.newRecord();
    }

    /**
     * Метод отмечает пункт как "Избранный", либо наоборот
     *
     * @param item текущий пункт
     */
    private void setBookmark(final Item item) {
        new SendGetRequest("rest/api/registry/set_bookmark?itemID=" + item.favoriteItem.getItemID() +
                "&bookmark=" + !Boolean.parseBoolean(item.favoriteItem.getIsBookmark()), person) {
            @Override
            protected void onPostExecute(String result) {
                if (result == null) {
                    return;
                }
                if (item.favoriteItem.getIsBookmark().equals("true")) {
                    item.favoriteItem.setIsBookmark("false");
                    item.favoriteIcon.setImageResource(R.drawable.favorite_icon_disable);
                } else {
                    item.favoriteItem.setIsBookmark("true");
                    item.favoriteIcon.setImageResource(R.drawable.favorite_icon_enable);
                }
                super.onPostExecute(result);
            }
        }.execute();
    }

    public boolean isAll() {
        return all;
    }

    public void setAll(boolean all) {
        this.all = all;
    }

    public void setFavoriteItems(FavoriteItem[] favoriteItems) {
        this.favoriteItems = favoriteItems;
    }

    public Item getSelectedItem() {
        return selectedItem;
    }

    public void setFavoriteItemListener(FavoriteItemListener favoriteItemListener) {
        this.favoriteItemListener = favoriteItemListener;
    }

    public class Item extends LinearLayout {

        /**
         * Иконка справа от имени
         */
        ImageView icon;

        /**
         * Иконка справа от имени
         */
        ImageView favoriteIcon;

        /**
         * Состояние (раскрыто/свернуто)
         */
        boolean state = false;

        /**
         * UUID родителя
         */
        String parentID = null;

        /**
         * Уровень вложенности
         */
        int level = 0;

        /**
         * Тип пункта
         */
        String type;

        /**
         * Описание диалога
         */
        DialogItem dialogItem;

        /**
         * Данные о пункте
         */
        FavoriteItem favoriteItem;

        /**
         * Фон
         */
        RelativeLayout background;

        public Item(Context context, final String itemName, final boolean child,
                    String parentID, int level, final String type, final FavoriteItem favoriteItem) {

            super(context);

            this.parentID = parentID;

            this.level = level;

            this.type = type;

            this.favoriteItem = favoriteItem;

            setOrientation(LinearLayout.VERTICAL);

            setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

            LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            final RelativeLayout contentLayout;
            if (all) {
                contentLayout = (RelativeLayout) inflater.inflate(R.layout.favorites_item, null);
                background = (RelativeLayout) contentLayout.findViewById(R.id.background_favorite_item);
            } else {
                setBackgroundColor(getResources().getColor(R.color.create_menu_dialog_item_background_color));
                contentLayout = (RelativeLayout) inflater.inflate(R.layout.create_menu_dialog_item, null);
            }

            contentLayout.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (child) {
                        iconEvent();
                    } else if (all) {
                        if (selectedItem != null) {
                            selectedItem.background.setBackgroundColor(getResources().getColor(R.color.item_list_attachment_color));
                        }
                        selectedItem = getItem();
                        background.setBackgroundColor(getResources().getColor(R.color.selected_item_list_color));
                    } else {
                        if (type.equals(FavoritesConsts.ALL)) {
                            dismiss();
                            showFavoriteActivity();
                        } else if (type.equals(FavoritesConsts.WORK)) {
                            dismiss();
                            createWork();
                        } else if (type.equals(FavoritesConsts.DIALOGS)) {
                            dismiss();
                            createCustomWork(dialogItem);
                        } else if (type.equals(FavoritesConsts.DOCUMENTS)) {
                            dismiss();
                            createDocument(favoriteItem);
                        } else if (type.equals(FavoritesConsts.UPLOAD_FILE)) {
                            // hardcode...
                            if (itemName.endsWith(activity.getResources().getString(R.string.from_android))) {
                                dismiss();
                                fromDevice();
                            } else if (itemName.endsWith(activity.getResources().getString(R.string.do_photo))) {
                                dismiss();
                                fromCamera();
                            }
                        } else if (type.equals(FavoritesConsts.NEW_FOLDER)) {
                            dismiss();
                            newFolder();
                        } else if (type.equals(FavoritesConsts.NEW_RECORD)) {
                            dismiss();
                            newRecord();
                        }
                    }
                }
            });

            int margin = (int) (getResources().getDimension(R.dimen.create_menu_dialog_name_margin_left));
            int marginTop = (int) (getResources().getDimension(R.dimen.create_menu_dialog_name_margin_top));

            int marginLeft = margin;
            if (level == 1) {
                marginLeft = margin + margin;
            } else if (level >= 2) {
                marginLeft = margin + margin + margin;
            }

            // имя пункта
            TextView name = (TextView) contentLayout.findViewById(R.id.name);
            name.setText(itemName);
            name.setTypeface((all ? Fonts.getMedium(activity) : Fonts.getRoman(activity)));

            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) name.getLayoutParams();
            params.setMargins(marginLeft, marginTop, margin + margin, marginTop);
            name.setLayoutParams(params);

            // иконка раскрытия дочерних пунктов
            icon = (ImageView) contentLayout.findViewById(R.id.icon);
            icon.setOnClickListener(new ItemClickListener());

            // если есть дочерние - отображаем стрелочку
            if (child) {
                icon.setVisibility(View.VISIBLE);
            }

            // со "Звездочкой" работаем только если находимся в экране со списком всех пунктов
            if (all) {

                // путь пункта (при поиске)
                TextView searchPath = (TextView) contentLayout.findViewById(R.id.search_path);

                if (search) {
                    // имя пути до родителей
                    String path = revertPath(getSearchPath(favoriteItem, ""));
                    params = (RelativeLayout.LayoutParams) searchPath.getLayoutParams();
                    params.setMargins(marginLeft, -margin, margin, margin);
                    searchPath.setLayoutParams(params);
                    searchPath.setVisibility(View.VISIBLE);
                    searchPath.setTypeface(Fonts.getRoman(activity));
                    // если у элеиента нет родиеля - путь отображать не надо
                    if (path == null) {
                        searchPath.setVisibility(View.GONE);
                    } else {
                        searchPath.setText(path);
                    }
                } else {
                    searchPath.setVisibility(View.GONE);
                }

                // иконка раскрытия дочерних пунктов
                favoriteIcon = (ImageView) contentLayout.findViewById(R.id.favorite_icon);
                favoriteIcon.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        setBookmark(getItem());
                    }
                });

                if (favoriteItem.getIsBookmark() != null && favoriteItem.getIsBookmark().equals("true")) {
                    favoriteIcon.setImageResource(R.drawable.favorite_icon_enable);
                } else if (child) {
                    favoriteIcon.setVisibility(View.GONE);
                }
            }

            addView(contentLayout);
        }

        private void iconEvent() {
            if (state) {
                hide();
            } else {
                for (FavoriteItem item : favoriteItems) {
                    if (item.getParentID() != null && item.getParentID().equals(parentID)) {
                        addView(getFavoriteItem(item, level, false));
                    }
                }
                state = true;
                icon.setImageResource(R.drawable.dialog_item_icon_detailed);
            }
        }

        private Item getItem() {
            return this;
        }

        /**
         * Скрытие всех дочерних элементов для текущего
         */
        private void hide() {
            for (int i = getChildCount() - 1; i >= 1; i--) {
                Item item = (Item) getChildAt(i);
                if (selectedItem == item) {
                    selectedItem = null;
                }
                removeViewAt(i);
            }
            state = false;
            icon.setImageResource(R.drawable.dialog_item_icon_undetiled);
        }

        /**
         * Событие тап на изображение
         */
        private class ItemClickListener implements OnClickListener {
            public void onClick(View view) {
                iconEvent();
            }
        }
    }
}