package kz.arta.synergy.workflow.mobile.android.works.activities.create;

import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;

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

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.CreateDefaults;
import kz.arta.synergy.workflow.mobile.android.common.models.Person;
import kz.arta.synergy.workflow.mobile.android.common.models.settings.DialogInfoItem;
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.DateUtils;
import kz.arta.synergy.workflow.mobile.android.common.utils.MyApplication;
import kz.arta.synergy.workflow.mobile.android.works.fragments.FragmentCreateWork;
import kz.arta.synergy.workflow.mobile.android.works.manager.create.ChangeWork;
import kz.arta.synergy.workflow.mobile.android.works.manager.create.CreateWork;
import kz.arta.synergy.workflow.mobile.android.works.models.WorkItem;

/**
 * Создание работы (новая версия, с шагами)
 * Created by neox on 29.05.15.
 */
public class CreateWorkCustomActivity extends FragmentActivity {

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

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

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

    /**
     * Идентификатор текущего диалога
     */
    private String dialogUUID;

    /**
     * Фрагменты внутри ViewPager'e
     */
    private Map<Integer, FragmentCreateWork> fragments;

    /**
     * Работа (используется только при редактировании работы)
     */
    private WorkItem work;

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {

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

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

        activity = this;

        fragments = new HashMap<>();

        // прогресс
        progressBar = (ProgressWheel) findViewById(R.id.create_work_progress_bar);

        // все данные о пользователе
        person = (Person) getIntent().getSerializableExtra(ActivityConst.PERSON);

        // идентификатор диалога
        dialogUUID = getIntent().getStringExtra(ActivityConst.DIALOG_UUID);

        // описание диалога
        DialogInfoItem dialog = (DialogInfoItem) getIntent().getSerializableExtra(ActivityConst.DIALOG);
        if (dialog != null) {
            dialog.setSteps(getComponents(dialog));
        }

        // рабта
        work = (WorkItem) getIntent().getSerializableExtra(ActivityConst.WORK);

        // если изменяем работу - загружаем только диалог, иначе диалог и данные для создания работы
        if (work != null && dialog != null) {
            init(dialog);
        } else {
            getCreateDefaults();
        }
    }

    /**
     * Инициализация
     */
    private void init(DialogInfoItem dialog) {
        initActionBar(dialog.getName());
        initViewPager(dialog);
    }

    /**
     * Метод выполняется после успешной загрузки информации о диалоге - инициализирует ViewPager
     */
    private void initViewPager(final DialogInfoItem dialog) {
        PagerAdapter workPageAdapter = new PagerAdapter(getSupportFragmentManager(), dialog);
        RelativeLayout viewPagerPanel = (RelativeLayout) findViewById(R.id.create_work_view_pager_layout);
        ViewPager viewPager = (ViewPager) viewPagerPanel.findViewById(R.id.create_work_view_pager);
        viewPager.setAdapter(workPageAdapter);
        CirclePageIndicator indicator = (CirclePageIndicator) viewPagerPanel.findViewById(R.id.create_work_indicator);
        indicator.setViewPager(viewPager);
        indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int i, float v, int i2) {
            }

            @Override
            public void onPageSelected(int position) {
            }

