package dp.mendelu.roman.diplomkaapp42;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.shephertz.app42.paas.sdk.android.App42API;
import com.shephertz.app42.paas.sdk.android.App42CallBack;
import com.shephertz.app42.paas.sdk.android.App42Response;
import com.shephertz.app42.paas.sdk.android.storage.GeoTag;
import com.shephertz.app42.paas.sdk.android.storage.Storage;
import com.shephertz.app42.paas.sdk.android.storage.StorageService;

import java.math.BigDecimal;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;

/**
 * Trida pro ulozeni jednoho bodu z prezencni vrstvy do cloudu. Z cloudu dostanu odpoved a tu
 * ulozim do lok. db.
 */
public class SyncIniciate extends AsyncTask<URL, Integer,Storage.JSONDocument> {
    static String TAG = "SyncIniciate";
    Activity mActivity;
    String mJson;
    float mLat;
    float mLng;
    /**
     * Predani contentu a hodnot
     * @param activity
     */
    public SyncIniciate(Activity activity, String json, float lat,float lng){
        mActivity = activity;
        mJson = json;
        mLat = lat;
        mLng = lng;
    }

    @Override
    protected Storage.JSONDocument doInBackground(URL... params) {

        GeoTag gp = new GeoTag();
        gp.setLat(new BigDecimal(mLat));
        gp.setLng(new BigDecimal(mLng));
        Log.i(TAG, mJson + mLat + mLng);
        StorageService storageService = App42API.buildStorageService();
        storageService.setGeoTag(gp);
        Storage storage = storageService.insertJSONDocument(Constants.CLOUD_DB_NAME, Constants.COLLECTION_NAME, mJson);

        /**
         * v storage mam  odpoved  + ten jeden konkretni json (size = 1)
         * storage.getJsonDocList()) mi vytahne  doc_ID + json
         * kontrolni logy
         */

        Log.i(TAG, "storage.toString()" + storage.toString());
        Log.i(TAG, "storage.getRecordCount()" + storage.getRecordCount());
        Log.i(TAG, "storage.getJsonDocList()" + storage.getJsonDocList());
        Log.i(TAG, "storage.getJsonDocList().get(0)" + storage.getJsonDocList().get(0));
        Log.i(TAG, "storage.getJsonDocList().size()" + storage.getJsonDocList().size());
        Log.i(TAG, "storage.getJsonDocList().size()" + Arrays.toString(storage.getJsonDocList().toArray()));


        Storage.JSONDocument oneJsonDoc = storage.getJsonDocList().get(0);
        String pom =  oneJsonDoc.getUpdatedAt()  +
                oneJsonDoc.getCreatedAt() +
                oneJsonDoc.getDocId()     +
                oneJsonDoc.getJsonDoc()   +
                oneJsonDoc.getLocation().getLat()+
                oneJsonDoc.getLocation().getLng();
        Log.i(TAG, "Document> " + pom);

        return oneJsonDoc;
    }

    @Override
    protected void onPostExecute(Storage.JSONDocument oneJsonDoc) {
        super.onPostExecute(oneJsonDoc);

        if (oneJsonDoc == null){
            Log.i(TAG, "onPostExecute:" + "empty");
        } else {
            String pom =  oneJsonDoc.getUpdatedAt()   +
                            oneJsonDoc.getCreatedAt() +
                            oneJsonDoc.getDocId()     +
                            oneJsonDoc.getJsonDoc();
            Log.i(TAG, "onPostExecute:" + pom);


                saveOneToDatabase(oneJsonDoc);
            }
        Toast.makeText(mActivity, "Item saved", Toast.LENGTH_SHORT).show();
        ReportsActivity.Log(mActivity,TAG, "Sync to cloud OK. Item saved");


    }

