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

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.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.common.models.ErrorCode;
import kz.arta.synergy.workflow.mobile.android.common.models.Person;
import kz.arta.synergy.workflow.mobile.android.common.offline.add.AddFinishProcess;
import kz.arta.synergy.workflow.mobile.android.common.requests.RestClient;
import kz.arta.synergy.workflow.mobile.android.common.utils.Wrapper;

/**
 * Created by neox on 21.04.14.
 * Завершение работы процессом
 */
public class FinishProcess extends AsyncTask<Void, Void, String> {

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

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

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

    /**
     * procInstID
     */
    private String procInstID;

    /**
     * Сигнал (подтверждение/отклонение)
     */
    private String signal;

    /**
     * Комментарий (будет добавлен к работе после завершения)
     */
    private String comment;

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

    /**
     * Имя работы (Оффлайн режим)
     */
    private String name;

    /**
     * Добавить подпись или нет
     */
    private boolean addSignature;

    /**
     * Данные для подписи
     */
    private String rawData;

    /**
     * Сертификат в base64
     */
    private String certificate;

    /**
     * UUID сертификата
     */
    private String certID;

    /**
     * Подписанные данные
     */
    private String signData;

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

    /**
     * Метод отправляет запрос на сервер для завершения процесса согласования/рассмотрения/ознакомления
     * В случае успешного выполнения возвращает строку в формате json
     *
     * @return - результат запроса в формате json
     */
    public String finish() {

        try {

            URL url = new URL(person.getHost() + "rest/api/workflow/finish_process");
            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("procInstID=" + URLEncoder.encode(procInstID, "utf-8") + "&");
            request.writeBytes("signal=" + URLEncoder.encode(signal, "utf-8") + "&");

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

            if (addSignature) {
                request.writeBytes("addSignature=" + URLEncoder.encode("true", "utf-8") + "&");
                request.writeBytes("rawdata=" + URLEncoder.encode(rawData, "utf-8") + "&");
                if (certificate != null) {
                    request.writeBytes("certificate=" + URLEncoder.encode(certificate, "utf-8") + "&");
                }
                if (certID != null) {
                    request.writeBytes("certID=" + URLEncoder.encode(certID, "utf-8") + "&");
                }
                if (signData != null) {
                    request.writeBytes("signdata=" + URLEncoder.encode(signData, "utf-8") + "&");
                }
            }

            request.flush();
            request.close();

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

            return response.toString();

        } catch (Exception exc) {
            return null;
        }
    }

    public String sign() {

        try {

            URL url = new URL(person.getHost() + "rest/api/docflow/sign");
            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("documentID=" + URLEncoder.encode(documentID, "utf-8") + "&");
            request.writeBytes("rawdata=" + URLEncoder.encode(rawData, "utf-8") + "&");

            if (addSignature) {
                if (certificate != null) {
                    request.writeBytes("certificate=" + URLEncoder.encode(certificate, "utf-8") + "&");
                }
                if (certID != null) {
                    request.writeBytes("certID=" + URLEncoder.encode(certID, "utf-8") + "&");
                }
                if (signData != null) {
                    request.writeBytes("signdata=" + URLEncoder.encode(signData, "utf-8") + "&");
                }
            }

            request.flush();
            request.close();

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

            return response.toString();

        } catch (Exception exc) {
            return null;
        }
    }

    @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) {
            try {
                ErrorCode errorCode = RestClient.getGson().fromJson(result, ErrorCode.class);
                if (errorCode.getErrorCode().equals(Wrapper.NO_ERROR)) {
                    Intent intent = new Intent();
                    intent.putExtra("finished_send_work", signal);
                    activity.setResult(Activity.RESULT_OK, intent);
                    activity.finish();
                } else {
                    AppMsg.makeText(activity, errorCode.getErrorMessage(), AppMsg.STYLE_ALERT).show();
                }
            } catch (Exception exc) {
                AppMsg.makeText(activity, activity.getResources().getString(R.string.error_request), AppMsg.STYLE_ALERT).show();
            }
        } else {
            AddFinishProcess finish = new AddFinishProcess(activity);
            finish.add(actionID, procInstID, signal, comment, String.valueOf(addSignature), rawData, name);
            Intent intent = new Intent();
            intent.putExtra("finished_send_work", signal);
            intent.putExtra("comment", comment);
            activity.setResult(Activity.RESULT_OK, intent);
            activity.finish();
        }
        super.onPostExecute(result);
    }

    @Override
    protected String doInBackground(Void... voids) {
        if (documentID != null) {
            return sign();
        } else {
            return finish();
        }
    }

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

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

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

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

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

    public void setProcInstID(String procInstID) {
        this.procInstID = procInstID;
    }

    public void setSignal(String signal) {
        this.signal = signal;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public void setAddSignature(boolean addSignature) {
        this.addSignature = addSignature;
    }

    public void setRawData(String rawData) {
        this.rawData = rawData;
    }

    public void setCertificate(String certificate) {
        this.certificate = certificate;
    }

    public void setCertID(String certID) {
        this.certID = certID;
    }

    public void setSignData(String signData) {
        this.signData = signData;
    }

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