            @Override
            public void onPageScrollStateChanged(int i) {
            }
        });
        // если всего один шаг - выключаем индикаторы
        if (dialog.getSteps().size() == 1) {
            viewPagerPanel.setVisibility(View.VISIBLE);
            indicator.setVisibility(View.GONE);
        } else {
            viewPagerPanel.setVisibility(View.VISIBLE);
        }
        // натажие на кнопку сохранить
        createWorkButton = (Button) findViewById(R.id.create_work_button_save);
        createWorkButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                createWork();
            }
        });
    }

    /**
     * Вызывается при нажатии на кнопку "Сохранить" (отправляет запрос на создание работы)
     */
    private void createWork() {
        String name = null;
        String responsibleID = null;
        String authorID = null;
        List<String> users = null;
        String startDate = null;
        String finishDate = null;
        String priority = null;
        String comment = null;
        String completionFormID = null;
        List<String> files = null;
        for (Map.Entry<Integer, FragmentCreateWork> entry : fragments.entrySet()) {
            FragmentCreateWork fragment = entry.getValue();
            if (fragment.getName() != null) {
                name = fragment.getName();
            }
            if (fragment.getResponsibleID() != null) {
                responsibleID = fragment.getResponsibleID();
            }
            if (fragment.getAuthorID() != null) {
                authorID = fragment.getAuthorID();
            }
            if (fragment.getSelectedUsers() != null) {
                users = fragment.getSelectedUsers();
            }
            if (fragment.getStartDate() != null) {
                startDate = fragment.getStartDate();
            }
            if (fragment.getFinishDate() != null) {
                finishDate = fragment.getFinishDate();
            }
            if (fragment.getPriority() != null) {
                priority = fragment.getPriority();
            }
            if (fragment.getComment() != null) {
                comment = fragment.getComment();
            }
            if (fragment.getCompletionFormID() != null) {
                completionFormID = fragment.getCompletionFormID();
            }
            if (fragment.getFiles().size() != 0) {
                files = fragment.getFiles();
            }
        }
        if (name == null || name.isEmpty()) {
            AppMsg.makeText(activity, getString(R.string.empty_edit), AppMsg.STYLE_ALERT).show();
            return;
        }
        if (priority != null && priority.equals("-1")) {
            AppMsg.makeText(activity, getString(R.string.message_incorrect_priority), AppMsg.STYLE_ALERT).show();
            return;
        }
        if (work != null) {
            try {
                Calendar cal1 = Calendar.getInstance();
                Calendar cal2 = Calendar.getInstance();
                cal1.setTime(new SimpleDateFormat(DateUtils.DEFAULT_DATE_FORMAT).parse(finishDate));
                cal2.setTime(new SimpleDateFormat(DateUtils.DEFAULT_DATE_FORMAT).parse(work.getFinish_date()));
                if (!responsibleID.equals(work.getUser().getID())) {
                    if (work.getIs_expired().equals("true")) {
                        if (!cal1.after(cal2)) {
                            AppMsg.makeText(activity, getString(R.string.can_not_change_expired_work_responsible), AppMsg.STYLE_ALERT).show();
                        } else {
                            showDialogChangeWork(name, responsibleID, priority, startDate, finishDate, completionFormID, files);
                        }
                    } else {
                        showDialogChangeWork(name, responsibleID, priority, startDate, finishDate, completionFormID, files);
                    }
                } else {
                    changeWorkRequest(name, responsibleID, priority, startDate, finishDate, completionFormID, files);
                }
            } catch (Exception exc) {
                AppMsg.makeText(activity, exc.getMessage(), AppMsg.STYLE_ALERT).show();
            }
        } else {
            if (responsibleID == null) {
                if (users == null || users.size() == 0) {
                    AppMsg.makeText(activity, getString(R.string.empty_edit), AppMsg.STYLE_ALERT).show();
                    return;
                }
            }
            CreateWork create = new CreateWork(progressBar, activity, person);
            // кнопка "Сохранить"
            create.setCreateWorkButton(createWorkButton);
            // текст работы
            create.setName(name);
            // добавлять ли ответственного
            create.setEnableResponsible(responsibleID != null);
            // автор работы
            create.setAuthorID(authorID);
            // исполнитель работы
            create.setUserID(responsibleID);
            // соисполнители (если есть)
            create.setResUserID(users);
            // начальное время
            create.setStartDate(startDate);
            // время завершения
            create.setFinishDate(finishDate);
            // приоритет
            create.setPriority(priority);
            // передаем форму завершения
            create.setCompletionFormID(completionFormID);
            // если комментарий есть - добавляем его
            create.setCommentText(comment);
            // передаем список файлов
            create.setFileNames(files);
            // и запускаем поток
            create.execute();
        }
    }

    /**
     * Запрос на изменение работы
     *
     * @param name             текст работы
     * @param responsibleID    uuid ответственного
     * @param priority         приоритет
     * @param startDate        дата начала
     * @param finishDate       дата завершения
     * @param completionFormID форма завершения
     * @param files            список добавленных файлов
     */
    private void changeWorkRequest(String name, String responsibleID, String priority,
                                   String startDate, String finishDate, String completionFormID, List<String> files) {
        ChangeWork changeWork = new ChangeWork(progressBar, activity, person);
        changeWork.setFileNames(files);
        changeWork.setCompletionFormID(completionFormID);
        changeWork.setFinishDate(finishDate);
        changeWork.setStartDate(startDate);
        if (!work.getUser().getID().equals(responsibleID)) {
            changeWork.setUserID(responsibleID);
        }
        changeWork.setName(name);
        changeWork.setPriority(priority);
        changeWork.setActionID(work.getActionID());
        changeWork.execute();
    }

    /**
     * Диалог вызывается при изменении работы - если пользователь изменил ответственного
     */
    private void showDialogChangeWork(final String name, final String responsibleID, final String priority,
                                      final String startDate, final String finishDate, final String completionFormID, final List<String> fileNames) {
        AlertDialog.Builder ad = new AlertDialog.Builder(activity);
        ad.setTitle(getString(R.string.change_responsible));  // заголовок
        ad.setMessage(getString(R.string.message_change_responsible_change_work));
        ad.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int arg1) {
                changeWorkRequest(name, responsibleID, priority, startDate, finishDate, completionFormID, fileNames);
            }
        });
        ad.setNegativeButton(getString(R.string.no), null);
        ad.setCancelable(true);
        ad.show();
    }

    /**
     * Метод загружает дефолтные параметры для создания работы при открытии экрана
     */
    private void getCreateDefaults() {
        new SendGetRequest("rest/api/workflow/work/create_defaults", person) {
            @Override
            protected void onPreExecute() {
                progressBar.setVisibility(View.VISIBLE);
                super.onPreExecute();
            }

            @Override
            protected void onPostExecute(String result) {
                if (result == null) {
                    AppMsg.makeText(activity, getString(R.string.error_to_get_create_defaults), AppMsg.STYLE_ALERT).show();
                    progressBar.setVisibility(View.GONE);
                    return;
                }
                CreateDefaults createDefaults = null;
                try {
                    createDefaults = RestClient.getGson().fromJson(result, CreateDefaults.class);
                } catch (Exception exc) {
                    AppMsg.makeText(activity, getString(R.string.error_parsing), AppMsg.STYLE_ALERT).show();
                }
                if (createDefaults != null) {
                    person.setDefaults(createDefaults);
                    getDialogInfo();
                } else {
                    progressBar.setVisibility(View.GONE);
                }
                super.onPostExecute(result);
            }
        }.execute();
    }

    /**
     * Метод загружает информацию о диалоге
     */
    private void getDialogInfo() {
        new SendGetRequest("rest/api/workflow/get_dialog_info?uuid=" + dialogUUID + "&locale=" + MyApplication.getLang(), person) {
            @Override
            protected void onPostExecute(String result) {
                if (result == null) {
                    AppMsg.makeText(activity, getString(R.string.error_to_get_dialog_info), AppMsg.STYLE_ALERT).show();
                    progressBar.setVisibility(View.GONE);
                    return;
                }
                DialogInfoItem dialog = null;
                try {
                    dialog = RestClient.getGson().fromJson(result, DialogInfoItem.class);
                } catch (Exception exc) {
                    AppMsg.makeText(activity, getString(R.string.error_parsing), AppMsg.STYLE_ALERT).show();
                }
                if (dialog == null || dialog.getSteps() == null) {
                    return;
                }
                dialog.setSteps(getComponents(dialog));
                init(dialog);
                progressBar.setVisibility(View.GONE);
                super.onPostExecute(result);
            }
        }.execute();
    }

    /**
     * Метод возвращает компоненты для отрисовки экрана для создания работы
     *
     * @param dialog описание диалога, которое вернул сервер
     * @return компоненты для мобильного клиента
     */
    private List<List<DialogInfoItem.Components>> getComponents(DialogInfoItem dialog) {
        List<List<DialogInfoItem.Components>> newDialog = new ArrayList<>();
        for (int i = 0; i < dialog.getSteps().size(); i++) {
            List<DialogInfoItem.Components> components = new ArrayList<>();
            for (int j = 0; j < dialog.getSteps().get(i).size(); j++) {
                // следующие 3 компонента пока не используются в мобильном клиенте, поэтому фильтруем
                if (dialog.getSteps().get(i).get(j).isShow() && !dialog.getSteps().get(i).get(j).getType().equals("LOAD") &&
                        !dialog.getSteps().get(i).get(j).getType().equals("KEYWORDS") && !dialog.getSteps().get(i).get(j).getType().equals("REPEAT")) {
                    components.add(dialog.getSteps().get(i).get(j));
                }
            }
            if (!components.isEmpty()) {
                newDialog.add(components);
            }
        }
        return newDialog;
    }

    /**
     * Заголовок actionBar'а
     *
     * @param titleActionBar - текст actionBar'а
     */
    private void initActionBar(String titleActionBar) {
        TextView textView = (TextView) findViewById(R.id.title_action_bar_create_work);
        textView.setText(titleActionBar);
    }

    private class PagerAdapter extends FragmentPagerAdapter {

        DialogInfoItem dialog;

        public PagerAdapter(FragmentManager fm, DialogInfoItem dialog) {
            super(fm);
            this.dialog = dialog;
        }

        @Override
        public Fragment getItem(int position) {
            FragmentCreateWork fragment = FragmentCreateWork.newInstance(dialog.getSteps().get(position), person, work);
            fragments.put(position, fragment);
            return fragment;
        }

        @Override
        public int getCount() {
            return dialog.getSteps().size();
        }
    }
}
