package kz.arta.synergy.workflow.mobile.android.comments.manager;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
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.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

import kz.arta.synergy.workflow.mobile.android.R;
import kz.arta.synergy.workflow.mobile.android.comments.CommentConst;
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.offline.add.AddComment;
import kz.arta.synergy.workflow.mobile.android.common.offline.add.AddEditComment;
import kz.arta.synergy.workflow.mobile.android.common.offline.get.WorkCommentsTable;
import kz.arta.synergy.workflow.mobile.android.common.requests.RestClient;
import kz.arta.synergy.workflow.mobile.android.common.utils.Logger;
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.offline.DocumentCommentsTable;
import kz.arta.synergy.workflow.mobile.android.documents.offline.actions.DocumentAddCommentTable;
import kz.arta.synergy.workflow.mobile.android.documents.offline.actions.DocumentEditCommentTable;

/**
 * Created by neox on 11.04.14.
 * Добавление комментария
 */
public class AddCommentRequest extends AsyncTask<String, Void, String> {

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

    /**
     * Настройки
     */
    private SharedPreferences mSettings;

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

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

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

    /**
     * UUID документа
     */
    private String documentID;

    /**
     * Текст работы (для оффлайн режима)
     */
    private String name;

    /**
     * id комментария (передается при редактировании)
     */
    private String commentID;

    /**
     * текст комментария (передается при редактировании)
     */
    private String commentText;

    /**
     * Время добавления комментария
     */
    private String time;

    /**
     * Добавляем ли мы новый комментарий
     */
    private boolean edit;

    /**
     * Тип комментария (работа/документ/личные)
     */
    private String commentType;

    /**
     * Метод выполняется после добавления комментария
     * Если комментарий добавлен успешен - отправляем интент на обновление списка комментариев
     * Иначе - выводим сообщение об ошибке
     *
     * @param result - результат запроса в формате json
     */
    @Override
    protected void onPostExecute(String result) {
        // если ответ от сервера успешно пришел
        if (result != null) {
            try {
                ErrorCode errorCode = RestClient.getGson().fromJson(result, ErrorCode.class);
                if (documentID != null) {
                    if (errorCode.getErrorCode().equals(Wrapper.NO_ERROR)) {
                        commentAdded();
                    } else {
                        AppMsg.makeText(activity, errorCode.getMessage(), AppMsg.STYLE_ALERT).show();
                    }
                } else {
                    if (errorCode.getResult().equals(Wrapper.NO_ERROR)) {
                        commentAdded();
                    } else {
                        AppMsg.makeText(activity, errorCode.getMessage(), AppMsg.STYLE_ALERT).show();
                    }
                }
            } catch (Exception exc) {
                AppMsg.makeText(activity, activity.getResources().getString(R.string.error_request), AppMsg.STYLE_ALERT).show();
            }
        } else if (Utils.checkSyncEnables(mSettings)) {
            if (documentID != null && workID != null) {
                // если добавляется новый комментарий
                if (!edit) {
                    AddComment addComment = new AddComment(activity);
                    addComment.add(workID, person.getUserName(), String.valueOf(System.currentTimeMillis()), commentText, name, commentType);
                } else {
                    if (commentID == null) {
                        AddComment addComment = new AddComment(activity);
                        addComment.editCommentByData(time, commentText, name);
                    } else {
                        // из этой таблицы будет отправлен запрос на редактирование комментария при подключении к интернету
                        AddEditComment addEditComment = new AddEditComment(activity);
                        addEditComment.add(workID, commentID, commentText, name);
                        // этот комментарий будет отображен пользователю в оффлайн режиме
                        WorkCommentsTable workCommentsTable = new WorkCommentsTable(activity);
                        workCommentsTable.updateComment(commentText, commentID);
                    }
                }
            } else if (documentID != null) {
                if (!edit) {
                    DocumentAddCommentTable documentAddCommentTable = new DocumentAddCommentTable(activity.getBaseContext());
                    documentAddCommentTable.add(documentID, person.getUserName(), String.valueOf(System.currentTimeMillis()), commentText, name, commentType);
                } else {
                    if (commentID == null) {
                        DocumentAddCommentTable documentAddCommentTable = new DocumentAddCommentTable(activity.getBaseContext());
                        documentAddCommentTable.editCommentByData(time, commentText, name);
                    } else {
                        // из этой таблицы будет отправлен запрос на редактирование комментария при подключении к интернету
                        DocumentEditCommentTable documentEditCommentTable = new DocumentEditCommentTable(activity);
                        documentEditCommentTable.add(documentID, commentID, commentText, name);
                        // этот комментарий будет отображен пользователю в оффлайн режиме
                        DocumentCommentsTable documentCommentsTable = new DocumentCommentsTable(activity);
                        documentCommentsTable.updateComment(commentText, commentID);
                    }
                }
            } else if (workID != null) {
                // если добавляется новый комментарий
                if (!edit) {
                    AddComment addComment = new AddComment(activity);
                    addComment.add(workID, person.getUserName(), String.valueOf(System.currentTimeMillis()), commentText, name, commentType);
                } else {
                    if (commentID == null) {
                        AddComment addComment = new AddComment(activity);
                        addComment.editCommentByData(time, commentText, name);
                    } else {
                        // из этой таблицы будет отправлен запрос на редактирование комментария при подключении к интернету
                        AddEditComment addEditComment = new AddEditComment(activity);
                        addEditComment.add(workID, commentID, commentText, name);
                        // этот комментарий будет отображен пользователю в оффлайн режиме
                        WorkCommentsTable workCommentsTable = new WorkCommentsTable(activity);
                        workCommentsTable.updateComment(commentText, commentID);
                    }
                }
            }
            // возвращаем результат в активити
            Intent intent = new Intent();
            activity.setResult(Activity.RESULT_OK, intent);
            activity.finish();
        } else {
            AppMsg.makeText(activity, activity.getString(R.string.error_add_comment), AppMsg.STYLE_ALERT).show();
        }
        progressBar.setVisibility(View.GONE);
        super.onPostExecute(result);
    }

