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

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Base64;
import android.view.View;
import android.widget.Button;

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

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
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.utils.MyApplication;
import kz.arta.synergy.workflow.mobile.android.common.utils.Wrapper;
import kz.arta.synergy.workflow.mobile.android.files.manager.UploadFile;

/**
 * Created by neox on 15.04.14.
 * Создание работы
 */
public class CreateWork extends AsyncTask<Void, Void, String> {

    /**
     * Диалог, показывается если пользователь добавил нное количество файлов при создании работы
     */
    private ProgressDialog progressDialog;

    /**
     * Прогрессбар для активити
     */
    private ProgressWheel progressBar;

    /**
     * Активити, из которого вызывается метод
     */
    private Activity activity;

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

    /**
     * Текст работы
     */
    private String name;

    /**
     * Дата начала
     */
    private String startDate;

    /**
     * Дата заершения
     */
    private String finishDate;

    /**
     * UUID ответственного
     */
    private String userID;

    /**
     * UUID автора
     */
    private String authorID;

    /**
     * UUID исполнителей
     */
    private List<String> resUserID;

    /**
     * Приоритет
     */
    private String priority;

    /**
     * UUID формы заврешения
     */
    private String completionFormID;

    /**
     * Текст комментария
     */
    private String commentText;

    /**
     * Добавленные файлы
     */
    private List<String> fileNames;

    /**
     * Включена ли галочка "Ответственный"
     */
    private boolean enableResponsible;

    /**
     * Кнопка "Создать"
     */
    private Button createWorkButton;

    public CreateWork(ProgressWheel progressBar, Activity activity, Person person) {
        this.progressBar = progressBar;
        this.activity = activity;
        this.person = person;
    }

    /**
     * Этот метод выполняется после создания работы
     * Если пользователь добавил файлы либо комментарий при создании работы - добавляем их в созданную работу
     * При успешном выполнении всех действий - отправляем интент, что работа создалась успешно
     *
     * @param result - результат запроса в формате json
     */
    @Override
    protected void onPostExecute(String result) {
        createWorkButton.setEnabled(true);
        progressBar.setVisibility(View.GONE);
        if (result == null) {
            AppMsg.makeText(activity, activity.getString(R.string.error_create_work), AppMsg.STYLE_ALERT).show();
            return;
        }
        try {
            ErrorCode errorCode = RestClient.getGson().fromJson(result, ErrorCode.class);
            if (!errorCode.getErrorCode().equals(Wrapper.NO_ERROR)) {
                AppMsg.makeText(activity, errorCode.getErrorMessage(), AppMsg.STYLE_ALERT).show();
            } else {
                // посылаем интент что работа успешно создана
                Intent intent = new Intent();
                intent.putExtra(ActivityConst.UPDATE_WORK_LIST, ActivityConst.UPDATE_WORK_LIST);
                activity.setResult(Activity.RESULT_OK, intent);
                activity.finish();
            }
        } catch (Exception exc) {
            AppMsg.makeText(activity, activity.getString(R.string.error_create_work), AppMsg.STYLE_ALERT).show();
        }
        super.onPostExecute(result);
    }

