package kz.arta.synergy.workflow.mobile.android.forms.general.components.users.activity;

import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.google.gson.reflect.TypeToken;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.pnikosis.materialishprogress.ProgressWheel;

import java.util.ArrayList;
import java.util.Collections;
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.components.SearchEditText;
import kz.arta.synergy.workflow.mobile.android.common.models.Person;
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.Const;
import kz.arta.synergy.workflow.mobile.android.common.utils.Fonts;
import kz.arta.synergy.workflow.mobile.android.common.utils.FragmentConst;
import kz.arta.synergy.workflow.mobile.android.common.utils.HorizontalListView;
import kz.arta.synergy.workflow.mobile.android.common.utils.Utils;
import kz.arta.synergy.workflow.mobile.android.files.adapters.AdapterPath;
import kz.arta.synergy.workflow.mobile.android.files.models.Path;
import kz.arta.synergy.workflow.mobile.android.forms.general.components.users.UsersChooserConst;
import kz.arta.synergy.workflow.mobile.android.forms.general.components.users.adapters.PositionsChooserAdapter;
import kz.arta.synergy.workflow.mobile.android.forms.general.components.users.model.DepartmentModel;
import kz.arta.synergy.workflow.mobile.android.forms.general.components.users.model.PositionModel;
import kz.arta.synergy.workflow.mobile.android.forms.general.components.users.model.UserModel;
import kz.arta.synergy.workflow.mobile.android.forms.general.components.users.navigator.UsersChooserNavigatorItem;

/**
 * Created by neox on 05.04.16.
 * Должность чузер
 */
public class PositionsChooserActivity extends Activity {

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

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

    /**
     * Авторизированный пользователь
     */
    private Person person;

    /**
     * Боковая навигация
     */
    private SlidingMenu slidingMenu;

    /**
     * Контейнер с навигатором
     */
    private LinearLayout navigatorLayout;

    /**
     * Адаптер для списка должностей
     */
    private PositionsChooserAdapter positionsAdapter;

    /**
     * Должности в списке
     */
    private List<PositionModel> positionsArray;

    /**
     * Выбранные должности
     */
    private List<PositionModel> selectedPositions;

    /**
     * Данные компонента "Путь"
     */
    private List<Path> pathData;

    /**
     * Адаптер компонента "Путь"
     */
    private BaseAdapter pathAdapter;

    /**
     * Компонент "Путь"
     */
    private HorizontalListView pathList;

    /**
     * Компонент для поиска
     */
    private SearchEditText searchEditText;

    /**
     * Идентификатор текущего департамента
     */
    private String departmentID;

    /**
     * Используется ли мультивыбор
     */
    private boolean multiSelect;

    /**
     * Отображать вакантные должности или нет
     */
    private boolean showVacant;

    /**
     * Фильтрация по userID
     */
    private String filterUserID;

    /**
     * Фильтрация по departmentID
     */
    private String filterDepartmentID;

    /**
     * С какой записи загружать пользователей
     */
    private int startRecord = 0;

    /**
     * Загружается ли список в данный момент
     */
    private boolean isLoading = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

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

        activity = this;

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

        Intent intent = getIntent();
        person = (Person) intent.getSerializableExtra(ActivityConst.PERSON);
        multiSelect = intent.getBooleanExtra(UsersChooserConst.MULTI_SELECT, false);
        filterUserID = intent.getStringExtra(UsersChooserConst.FILTER_USER_ID);
        filterDepartmentID = intent.getStringExtra(UsersChooserConst.FILTER_DEPARTMENT_ID);
        selectedPositions = RestClient.getGson().fromJson(intent.getStringExtra(UsersChooserConst.SELECTED_ITEMS),
                new TypeToken<List<PositionModel>>() {
                }.getType());
        showVacant = intent.getBooleanExtra(UsersChooserConst.SHOW_VACANT, false);

