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

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import com.google.gson.reflect.TypeToken;

import java.util.Iterator;
import java.util.List;

import kz.arta.synergy.workflow.mobile.android.common.requests.RestClient;
import kz.arta.synergy.workflow.mobile.android.files.models.Node;

/**
 * Created by neox on 29.08.16.
 */
public class FilesListTable extends SQLiteOpenHelper {

    private SQLiteDatabase db = getWritableDatabase();
    private static final String TABLE_NAME = "FilesListTable";
    private static final String TABLE = "create table " + TABLE_NAME + " ("
            + "key text,"
            + "value text"
            + ");";

    public FilesListTable(Context context) {
        super(context, TABLE_NAME, null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i2) {

    }

    public boolean removeAll() {
        try {
            db.delete(TABLE_NAME, null, null);
            return true;
        } catch (Exception exc) {
            return false;
        }
    }

    public boolean add(String key, String value) {
        try {
            ContentValues cv = new ContentValues();
            cv.put("key", key);
            cv.put("value", value);
            db.insert(TABLE_NAME, null, cv);
            return true;
        } catch (Exception exc) {
            return false;
        }
    }

    public String get(String key) {
        String result = null;
        Cursor c = null;
        try {
            c = db.rawQuery("select * from " + TABLE_NAME + " where key = ?", new String[]{key});
            if (c.moveToFirst()) {
                result = c.getString(c.getColumnIndex("value"));
            }
            return result;
        } catch (Exception exc) {
            return null;
        } finally {
            if (c != null) {
                c.close();
            }
        }
    }

    public void removeNode(String key, String nodeID) {
        String nodesJson = null;
        Cursor c = null;
        try {
            c = db.rawQuery("select * from " + TABLE_NAME + " where key = ?", new String[]{key});
            if (c.moveToFirst()) {
                nodesJson = c.getString(c.getColumnIndex("value"));
            }
            c.close();
            List<Node> filesList = RestClient.getGson().fromJson(nodesJson, new TypeToken<List<Node>>() {
            }.getType());
            Iterator<Node> iterator = filesList.iterator();
            while (iterator.hasNext()) {
                Node node = iterator.next();
                if (node.getIdentifier().equals(nodeID)) {
                    iterator.remove();
                }
            }
            String result = RestClient.getGson().toJson(filesList);
            ContentValues cv = new ContentValues();
            cv.put("value", result);
            db.update(TABLE_NAME, cv, "key = ?", new String[]{key});
        } catch (Exception exc) {
            // handling error ...
        } finally {
            if (c != null) {
                c.close();
            }
        }
    }

    public void renameNode(String key, String nodeID, String newName) {
        String nodesJson = null;
        Cursor c = null;
        try {
            c = db.rawQuery("select * from " + TABLE_NAME + " where key = ?", new String[]{key});
            if (c.moveToFirst()) {
                nodesJson = c.getString(c.getColumnIndex("value"));
            }
            c.close();
            List<Node> filesList = RestClient.getGson().fromJson(nodesJson, new TypeToken<List<Node>>(){}.getType());
            for (Node node : filesList) {
                if (node.getIdentifier().equals(nodeID)) {
                    node.setName(newName);
                    break;
                }
            }
            String result = RestClient.getGson().toJson(filesList);
            ContentValues cv = new ContentValues();
            cv.put("value", result);
            db.update(TABLE_NAME, cv, "key = ?", new String[]{key});
        } catch (Exception exc) {
            // handling error ...
        } finally {
            if (c != null) {
                c.close();
            }
        }
    }

    public void moveNode(String key, String oldNode, String newNode) {
        String nodesJson = null;
        Cursor c = null;
        try {
            c = db.rawQuery("select * from " + TABLE_NAME + " where key = ?", new String[]{key});
            if (c.moveToFirst()) {
                nodesJson = c.getString(c.getColumnIndex("value"));
            }
            c.close();
            List<Node> filesList = RestClient.getGson().fromJson(nodesJson, new TypeToken<List<Node>>(){}.getType());
            Iterator<Node> iterator = filesList.iterator();
            Node movedNode = null;
            while (iterator.hasNext()) {
                Node node = iterator.next();
                if (node.getIdentifier().equals(oldNode)) {
                    movedNode = node;
                    iterator.remove();
                }
            }
            String result = RestClient.getGson().toJson(filesList);
            ContentValues cv = new ContentValues();
            cv.put("value", result);
            db.update(TABLE_NAME, cv, "key = ?", new String[]{key});
            c = db.rawQuery("select * from " + TABLE_NAME + " where key = ?", new String[]{newNode});
            if (c.moveToFirst()) {
                nodesJson = c.getString(c.getColumnIndex("value"));
            }
            c.close();
            filesList = RestClient.getGson().fromJson(nodesJson, new TypeToken<List<Node>>() {
            }.getType());
            filesList.add(movedNode);
            result = RestClient.getGson().toJson(filesList);
            cv = new ContentValues();
            cv.put("value", result);
            db.update(TABLE_NAME, cv, "key = ?", new String[]{newNode});
        } catch (Exception exc) {
            // handling error ...
        } finally {
            if (c != null) {
                c.close();
            }
        }
    }
}
