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

import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.devspark.appmsg.AppMsg;
import com.google.gson.JsonSyntaxException;
import com.pnikosis.materialishprogress.ProgressWheel;

import java.io.Serializable;
import java.util.ArrayList;
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.models.ErrorCode;
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.Fonts;
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.resolution.ResolutionConst;
import kz.arta.synergy.workflow.mobile.android.documents.resolution.adapters.AdapterResolution;
import kz.arta.synergy.workflow.mobile.android.documents.resolution.manager.SaveResolution;
import kz.arta.synergy.workflow.mobile.android.documents.resolution.models.ItemResolution;
import kz.arta.synergy.workflow.mobile.android.documents.resolution.models.ItemResolutionInfo;

/**
 * Created by neox on 14.09.14.
 * Экран со списком резолюций
 */
public class ResolutionActivity extends Activity {

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

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

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

    /**
     * Кнопка "Сохранить"
     */
    private Button saveResolutionButton;

    /**
     * Чекбокс "Является контрольным"
     */
    private CheckBox controlled;

    /**
     * Идентификатор работы
     */
    private String workID;

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

    /**
     * Элеметы резолюции
     */
    private List<ItemResolution> data;

    /**
     * Адаптер списка
     */
    private AdapterResolution adapterResolution;

    /**
     * Выделенный элемент
     */
    private int selectedItem;

    /**
     * Весь массив резолюций
     */
    private ItemResolutionInfo[] resolutions;

    /**
     * Элемент резолюции
     */
    private int item;

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

    /**
     * Добавляется новая либо редактируетя существующая
     */
    private boolean isNew;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

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

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

        activity = this;
        person = (Person) getIntent().getSerializableExtra(ActivityConst.PERSON);
        workID = getIntent().getStringExtra(ActivityConst.WORK_ID);
        documentID = getIntent().getStringExtra(ActivityConst.DOCUMENT_ID);
        item = getIntent().getIntExtra(ActivityConst.WORK_INFO_RESOLUTION_ITEM, 0);
        isNew = getIntent().getBooleanExtra(ActivityConst.IS_NEW, false);

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

        // создаем компоненты
        initComponents();

