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

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

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.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 25.04.14.
 * Изменение работы
 */
public class ChangeWork extends AsyncTask<Void, Void, String> {

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

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

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

    /**
     * Имя работы
     */
    private String name;

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

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

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

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

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

    /**
     * Список добавленных файлов
     */
    private List<String> fileNames;

    /**
     * UUID работы
     */
    private String actionID;

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

    @Override
    protected void onPreExecute() {
        progressBar.setVisibility(View.VISIBLE);
        super.onPreExecute();
    }

    /**
     * Этот метод выполняется после изменения работы
     * Если пользователь добавил файлы либо комментарий при изменении работы - добавляем их в текущую работу
     * При успешном выполнении всех действий - отправляем интент, что работа изменилась успешно
     *
     * @param result - результат запроса в формате json
     */
    @Override
    protected void onPostExecute(String result) {
        progressBar.setVisibility(View.GONE);
        if (result == null) {
            AppMsg.makeText(activity, activity.getString(R.string.error_edit_work), AppMsg.STYLE_ALERT).show();
            return;
        }
        try {
            Result errorCode = RestClient.getGson().fromJson(result, Result.class);
            if (!errorCode.getErrorCode().equals(Wrapper.NO_ERROR)) {
                AppMsg.makeText(activity, errorCode.getErrorMessage(), AppMsg.STYLE_ALERT).show();
            } else {
                // если есть вложения
                if (fileNames != null && fileNames.size() != 0) {
                    new AddFiles(errorCode.getWorkID()).execute();
                } 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_edit_work), AppMsg.STYLE_ALERT).show();
        }
        super.onPostExecute(result);
    }

    @Override
    protected String doInBackground(Void... voids) {
        return change();
    }

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

        try {

            URL url = new URL(person.getHost() + "rest/api/workflow/work/save");
            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 (priority == null) {
                request.writeBytes("priority=" + URLEncoder.encode(person.getDefaults().getPriority(), "utf-8") + "&");
            } else {
                request.writeBytes("priority=" + URLEncoder.encode(priority, "utf-8") + "&");
            }
            request.writeBytes("actionID=" + URLEncoder.encode(actionID, "utf-8") + "&");
            if (userID != null) {
                request.writeBytes("userID=" + URLEncoder.encode(userID, "utf-8") + "&");
            }
            if (completionFormID != null) {
                request.writeBytes("completionFormID=" + URLEncoder.encode(completionFormID, "utf-8") + "&");
            }
            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 setUserID(String userID) {
        this.userID = userID;
    }

    public void setActionID(String actionID) {
        this.actionID = actionID;
    }

    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 setPriority(String priority) {
        this.priority = priority;
    }

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

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

    /**
     * Ответ от сервера
     */
    class Result extends ErrorCode {

        String workID;

        public String getWorkID() {
            return workID;
        }
    }

    /**
     * Если пользователь добавил нное количество файлов при изменении работы - вызывается этот класс
     * На вход принимает workID и progressDialog
     */
    class AddFiles extends AsyncTask<Void, Void, Void> {

        String workID;

        public AddFiles(String workID) {
            this.workID = workID;
        }

        @Override
        protected Void doInBackground(Void... voids) {
            UploadFile uploadFile = new UploadFile(person, false, UploadFile.INBOX_FILE);
            for (String fileName : fileNames) {
                uploadFile.uploadFile(workID, new File(fileName).getName(), fileName, true);
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            progressBar.setVisibility(View.GONE);
            Intent intent = new Intent();
            intent.putExtra(ActivityConst.UPDATE_WORK_LIST, ActivityConst.UPDATE_WORK_LIST);
            activity.setResult(Activity.RESULT_OK, intent);
            activity.finish();
            super.onPostExecute(aVoid);
        }
    }
}
