package io.scrollback.neighborhoods.modules.choosers;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.support.v4.content.CursorLoader;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;

import java.io.File;


public class ImageChooserModule extends ReactContextBaseJavaModule {

    private static final int PICK_IMAGE = 3500;

    private Context mActivityContext;
    private Promise mPickerPromise;

    public ImageChooserModule(ReactApplicationContext reactContext, Context activityContext) {
        super(reactContext);

        mActivityContext = activityContext;
    }

    @Override
    public String getName() {
        return "ImageChooserModule";
    }

    private void resolvePromise(WritableMap map) {
        if (mPickerPromise != null) {
            mPickerPromise.resolve(map);
            mPickerPromise = null;
        }
    }

    private void rejectPromise(String reason) {
        if (mPickerPromise != null) {
            mPickerPromise.reject(reason);
            mPickerPromise = null;
        }
    }

    private String getPathFromUri(Uri contentUri) {
        if (contentUri.getScheme().equals("file")) {
            return contentUri.getPath();
        }

        String[] projection = {MediaStore.Images.Media.DATA};

        CursorLoader loader = new CursorLoader(mActivityContext, contentUri, projection, null, null, null);
        Cursor cursor = loader.loadInBackground();

        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

        cursor.moveToFirst();

        String result = cursor.getString(column_index);

        cursor.close();

        return result;
    }

    private String getNameFromUri(Uri contentUri) {
        if (contentUri.getScheme().equals("file")) {
            return contentUri.getLastPathSegment();
        }

        String[] projection = {MediaStore.MediaColumns.DISPLAY_NAME};

        Cursor metaCursor = mActivityContext.getContentResolver().query(contentUri, projection, null, null, null);

        if (metaCursor != null) {
            try {
                if (metaCursor.moveToFirst()) {
                    return metaCursor.getString(0);
                }
            } finally {
                metaCursor.close();
            }
        }

        return contentUri.getLastPathSegment();
    }

    private long getSizeFromUri(Uri contentUri) {
        if (contentUri.getScheme().equals("file")) {
            return new File(contentUri.getPath()).length();
        }

        Cursor cursor = mActivityContext.getContentResolver().query(contentUri, null, null, null, null);

        cursor.moveToFirst();

        long size = cursor.getLong(cursor.getColumnIndex(OpenableColumns.SIZE));

        cursor.close();

        return size;
    }

    @ReactMethod
    public void pickImage(final Promise promise) {
        final Intent galleryIntent = new Intent(Intent.ACTION_PICK);

        galleryIntent.setType("image/*");

        final Intent chooserIntent = Intent.createChooser(galleryIntent, "Pick an image");

        ((Activity) mActivityContext).startActivityForResult(chooserIntent, PICK_IMAGE);

        mPickerPromise = promise;
    }

    public boolean handleActivityResult(final int requestCode, final int resultCode, final Intent intent) {
        if (requestCode == PICK_IMAGE) {
            if (mPickerPromise != null) {
                if (resultCode == Activity.RESULT_CANCELED) {
                    rejectPromise("Image picker was cancelled");
                } else if (resultCode == Activity.RESULT_OK) {
                    Uri uri = intent.getData();

                    if (uri != null) {
                        BitmapFactory.Options options = new BitmapFactory.Options();

                        options.inJustDecodeBounds = true;

                        BitmapFactory.decodeFile(getPathFromUri(uri), options);

                        WritableMap map = Arguments.createMap();

                        map.putInt("height", options.outHeight);
                        map.putInt("width", options.outWidth);
                        map.putDouble("size", getSizeFromUri(uri));
                        map.putString("name", getNameFromUri(uri));
                        map.putString("uri", uri.toString());

                        resolvePromise(map);
                    } else {
                        rejectPromise("Failed to pick image");
                    }
                }
            }

            return true;
        }

        return false;
    }
}

@@ -1879,24 +1879,42 @@
 kground();%0A%0A
+        try %7B%0A    
         int 
@@ -1989,32 +1989,36 @@
 DATA);%0A%0A        
+    
 cursor.moveToFir
@@ -2036,23 +2036,18 @@
     
-String result =
+    return
  cur
@@ -2075,25 +2075,24 @@
 index);%0A
-%0A
         
 cursor.c
@@ -2087,47 +2087,121 @@
     
-cursor.close();%0A%0A        return result;
+%7D catch (RuntimeException e) %7B%0A            return null;%0A        %7D finally %7B%0A            cursor.close();%0A        %7D
 %0A   
@@ -3141,32 +3141,66 @@
 , null, null);%0A%0A
+        if (cursor != null) %7B%0A    
         cursor.m
@@ -3206,32 +3206,36 @@
 moveToFirst();%0A%0A
+    
         long siz
@@ -3300,32 +3300,36 @@
 IZE));%0A%0A        
+    
 cursor.close();%0A
@@ -3333,24 +3333,28 @@
 );%0A%0A        
+    
 return size;
@@ -3354,16 +3354,45 @@
 n size;%0A
+        %7D%0A%0A        return 0;%0A
     %7D%0A%0A 
@@ -4405,24 +4405,132 @@
 ds = true;%0A%0A
+                        String path = getPathFromUri(uri);%0A%0A                        if (path != null) %7B%0A    
             
@@ -4566,35 +4566,20 @@
 odeFile(
-getPathFromUri(uri)
+path
 , option
@@ -4607,16 +4607,20 @@
         
+    
 Writable
@@ -4669,32 +4669,36 @@
                 
+    
 map.putInt(%22heig
@@ -4738,32 +4738,36 @@
                 
+ 
+   
 map.putInt(%22widt
@@ -4789,16 +4789,20 @@
 Width);%0A
+    
         
@@ -4877,32 +4877,36 @@
                 
+ 
+   
 map.putString(%22n
@@ -4925,32 +4925,36 @@
 eFromUri(uri));%0A
+    
                 
@@ -5024,16 +5024,20 @@
         
+    
 resolveP
@@ -5041,32 +5041,163 @@
 vePromise(map);%0A
+                        %7D else %7B%0A                            rejectPromise(%22Failed resolve image path%22);%0A                        %7D%0A
                 

Handle excecptions in image picker