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

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Base64;
import android.util.Log;

import com.devspark.appmsg.AppMsg;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Map;
import java.util.Set;

import kz.arta.synergy.workflow.mobile.android.R;
import kz.arta.synergy.workflow.mobile.android.common.models.Person;
import kz.arta.synergy.workflow.mobile.android.common.utils.Const;
import kz.arta.synergy.workflow.mobile.android.common.utils.Utils;

/**
 * Created by neox on 10.04.14.
 * Загрузка и открытие файла
 */
public class DownloadFile extends AsyncTask<String, Integer, String> {

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

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

    /**
     * Имя файла
     */
    private String fileName;

    /**
     * Прогресс выполнения
     */
    private ProgressDialog progressDialog;

    /**
     * Ссылка на скачивание файла
     */
    private String url;

    /**
     * Используется ли только скачивание
     */
    private boolean onlyGet;

    /**
     * Размер
     */
    private String contentLength;

    public DownloadFile(Activity activity, Person person) {
        this.activity = activity;
        this.person = person;
        progressDialog = new ProgressDialog(activity);
    }

    @Override
    protected void onPreExecute() {
        if (!onlyGet) {
            progressDialog.setMessage(activity.getString(R.string.wait_while_file_will_added) + "...");
            progressDialog.setCancelable(true);
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.show();
            progressDialog.setCancelable(false);
        }
    }

    @Override
    protected String doInBackground(String... params) {
        int totalSize;
        int downloadedSize;
        HttpURLConnection connection = null;
        try {
            String contentDis = null;
            contentLength = null;
            URL urls = new URL(url);
            connection = (HttpURLConnection) urls.openConnection();
            String basicAuth = "Basic " + new String(Base64.encode(person.getAuth().getBytes(), Base64.NO_WRAP));
            connection.setRequestProperty("Authorization", basicAuth);
            Map headerFields = connection.getHeaderFields();
            Set headers = headerFields.entrySet();
            File folder = new File(Environment.getExternalStorageDirectory() + File.separator + Const.DIRECTORY_PHOTOS_NAME);
            if (!folder.exists()) {
                folder.mkdir();
            }
            if (onlyGet) {
                InputStream is = connection.getInputStream();
                BufferedInputStream inStream = new BufferedInputStream(is, 1024);
                FileOutputStream outStream = new FileOutputStream(folder + File.separator + fileName);
                byte[] buff = new byte[1024];
                totalSize = connection.getContentLength();
                progressDialog.setMax(totalSize / 1024);
                downloadedSize = 0;
                int bufferLength;
                while ((bufferLength = inStream.read(buff)) > 0) {
                    outStream.write(buff, 0, bufferLength);
                    downloadedSize += bufferLength;
                    publishProgress(downloadedSize);
                }
                outStream.flush();
                outStream.close();
                inStream.close();
            } else {
                for (Object header : headers) {
                    Map.Entry map = (Map.Entry) header;
                    if ("Content-Disposition".equals(map.getKey())) {
                        contentDis = map.getValue().toString();
                        Log.d("TAGSS", contentDis);
                    }
                    if ("Content-Length".equals(map.getKey())) {
                        contentLength = map.getValue().toString();
                    }
                }
                if (contentDis != null) {
                    StringBuilder buffer = new StringBuilder(contentDis);
                    if (buffer.indexOf("\"") != -1) {
                        fileName = URLDecoder.decode(buffer.substring(buffer.indexOf("filename") + 10, buffer.length() - 1), "UTF-8");
                        fileName = fileName.substring(fileName.indexOf("''")+2);
                    } else {
                        fileName = URLDecoder.decode(buffer.substring(buffer.indexOf("filename") + 10, buffer.length() - 1), "UTF-8");
                        fileName = fileName.substring(fileName.indexOf("''")+2);
                    }
                    InputStream is = connection.getInputStream();
                    BufferedInputStream inStream = new BufferedInputStream(is, 1024);
                    FileOutputStream outStream = new FileOutputStream(folder + File.separator + fileName);
                    byte[] buff = new byte[1024];
                    totalSize = connection.getContentLength();
                    progressDialog.setMax(totalSize / 1024);
                    downloadedSize = 0;
                    int bufferLength;
                    while ((bufferLength = inStream.read(buff)) > 0) {
                        outStream.write(buff, 0, bufferLength);
                        downloadedSize += bufferLength;
                        publishProgress(downloadedSize);
                    }
                    outStream.flush();
                    outStream.close();
                    inStream.close();
                } else {
                    String line;
                    InputStream is = connection.getInputStream();
                    BufferedReader in = new BufferedReader(new InputStreamReader(is));
                    StringBuilder result = new StringBuilder();
                    while ((line = in.readLine()) != null) {
                        result.append(line);
                    }
                    return result.toString();
                }
            }
        } catch (Exception e) {
            return null;
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
        return null;
    }

    protected void onProgressUpdate(Integer... values) {
        if (!onlyGet) {
            progressDialog.setProgress(values[0] / 1024);
        }
    }

    @Override
    protected void onPostExecute(String result) {
        if (onlyGet) {
            return;
        }
        progressDialog.dismiss();
        if (contentLength != null && contentLength.equals("[0]")) {
            AppMsg.makeText(activity, activity.getString(R.string.printable_def_not_found), AppMsg.STYLE_ALERT).show();
            return;
        }
        if (result != null) {
            AppMsg.makeText(activity, result, AppMsg.STYLE_ALERT).show();
        } else {
            String fullFilePath = Environment.getExternalStorageDirectory() +
                    File.separator + Const.DIRECTORY_PHOTOS_NAME + File.separator + fileName;
            String mime = Utils.getMimeByFilename(fullFilePath);
            Intent intent = new Intent();
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setAction(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File(fullFilePath)), mime);
            try {
                activity.startActivity(intent);
            } catch (ActivityNotFoundException e) {
                AppMsg.makeText(activity, activity.getString(R.string.unknown_file), AppMsg.STYLE_ALERT).show();
            }
        }
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setOnlyGet(boolean onlyGet) {
        this.onlyGet = onlyGet;
    }
}