package com.hikapro.backpack.model.dao;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;

import com.hikapro.backpack.App;
import com.hikapro.backpack.R;
import com.hikapro.backpack.model.NetworkUtil;

/**
 * Created by tariel on 04/05/16.
 */
public class ImageDownloadHelper {

    public static final String IMAGE_DOWNLOAD_TAG = "Image download";
    public static final String IMAGE_DIRECTORY_NAME = "items";
    private Context context;

    public ImageDownloadHelper() {
        this.context = App.getAppContext();
    }

    public Bitmap loadImage(String netPath) {
        Bitmap bitmap = null;
        if (NetworkUtil.isInternetAvailable()) {
            try {
                URL url = new URL(netPath);
                URLConnection conn = url.openConnection();
                conn.setReadTimeout(4000);
                bitmap = BitmapFactory.decodeStream(conn.getInputStream());
            } catch (SocketTimeoutException ex) {
                bitmap = null;
                Log.e(IMAGE_DOWNLOAD_TAG, " Timeout elapsed.");
            } catch (Exception ex) {
                Log.e(IMAGE_DOWNLOAD_TAG, " File cannot be downloaded due to exception.");
            }
        }

        return bitmap;
    }

    public boolean existsExternal(String filename) {
        boolean ret = false;
        if (isExternalStorageReadable()) {
            File directory = getDir();
            File file = new File(directory.getAbsoluteFile(), filename);
            ret = file.exists();
        }
        return ret;
    }
    public boolean existsInternal(String filename) {
        boolean ret = false;
        File file = createTempFile(filename);
        if (file != null) {
            ret = file.exists();
        }
        return ret;
    }

    private File createTempFile(String fileName) {
        File file = null;
        try {
            file = File.createTempFile(fileName, null, context.getCacheDir());
        }  catch (IOException e) {
            Log.e(IMAGE_DOWNLOAD_TAG, " Cannot obtain temp file");
        }

        return file;
    }

    public String generateFileName(String netPath) {
        String ret = "";
        if (netPath != null && !netPath.isEmpty()) {
            ret = Uri.parse(netPath).getLastPathSegment();
        }
        return ret;
    }

    public String saveImageInternal(String filename, Bitmap bitmap) {
        File file = null;
        FileOutputStream outputStream = null;
        if (bitmap != null && !filename.isEmpty()) {
            file = createTempFile(filename);
            if (file != null) {
                try {
                    outputStream = new FileOutputStream(file);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
                } catch (Exception e) {
                    Log.e(IMAGE_DOWNLOAD_TAG, "File cannot be saved (Internal): " + e);
                } finally {

                    if (outputStream != null) {
                        try {
                            outputStream.flush();
                            outputStream.close();
                        } catch (IOException e) {
                            // do nothing here
                        }
                    }
                }
            }
        }
        return file != null ? file.getAbsolutePath() : null;
    }

    public String saveImageExternal(String filename, Bitmap bitmap) {
        File file = null;
        FileOutputStream outputStream = null;
        if (isExternalStorageWritable()) {
            if (bitmap != null && !filename.isEmpty()) {
                try {
                    File directory = getDir();
                    if (directory != null) {
                        file = new File(directory.getAbsoluteFile(), filename);
                        outputStream = new FileOutputStream(file);
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
                    } else {
                        Log.e(IMAGE_DOWNLOAD_TAG, "Saving failed (External): directory unavailable.");
                    }
                } catch (Exception e) {
                    Log.e(IMAGE_DOWNLOAD_TAG, "File cannot be saved (External): " + e);

                } finally {

                    if (outputStream != null) {
                        try {
                            outputStream.flush();
                            outputStream.close();

                        } catch (IOException e) {
                            // do nothing here
                        }
                    }
                }
            }
        }
        return file != null ? file.getAbsolutePath() : null;
    }

    /* Checks if external storage is available for read and write */
    public boolean isExternalStorageWritable() {
        boolean ret;
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            ret = true;
        } else
            ret = false;

        return ret;
    }

    /* Checks if external storage is available to at least read */
    public boolean isExternalStorageReadable() {
        boolean ret;
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state) ||
                Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            ret = true;
        } else
            ret = false;

        return ret;
    }

    private File getDir() {
        File ret = null;
        // Get available SD cards
        File[] dirs = ContextCompat.getExternalFilesDirs(context, Environment.DIRECTORY_PICTURES);
        if (dirs != null) {
            switch (dirs.length) {
                case 1:
                    ret = new File(dirs[0], IMAGE_DIRECTORY_NAME); // can be emulated SD card
                    break;
                case 2:
                    ret = new File(dirs[1], IMAGE_DIRECTORY_NAME);// real SD card
                    break;
            }
        }

        if (!ret.mkdirs()) {
            Log.e(IMAGE_DOWNLOAD_TAG, "Directory was not created or already exists.");
        }
        return ret;
    }
}