    public void saveOneToDatabase(Storage.JSONDocument oneJsonDoc) {
        Log.i(TAG, "saveToDatabase");
        SQLiteDatabase db = (new DatabaseHelper(mActivity)).getWritableDatabase();
        ContentValues cv=new ContentValues();

        cv.put(Constants.UPDATED_AT,    oneJsonDoc.getUpdatedAt());
        cv.put(Constants.CREATED_AT,    oneJsonDoc.getCreatedAt());
        cv.put(Constants.DOC_ID,        oneJsonDoc.getDocId());
        cv.put(Constants.JSON,          oneJsonDoc.getJsonDoc());
        if(oneJsonDoc.getLocation() == null){
            Log.i(TAG, "Location NULL");
            cv.put(Constants.LATITUDE,  (byte[]) null);
            cv.put(Constants.LONGITUDE, (byte[]) null);
        } else {
            cv.put(Constants.LATITUDE,  oneJsonDoc.getLocation().getLat().floatValue());
            cv.put(Constants.LONGITUDE, oneJsonDoc.getLocation().getLng().floatValue());
        }

        db.insert(Constants.TABLE_NAME, Constants.JSON, cv);
        Log.i(TAG, "inserted");
        db.close();
    }
}

/**
 * Trida pro smazani jednoho konkretnuho zaznamu z cloudu
 */

class AsyncDelRow extends AsyncTask<URL, Integer,String> {
    private static final String TAG = "AsyncDelRow";
    String mCloud_delete_doc;
    String mCloud_updated_doc;
    Context mContext;


    public AsyncDelRow(Context context, String cloud_delete_doc, String cloud_updated_at){
        mCloud_delete_doc = cloud_delete_doc;
        mCloud_updated_doc = cloud_updated_at;
        mContext = context;
    }

    @Override
    protected String doInBackground(URL... params) {
        StorageService storageService = App42API.buildStorageService();
        //odchyceni vyjimky pri negativni odpovedi
        /**
         * Pokud vyskoci vyjimka, znamena to, ze neexistuje hledane doc_id a je detekovan konflikt
         * Reseni v catch.
         */
        try {
            String checkConflicts = storageService.findDocumentById(Constants.CLOUD_DB_NAME, Constants.COLLECTION_NAME,
                    mCloud_delete_doc).getJsonDocList().get(0).getUpdatedAt();

            Log.i(TAG,checkConflicts + "*" );
            Log.i(TAG,mCloud_updated_doc + "*");
            /**
             * Kontrola konfliktu, nebyl zaznam zmenen?
             */
            if (checkConflicts.equals(mCloud_updated_doc)) {
                //nezmeneo, normalne smaz

                //Object response = storageService.deleteDocumentById(Constants.CLOUD_DB_NAME, Constants.COLLECTION_NAME,                        mCloud_delete_doc);
                storageService.deleteDocumentById(Constants.CLOUD_DB_NAME, Constants.COLLECTION_NAME, mCloud_delete_doc);
               // App42Response app42response = (App42Response) response;
                //System.out.println("response is " + app42response);
               // Log.i(TAG, app42response + "");
                deleteByDoc(mCloud_delete_doc);

            }   else {
                //zmeneno -> konflikt
                ReportsActivity.Log(mContext, TAG, "Conflict Detected! Item " + mCloud_delete_doc + " not deleted");
                //Toast.makeText(mContext, "Conflict detected! Check reports", Toast.LENGTH_LONG).show(); vybazuje vyjimku, implementace pres postExecute
                String toast = "Conflict detected! Check reports";
                return toast;
            }
        }catch (Exception ex) {
                System.out.println("Exception Message> " + ex.getMessage());
                ReportsActivity.Log(mContext, TAG, "Conflict Detected! Item it was deleted in Cloud, deleting from Database. Sync OK.");

        }




        return "noToast";
    }

    @Override
    protected void onPostExecute(String toast) {
        if(toast.equals("noToast")){
            //nic
        } else{
            Toast.makeText(mContext, toast, Toast.LENGTH_LONG).show();
         }
    }

    void deleteByDoc(String mCloudDoc){
        SQLiteDatabase db;
        db = (new DatabaseHelper(mContext).getWritableDatabase());
        db.delete("geometry", "doc_id=?", new String[]{mCloudDoc});
        ReportsActivity.Log(mContext,TAG, "Sync to cloud. Item deleted.");
        db.close();
    }
}