        // загружаем данные о резолюции
        getResolutionInfo();


    }

    /**
     * Инициализация компонентов
     */
    private void initComponents() {

        data = new ArrayList<>();
        adapterResolution = new AdapterResolution(activity, data, person);

        ListView listView = (ListView) findViewById(R.id.item_resolution_list_view);
        listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
                if (resolutions[item].getCanEdit().equals("true")) {
                    selectedItem = i;
                    showRemoveDialog();
                } else {
                    AppMsg.makeText(activity, getString(R.string.resolution_accept_access_denied), AppMsg.STYLE_ALERT).show();
                }
                return true;
            }
        });

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                if (resolutions[item].getCanEdit().equals("true")) {
                    Intent intent = new Intent(activity, AddResolutionActivity.class);
                    intent.putExtra(ActivityConst.RESOLUTION_ITEM, data.get(position));
                    intent.putExtra(ActivityConst.PERSON, person);
                    intent.putExtra(ActivityConst.ITEM_NUMBER, String.valueOf(position));
                    intent.putExtra(ActivityConst.STATUS, Integer.parseInt(resolutions[item].getStatusID()));
                    intent.putExtra(ActivityConst.MAX_FINISH_DATE, resolutions[item].getMaxFinishDate());
                    startActivityForResult(intent, ResolutionConst.EDIT_ITEM_ACTIVITY);
                } else {
                    AppMsg.makeText(activity, getString(R.string.resolution_accept_access_denied), AppMsg.STYLE_ALERT).show();
                }
            }
        });

        listView.setAdapter(adapterResolution);

        // заголовок actionbar'а
        ((TextView) findViewById(R.id.title_action_bar_resolution)).setTypeface(Fonts.getMedium(activity));

        controlled = (CheckBox) findViewById(R.id.checkbox_resolution_have_control);
        controlled.setTypeface(Fonts.getMedium(activity));

        final CheckBox controlled = (CheckBox) findViewById(R.id.checkbox_resolution_have_control);
        controlled.setTypeface(Fonts.getMedium(activity));
        controlled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if (!resolutions[item].getCanEdit().equals("true")) {
                    AppMsg.makeText(activity, getString(R.string.resolution_accept_access_denied), AppMsg.STYLE_ALERT).show();
                    controlled.setChecked(false);
                }
            }
        });

        Button addItemButton = (Button) findViewById(R.id.add_item_resolution);
        addItemButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (resolutions[item].getCanEdit().equals("true")) {
                    Intent intent = new Intent(activity, AddResolutionActivity.class);
                    intent.putExtra(ActivityConst.PERSON, person);
                    intent.putExtra(ActivityConst.MAX_FINISH_DATE, resolutions[item].getMaxFinishDate());
                    startActivityForResult(intent, ResolutionConst.ADD_ITEM_ACTIVITY);
                } else {
                    AppMsg.makeText(activity, getString(R.string.resolution_accept_access_denied), AppMsg.STYLE_ALERT).show();
                }
            }
        });

        Button acceptResolutionButton = (Button) findViewById(R.id.accept_resolution);
        acceptResolutionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (resolutions[item].getCanEdit().equals("true")) {
                    if (isNew) {
                        showRepeatResolutionDialog();
                    } else {
                        acceptSaveResolution(true);
                    }
                } else {
                    AppMsg.makeText(activity, getString(R.string.resolution_accept_access_denied), AppMsg.STYLE_ALERT).show();
                }
            }
        });

        saveResolutionButton = (Button) findViewById(R.id.save_resolution);
        saveResolutionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                acceptSaveResolution(false);
            }
        });

        TextView titleHaveControl = (TextView) findViewById(R.id.checkbox_resolution_have_control_title);
        titleHaveControl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                controlled.setChecked(!controlled.isChecked());
            }
        });
    }

    /**
     * Метод отображает диалог с вопросом о наложении дополнительной резолюции
     */
    private void showRepeatResolutionDialog() {
        AlertDialog.Builder ad = new AlertDialog.Builder(activity);
        ad.setTitle(getString(R.string.start_resolution_title));
        ad.setMessage(getString(R.string.warning_resolution_text));
        ad.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int arg1) {
                acceptSaveResolution(true);
            }
        });
        ad.setNegativeButton(getString(R.string.no), null);
        ad.setCancelable(false);
        ad.show();
    }

    /**
     * Метод формирует строку и отправляет запрос на сервер
     *
     * @param accept принимаем или сохраняем резолюцию
     */
    private void acceptSaveResolution(boolean accept) {
        // если есть право редактировать резолюцию
        if (!resolutions[item].getCanEdit().equals("true")) {
            return;
        }
        // если выбран хоть один пункт резолюции
        if (data.isEmpty()) {
            AppMsg.makeText(activity, getString(R.string.no_resolution_items), AppMsg.STYLE_ALERT).show();
            return;
        }
        progressBar.setVisibility(View.VISIBLE);
        // здесь будут храниться пункты резолюции
        List<DataForSend> items = new ArrayList<>();
        for (ItemResolution item : data) {
            // пользователи
            List<String> users = new ArrayList<>();
            if (item.getUsers() != null && item.getUsers().length != 0) {
                for (int j = 0; j < item.getUsers().length; j++) {
                    users.add(item.getUsers()[j].getUserID());
                }
            }
            items.add(new DataForSend(
                    item.getName(),
                    item.getUserID(),
                    users,
                    (item.getFinishdate() != null && item.getFinishdate().getDate() != null ? item.getFinishdate().getDate() : null),
                    item.getDictID(),
                    item.getCompletionFormID(),
                    item.getItemID())
            );
        }
        // получаем финальную json строку и отправляем на сервер
        String result = RestClient.getGson().toJson(items);
        if (result != null) {
            SaveRes save = new SaveRes(result, accept);
            save.execute();
        }
    }

    /**
     * Метод отображения диалога удаления
     */
    private void showRemoveDialog() {
        AlertDialog.Builder ad = new AlertDialog.Builder(activity);
        ad.setTitle(getString(R.string.remove_resolution_title));  // заголовок
        ad.setMessage(getString(R.string.remove_resolution_text)); // сообщение
        ad.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int arg1) {
                data.remove(selectedItem);
                adapterResolution.notifyDataSetChanged();
            }
        });
        ad.setNegativeButton(getString(R.string.no), null);
        ad.setCancelable(false);
        ad.show();
    }

    /**
     * Метод отправляет запрос на получение резолюции
     */
    private void getResolutionInfo() {
        String url;
        if (workID != null) {
            url = "rest/api/docflow/doc/get_resolution?workID=" + workID + "&locale=" +
                    MyApplication.getLang();
        } else {
            url = "rest/api/docflow/doc/get_resolution?documentID=" + documentID + "&locale=" +
                    MyApplication.getLang();
        }
        new SendGetRequest(url, person) {
            @Override
            protected void onPostExecute(String result) {
                progressBar.setVisibility(View.GONE);
                if (result == null) {
                    AppMsg.makeText(activity, getString(R.string.error_request), AppMsg.STYLE_ALERT).show();
                    return;
                }
                // пытаемся распарсить результат
                try {
                    resolutions = RestClient.getGson().fromJson(result, ItemResolutionInfo[].class);
                    saveResolutionButton.setVisibility(resolutions[item].getStatusID().equals("1") ? View.GONE : View.VISIBLE);
                    projectID = resolutions[item].getProjectID();
                    // получаем элементы резолюции
                    ItemResolution[] items = resolutions[item].getItems();
                    if (items != null && items.length != 0) {
                        // бежим по ним и добавляем полученные данные в список
                        for (ItemResolution item : items) {
                            if (Utils.getProcessByDictId(item.getDictID(), person).equals(ResolutionConst.SEND_DOCUMENT)) {
                                item.setFinishdate(null);
                            }
                            putItem(item);
                        }
                        // в самом конце обновляем адаптер
                        adapterResolution.notifyDataSetChanged();
                    }
                    if (resolutions[item].getControlled().equals("true")) {
                        controlled.setChecked(true);
                    }
                } catch (JsonSyntaxException exc) {
                    AppMsg.makeText(activity, getString(R.string.resolution_not_found), AppMsg.STYLE_ALERT).show();
                }
                super.onPostExecute(result);
            }
        }.execute();
    }

    /**
     * Метод добавляет элемент в массив data
     *
     * @param item - пункт резолюции
     */
    private void putItem(ItemResolution item) {
        ItemResolution i = new ItemResolution();
        i.setName(item.getName());
        i.setUser(item.getUser());
        i.setUserID(item.getUserID());
        i.setUsers(item.getUsers());
        i.setFinishdate(item.getFinishdate());
        i.setTypeID(item.getTypeID());
        i.setCompletionFormID(item.getCompletionFormID());
        i.setItemID(item.getItemID());
        i.setDictID(item.getDictID());
        i.setItemName(item.getItemName());
        data.add(i);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent d) {
        if (resultCode == RESULT_CANCELED) {
            return;
        }
        ItemResolution itemResolution = (ItemResolution) d.getSerializableExtra(ActivityConst.RESOLUTION_ITEM);
        if (requestCode == ResolutionConst.ADD_ITEM_ACTIVITY) {
            if (itemResolution != null) {
                data.add(itemResolution);
                adapterResolution.notifyDataSetChanged();
            }
        } else if (requestCode == ResolutionConst.EDIT_ITEM_ACTIVITY) {
            String item = (String) d.getSerializableExtra(ActivityConst.ITEM_NUMBER);
            if (itemResolution != null && item != null) {
                data.set(Integer.parseInt(item), itemResolution);
                adapterResolution.notifyDataSetChanged();
            }
        }
        super.onActivityResult(requestCode, resultCode, d);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }

    /**
     * Запрос на сервер
     */
    class SaveRes extends AsyncTask<Void, Void, String> {

        /**
         * Информация о пунктах резолюции
         */
        String data;

        /**
         * Происходит сохранение либо подтверждение
         */
        boolean accept;

        /**
         * Активен ли чекбокс "Является контрольным"
         */
        boolean isControlled;

        public SaveRes(String data, boolean accept) {
            this.data = data;
            this.accept = accept;
        }

        @Override
        protected void onPreExecute() {
            isControlled = controlled.isChecked();
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String result) {
            progressBar.setVisibility(View.GONE);
            if (result == null) {
                AppMsg.makeText(activity, getResources().getString(R.string.error_request), AppMsg.STYLE_ALERT).show();
                return;
            }
            try {
                ErrorCode errorCode = RestClient.getGson().fromJson(result, ErrorCode.class);
                if (errorCode != null) {
                    if (errorCode.getErrorCode().equals(Wrapper.NO_ERROR)) {
                        Toast.makeText(activity, errorCode.getErrorMessage(), Toast.LENGTH_LONG).show();
                        finish();
                    } else {
                        AppMsg.makeText(activity, errorCode.getErrorMessage(), AppMsg.STYLE_ALERT).show();
                    }
                }
            } catch (JsonSyntaxException exc) {
                AppMsg.makeText(activity, exc.getMessage(), AppMsg.STYLE_ALERT).show();
            }
            super.onPostExecute(result);
        }

        @Override
        protected String doInBackground(Void... voids) {
            SaveResolution saveResolution = new SaveResolution();
            saveResolution.setPerson(person);
            return saveResolution.saveResolution(data, workID, documentID, accept, projectID, isControlled);
        }
    }

    class DataForSend implements Serializable {

        /**
         * Имя пункта
         */
        String name;

        /**
         * Идентификатор исполнителя
         */
        String userID;

        /**
         * Идентификаторы исполнителей
         */
        List<String> usersID;

        /**
         * Дата завершения в миллисекундах
         */
        String finishDate;

        /**
         * Идентификатор процесса
         */
        String dict_id;

        /**
         * Идентификатор формы завершения
         */
        String completionFormID;

        /**
         * Идентификатор пункта (используется при редактировании)
         */
        String itemID;

        DataForSend(String name, String userID, List<String> usersID,
                    String finishDate, String dict_id, String completionFormID, String itemID) {
            this.name = name;
            this.userID = userID;
            this.usersID = usersID;
            this.finishDate = finishDate;
            this.dict_id = dict_id;
            this.completionFormID = completionFormID;
            this.itemID = itemID;
        }
    }

}