        init();
    }

    /**
     * Инициализация
     */
    public void init() {

        ((TextView) findViewById(R.id.users_chooser_action_bar_title)).setText(R.string.positions);

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

        // кнопка "Навигатор"
        ImageView showNavigator = (ImageView) findViewById(R.id.user_chooser_icon_show_navigator);
        showNavigator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                slidingMenu.toggle();
            }
        });

        // компонент "Путь"
        pathData = new ArrayList<>();
        pathAdapter = new AdapterPath(activity, pathData);
        pathList = (HorizontalListView) findViewById(R.id.list_view_path_user_chooser);
        pathList.setAdapter(pathAdapter);
        pathList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                // все элементы отмечаем как "невыделенные"
                for (Path path : pathData) {
                    path.setSelected(false);
                }
                // говорим элемент, по которому происходит тап - будет выделен
                pathData.get(i).setSelected(true);
                searchListItem(navigatorLayout, pathData.get(i).getNodeID());
            }
        });

        // компонент для поиска
        searchEditText = (SearchEditText) findViewById(R.id.search_user_edit_text);
        searchEditText.setHint(getString(R.string.search_positions));
        searchEditText.setListener(new SearchEditText.SearchTextListener() {
            @Override
            public void onTextChanged(String text) {
                startRecord = 0;
                getPositions(departmentID, text, true);
            }
        });

        if (selectedPositions == null) {
            selectedPositions = new ArrayList<>();
        }

        positionsArray = new ArrayList<>();
        positionsAdapter = new PositionsChooserAdapter(this, positionsArray);

        // основной список
        ListView users = (ListView) findViewById(R.id.users_list);
        users.setAdapter(positionsAdapter);
        users.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                if (multiSelect) {
                    if (!positionsArray.get(i).isChecked()) {
                        selectedPositions.add(positionsArray.get(i));
                    } else {
                        String elementID = positionsArray.get(i).getElementID();
                        int foundIndex = -1;
                        for (int k = 0; k < selectedPositions.size(); k++) {
                            if (elementID.equals(selectedPositions.get(k).getElementID())) {
                                foundIndex = k;
                            }
                        }
                        selectedPositions.remove(foundIndex);
                    }
                    positionsArray.get(i).setChecked(!positionsArray.get(i).isChecked());
                } else {
                    for (PositionModel position : positionsArray) {
                        position.setChecked(false);
                    }
                    positionsArray.get(i).setChecked(true);
                    selectedPositions.clear();
                    selectedPositions.add(positionsArray.get(i));
                }
                positionsAdapter.notifyDataSetChanged();
            }
        });

        users.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (totalItemCount >= FragmentConst.DEFAULT_COUNT_WORKS) {
                    final int lastItem = firstVisibleItem + visibleItemCount;
                    if (lastItem == totalItemCount) {
                        if (!isLoading) {
                            isLoading = true;
                            startRecord += FragmentConst.DEFAULT_COUNT_WORKS;
                            getPositions(departmentID, "", false);
                        }
                    }
                }
            }

            @Override
            public void onScrollStateChanged(AbsListView absListView, int i) {
            }
        });

        // боковая навигация
        View view = getLayoutTree();
        slidingMenu = new SlidingMenu(getApplicationContext());
        slidingMenu.setMode(SlidingMenu.RIGHT);
        slidingMenu.attachToActivity(activity, SlidingMenu.SLIDING_CONTENT);
        slidingMenu.setMenu(view);
        slidingMenu.setBehindWidth(Utils.convertDpToPixel(Const.SLIDING_MENU_WIDTH, activity));

        // главный контейнер фильтров
        final SwipeRefreshLayout filtersScroll = (SwipeRefreshLayout) view.findViewById(R.id.refresh_filters);
        filtersScroll.setEnabled(false);

        navigatorLayout = (LinearLayout) view.findViewById(R.id.filters_list);

        getSelectedUsers(navigatorLayout);

        getDepartments(navigatorLayout);

        // кнопка "Готово"
        Button save = (Button) findViewById(R.id.user_chooser_activity_save);
        save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.putExtra(UsersChooserConst.SELECTED_ITEMS, RestClient.getGson().toJson(selectedPositions));
                setResult(RESULT_OK, intent);
                finish();
            }
        });
    }

    /**
     * Метод возвращает view навигатора
     *
     * @return view
     */
    private View getLayoutTree() {
        LayoutInflater ltInflater = getLayoutInflater();
        View view = ltInflater.inflate(R.layout.fragment_filters, null, false);
        (view.findViewById(R.id.sync_button_title)).setVisibility(View.GONE);
        (view.findViewById(R.id.sync_icon)).setVisibility(View.GONE);
        (view.findViewById(R.id.sync_button)).setVisibility(View.GONE);
        (view.findViewById(R.id.icon_settings)).setVisibility(View.GONE);
        ((TextView) view.findViewById(R.id.title_action_bar_filters)).setTypeface(Fonts.getMedium(activity));
        return view;
    }

    /**
     * Метод вызывается при нажатии на элемент пути
     *
     * @param layout контейнер
     * @param uuid   идентификатор элемента
     */
    private void searchListItem(LinearLayout layout, String uuid) {
        for (int i = 0; i < layout.getChildCount(); i++) {
            if (layout.getChildAt(i) instanceof UsersChooserNavigatorItem) {
                UsersChooserNavigatorItem node = (UsersChooserNavigatorItem) layout.getChildAt(i);
                if (node.getDepartmentID() != null && node.getDepartmentID().equals(uuid)) {
                    node.setSelected();
                    node.tapItem();
                    return;
                }
                searchListItem(node, uuid);
            }
        }
    }

    /**
     * Метод заполняет данными компонент "путь"
     *
     * @param pathItems элементы пути
     */
    public void initPath(List<UserModel> pathItems) {
        // очистка пути
        pathData.clear();
        for (int i = 0; i < pathItems.size(); i++) {
            Path path = new Path();
            path.setName(pathItems.get(i).getDepartmentName());
            path.setNodeID(pathItems.get(i).getUuid());
            pathData.add(path);
            if (i == pathItems.size() - 1) {
                path.setSelected(true);
            }
        }
        // обновляем компонент
        pathAdapter.notifyDataSetChanged();
        // скроллим список до конца
        pathList.scrollTo(Integer.MAX_VALUE);
    }

    /**
     * Метод загружает в список должностей по указанному departmentID
     *
     * @param departmentID идентификатор департамента
     * @param searchText   строка поиска
     */
    public void getPositions(String departmentID, String searchText, final boolean clearList) {
        this.departmentID = departmentID;
        new SendGetRequest("rest/api/userchooser/search_pos" +
                "?departmentID=" + departmentID + "" +
                (filterUserID != null && !filterUserID.equals("null") ? "&filterUserID=" + filterUserID : "") +
                (filterDepartmentID != null && !filterDepartmentID.equals("null") ? "&filterDepartmentID=" + filterDepartmentID : "") +
                "&showAll=true" +
                "&startRecord=" + startRecord +
                "&recordsCount=" + FragmentConst.DEFAULT_COUNT_WORKS +
                "&search=" + searchText +
                "&showOnlyVacant=" + (showVacant ? "true" : "false"), person) {
            @Override
            protected void onPreExecute() {
                progressBar.setVisibility(View.VISIBLE);
                super.onPreExecute();
            }

            @Override
            protected void onPostExecute(String result) {
                progressBar.setVisibility(View.GONE);
                if (result == null) {
                    return;
                }
                if (clearList) {
                    positionsArray.clear();
                }
                PositionModel[] positionModels = RestClient.getGson().fromJson(result, PositionModel[].class);
                isLoading = positionModels.length == 0;
                Collections.addAll(positionsArray, positionModels);
                for (int i = 0; i < positionsArray.size(); i++) {
                    for (int j = 0; j < selectedPositions.size(); j++) {
                        String elementID = positionsArray.get(i).getElementID();
                        String selectedElementID = selectedPositions.get(j).getElementID();
                        if (elementID.equals(selectedElementID)) {
                            positionsArray.get(i).setChecked(true);
                        }
                    }
                }
                positionsAdapter.notifyDataSetChanged();
            }
        }.execute();
    }

    /**
     * Метод добавляет плашку выбранных пользователей
     *
     * @param layout контейнер
     */
    private void getSelectedUsers(final LinearLayout layout) {

        UserModel userModel = new UserModel();
        userModel.setDepartmentName(getString(R.string.selected));

        List<UserModel> parents = new ArrayList<>();
        parents.add(userModel);

        UsersChooserNavigatorItem item = new UsersChooserNavigatorItem(activity);
        item.setPerson(person);
        item.setName(getString(R.string.selected));
        item.setLevel(1);
        item.setType(UsersChooserConst.SELECTED_USERS);
        item.setComponentType(UsersChooserConst.POSITIONS_CHOOSER);
        item.setHideIcon(true);
        item.setParents(parents);
        item.add();
        layout.addView(item);
    }

    /**
     * Метод добавляет плашку департаментов
     *
     * @param layout контейнер
     */
    public void getDepartments(final LinearLayout layout) {
        new SendGetRequest("rest/api/userchooser/search_dept?departmentID=" +
                "32b36e0c-4621-4c96-99e1-3826284c363e&showChildDepartments=false", person) {
            @Override
            protected void onPostExecute(String result) {
                if (result == null) {
                    return;
                }
                try {

                    DepartmentModel[] departments = RestClient.getGson().fromJson(result, DepartmentModel[].class);

                    UserModel userModel = new UserModel();
                    userModel.setDepartmentName(departments[0].getDepartmentName());
                    userModel.setUuid(departments[0].getDepartmentID());

                    List<UserModel> parents = new ArrayList<>();
                    parents.add(userModel);

                    UsersChooserNavigatorItem item = new UsersChooserNavigatorItem(activity);
                    item.setPerson(person);
                    item.setName(departments[0].getDepartmentName());
                    item.setLevel(1);
                    item.setType(UsersChooserConst.DEPARTMENTS);
                    item.setComponentType(UsersChooserConst.POSITIONS_CHOOSER);
                    item.setDepartmentID(departments[0].getDepartmentID());
                    item.setParents(parents);
                    item.add();
                    item.setSelected();
                    item.expand();
                    item.tapItem();

                    layout.addView(item);

                } catch (Exception exc) {
                    // handling error...
                }
            }
        }.execute();
    }

    @Override
    public void onBackPressed() {
        if (slidingMenu.isMenuShowing()) {
            hideMenu();
        } else {
            super.onBackPressed();
        }
    }

    /**
     * Метод добавляет в список выбранных пользователей
     */
    public void getSelected() {
        try {
            positionsArray.clear();
            for (PositionModel position : selectedPositions) {
                positionsArray.add(position);
            }
            positionsAdapter.notifyDataSetChanged();
        } catch (Exception exc) {
            // handling error...
        }
    }

    public void hideMenu() {
        slidingMenu.toggle();
    }
}