    @Override
    protected void onPreExecute() {
        // перед отправкой запроса - отображаем прогресс
        progressBar.setVisibility(View.VISIBLE);
        super.onPreExecute();
    }

    /**
     * Метод добавляет комментарий к работе
     * Возвращает строку в формате json
     *
     * @return результат запроса в формате json
     */
    public String addComment() {
        try {
            String u;
            if (documentID != null) {
                u = person.getHost() + "rest/api/docflow/doc/comments/save?locale=" + MyApplication.getLang();
            } else {
                u = person.getHost() + "rest/api/workflow/work/" + workID + "/comments/save?locale=" + MyApplication.getLang();
            }
            Logger.v(u);
            URL url = new URL(u);
            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());
            if (documentID != null) {
                request.writeBytes("documentID=" + URLEncoder.encode(documentID, "utf-8") + "&");
            } else {
                request.writeBytes("workID=" + URLEncoder.encode(workID, "utf-8") + "&");
            }
            if (edit) {
                request.writeBytes("commentID=" + URLEncoder.encode(commentID, "utf-8") + "&");
            }
            if (commentType.equals(CommentConst.PERSONAL)) {
                request.writeBytes("type=" + URLEncoder.encode(CommentConst.PERSONAL, "utf-8") + "&");
            }
            request.writeBytes("comment=" + URLEncoder.encode(commentText, "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();
            conn.disconnect();
            return response.toString();
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    protected String doInBackground(String... arg0) {
        return addComment();
    }

    /**
     * Метод говорит что комментарий успешно добавлен и возвращает OK в активити
     */
    private void commentAdded() {
        Intent intent = new Intent();
        activity.setResult(Activity.RESULT_OK, intent);
        activity.finish();
    }

    public void setCommentType(String commentType) {
        this.commentType = commentType;
    }

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

    public void setTime(String time) {
        this.time = time;
    }

    public void setProgressBar(ProgressWheel progressBar) {
        this.progressBar = progressBar;
    }

    public void setmSettings(SharedPreferences mSettings) {
        this.mSettings = mSettings;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public void setActivity(Activity activity) {
        this.activity = activity;
    }

    public void setWorkID(String workID) {
        this.workID = workID;
    }

    public void setCommentID(String commentID) {
        this.commentID = commentID;
    }

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

    public void setEdit(boolean edit) {
        this.edit = edit;
    }

    public void setDocumentID(String documentID) {
        this.documentID = documentID;
    }
}