    @Override
    protected void onPreExecute() {
        progressBar.setVisibility(View.VISIBLE);
        createWorkButton.setEnabled(false);
        if (fileNames != null && fileNames.size() != 0) {
            progressDialog = new ProgressDialog(activity);
            progressDialog.setMessage(activity.getString(R.string.please_wait));
            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progressDialog.setCancelable(false);
            progressDialog.show();
        }
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(Void... voids) {
        // если пользователь при создании работы добавил файлы - сначала добавляем их на сервер
        if (fileNames != null && fileNames.size() != 0) {
            // здесь будут храниться временные пути для добавленных файлов, их и будем отсылать на сервер при создании работы
            List<String> filePath = new ArrayList<>();
            // класс используется для добавления файла на сервер
            UploadFile uploadFile = new UploadFile(person, true, UploadFile.INBOX_FILE);
            // пробегаемся по каждому добавленному файлу с устройства
            for (String fileName : fileNames) {
                // и заливаем на сервер
                String name = new File(fileName).getName();
                String path = uploadFile.uploadFile(null, name, fileName, true);
                if (path != null) {
                    try {
                        filePath.add("path=" + path + ":" + URLEncoder.encode(name, "utf-8") + "&");
                    } catch (Exception ignored) {
                    }
                }
            }
            // создание работы с вложениями
            return create(filePath);
        } else {
            // создание работы без вложений
            return create(null);
        }
    }

    /**
     * Метод создает работу
     * При успешном выполнении - сервер возвращает строку в формате json
     * При неуспешном - возвращает null
     *
     * @return - результат запроса в формате json
     */
    private String create(List<String> filePath) {

        try {

            URL url = new URL(person.getHost() + "rest/api/workflow/work/create");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Accept", "application/json; charset=utf-8");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Cache-Control", "no-cache");
            String basicAuth = "Basic " + new String(Base64.encode((person.getAuth()).getBytes(), Base64.NO_WRAP));
            conn.setRequestProperty("Authorization", basicAuth);

            conn.setUseCaches(false);
            conn.setDoInput(true);
            conn.setDoOutput(true);

            DataOutputStream request = new DataOutputStream(conn.getOutputStream());
            request.writeBytes("name=" + URLEncoder.encode(name, "utf-8") + "&");

            request.writeBytes("startDate=" + URLEncoder.encode(startDate + ":00", "utf-8") + "&");
            request.writeBytes("finishDate=" + URLEncoder.encode(finishDate + ":00", "utf-8") + "&");

            if (enableResponsible) {
                request.writeBytes("userID=" + URLEncoder.encode(userID, "utf-8") + "&");
            }

            request.writeBytes("authorID=" + URLEncoder.encode(authorID, "utf-8") + "&");

            if (priority == null) {
                request.writeBytes("priority=" + URLEncoder.encode(person.getDefaults().getPriority(), "utf-8") + "&");
            } else {
                request.writeBytes("priority=" + URLEncoder.encode(priority, "utf-8") + "&");
            }

            if (completionFormID != null) {
                request.writeBytes("completionFormID=" + URLEncoder.encode(completionFormID, "utf-8") + "&");
            }

            if (resUserID != null) {
                for (String aResUserID : resUserID) {
                    request.writeBytes("resUserID=" + URLEncoder.encode(aResUserID, "utf-8") + "&");
                }
            }

            // если есть комментарий
            if (commentText != null && !commentText.isEmpty()) {
                request.writeBytes("comment=" + URLEncoder.encode(commentText, "utf-8") + "&");
            }

            // добавленные файлы
            if (filePath != null) {
                for (String path : filePath) {
                    request.writeBytes(path);
                }
            }

            request.writeBytes("locale=" + URLEncoder.encode(MyApplication.getLang(), "utf-8") + "&");
            request.flush();
            request.close();

            InputStream is = conn.getInputStream();
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            String line;
            StringBuilder response = new StringBuilder();
            while ((line = rd.readLine()) != null) {
                response.append(line);
                response.append('\r');
            }
            rd.close();

            return response.toString();
        } catch (Exception e) {
            return null;
        }
    }

    public void setEnableResponsible(boolean enableResponsible) {
        this.enableResponsible = enableResponsible;
    }

    public void setResUserID(List<String> resUserID) {
        this.resUserID = resUserID;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setStartDate(String startDate) {
        this.startDate = startDate;
    }

    public void setFinishDate(String finishDate) {
        this.finishDate = finishDate;
    }

    public void setUserID(String userID) {
        this.userID = userID;
    }

    public void setAuthorID(String authorID) {
        this.authorID = authorID;
    }

    public void setPriority(String priority) {
        this.priority = priority;
    }

    public void setCompletionFormID(String completionFormID) {
        this.completionFormID = completionFormID;
    }

    public void setCommentText(String commentText) {
        this.commentText = commentText;
    }

    public void setFileNames(List<String> fileNames) {
        this.fileNames = fileNames;
    }

    public void setCreateWorkButton(Button createWorkButton) {
        this.createWorkButton = createWorkButton;
    }
}
