package com.hyperling.carbupbeta;

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

import java.util.ArrayList;

/**
 * Created by usb on 12/24/14.
 */

// Database And ListItem Helper
public class DALIH extends SQLiteOpenHelper{
    public final boolean DEBUG = false;

    // SQL objects
    private static final String DB_NAME = "CARBUP.db";

    private static final String list_table = "list"; // Saved List Table name (EX: 01, Schnuck's beans)
    private static final String item_table = "item"; // Saved Item Table name (EG: 01, red beans, 70 carbs, 200 calories, etc)
    private static final String setting_table = "settings";

    private static final String list_id_col     = "list_id";
    private static final String list_name_col   = "list_name";

    private static final String item_id_col         = "item_id";
    private static final String item_name_col       = "item_name";
    private static final String item_cost_col       = "cost";
    private static final String item_servings_col   = "servings";
    private static final String item_calories_col   = "calories";
    private static final String item_carbs_col      = "carbs";
    private static final String item_fiber_col      = "fiber";
    private static final String item_list_id_col    = list_id_col;

    private static final String setting_last_list_col   = "last_list";
    private static final String setting_last_item_col   = "last_item";
    private static final String setting_ads_enabled_col = "ads_enabled";
    private static final String setting_quick_load_col  = "quick_load";
    private static final String setting_open_tab_col  = "open_tab";
    private static final int settings_total = 5;
    private static final int setting_last_list_index   = 0;
    private static final int setting_last_item_index   = 1;
    private static final int setting_ads_enabled_index = 2;
    private static final int setting_quick_load_index  = 3;
    private static final int setting_open_tab_index    = 4;
    private static final int setting_last_list_default  = -1;
    private static final int setting_last_item_default  = -1;
    private static final int setting_ads_enabled_default = 1;
    private static final int setting_quick_load_default  = 0;
    private static final int setting_open_tab_default    = 1;

    private static final String CREATESLTABLE = "CREATE TABLE " + list_table + "(" +
                                                                  list_id_col + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                                                                  list_name_col + " TEXT NOT NULL" +
                                                "); ";

    private static final String CREATESITABLE = "" +
            "CREATE TABLE " + item_table + "( " +
            item_id_col + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            item_name_col + " TEXT NOT NULL, " +
            item_cost_col + " REAL NOT NULL, " +
            item_servings_col + " REAL NOT NULL, " +
            item_calories_col + " REAL NOT NULL, " +
            item_carbs_col + " REAL NOT NULL, " +
            item_fiber_col + " REAL DEFAULT 0, " +
            item_list_id_col + " INTEGER NOT NULL, " +
            "FOREIGN KEY (" + item_list_id_col + ") REFERENCES " + list_table + "(" + list_id_col + ") ON DELETE CASCADE" +
            "); ";

    private static final String CREATESETTINGTABLE = "" +
            "CREATE TABLE " + setting_table + "( " +
            "  " + setting_last_list_col + " INTEGER NOT NULL, " +
            "  " + setting_last_item_col + " INTEGER NOT NULL, " +
            "  " + setting_ads_enabled_col + " INTEGER NOT NULL, " +
            "  " + setting_quick_load_col + " INTEGER NOT NULL, " +
            "  " + setting_open_tab_col + " INTEGER NOT NULL " +
            "); ";


    SQLiteDatabase db;

    public DALIH(Context context){
        //4, add fiber column to list_item
        super(context, DB_NAME, null, 4);
        return;
    }

    // Open the database
    public void open() throws SQLException{
        if (DEBUG) System.out.println("Opening DB");

        db = getWritableDatabase();
        return;
    }

    // Close the database
    public void close(){
        if (DEBUG) System.out.println("Closing DB");

        super.close();
        return;
    }

    // Insert a ListItem into the DB
    public void insertItem(ListItemInfo listItem){
        if (DEBUG) System.out.println("Inserting item: " + listItem.getID() + " " + listItem.getName());

        String query = "" +
                "INSERT INTO "+item_table+"("+item_name_col+", "+item_cost_col+", "+item_calories_col+", " +
                "                           "+item_carbs_col+", "+item_servings_col+", "+item_list_id_col+", " +
                "                           "+item_fiber_col+") " +
                "VALUES(\""+listItem.getName()+"\", "+listItem.getCost()+", "+listItem.getCalories()+", " +
                "       "+listItem.getCarbs()+", "+listItem.getServings()+", "+listItem.getListID() + ", " +
                "       "+listItem.getFiber()+"); ";

        doQuery(query);
        return;
    }

    public void updateItem(ListItemInfo listItem){
        if (DEBUG) System.out.println("Updating item: " + listItem.getID() + " " + listItem.getName());

        String query = "" +
                "UPDATE "+item_table+" " +
                "   SET "+item_name_col+" = \""+listItem.getName()+"\", " +
                "       "+item_cost_col+" = "+listItem.getCost()+", " +
                "       "+item_calories_col+" = "+listItem.getCalories()+", " +
                "       "+item_carbs_col+" = "+listItem.getCarbs()+", " +
                "       "+item_servings_col+" = "+listItem.getServings()+", " +
                "       "+item_fiber_col+" = "+listItem.getFiber()+", " +
                "       "+item_list_id_col+" = "+listItem.getListID()+" " +
                " WHERE "+item_id_col+" = "+listItem.getID() + "; ";

        doQuery(query);
        return;
    }

    // Remove a ListItem from the DB
    public void deleteItem(ListItemInfo listItem){
        if (DEBUG) System.out.println("Deleting item: " + listItem.getID() + " " + listItem.getName());

        String query = "" +
                "DELETE FROM "+item_table+" " +
                " WHERE "+item_id_col+" = "+listItem.getID() + "; ";

        doQuery(query);
        return;
    }

    // This method will give tab2 current List's items to sort through
    public ArrayList<ListItemInfo> getItems(int list_id){
        ArrayList<ListItemInfo> items = new ArrayList<ListItemInfo>();

        String query = "" +
                "SELECT "+item_id_col+", " +
                "       "+item_name_col+", " +
                "       "+item_cost_col+", " +
                "       "+item_servings_col+", " +
                "       "+item_calories_col+", " +
                "       "+item_carbs_col+", " +
                "       "+item_fiber_col+", " +
                "       "+item_list_id_col+" " +
                "  FROM "+item_table+" " +
                " WHERE "+item_list_id_col+" = "+list_id+"; ";

        if (DEBUG) System.out.println("Getting all items\n" + query);

        Cursor c = db.rawQuery(query, null);

        if (DEBUG) System.out.println("Cursor size: " + c.getCount());

        c.moveToFirst();
        while(!c.isAfterLast()){
            ListItemInfo temp = new ListItemInfo();

            temp.setID(c.getInt(0));
            temp.setName(c.getString(1));
            temp.setCost(c.getDouble(2));
            temp.setServings(c.getDouble(3));
            temp.setCalories(c.getDouble(4));
            temp.setCarbs(c.getDouble(5));
            temp.setFiber(c.getDouble(6));
            temp.setListID(c.getInt(7));

            items.add(temp);
            c.moveToNext();
        }
        c.close();

        return items;
    }

    public void insertList(ListInfo list){
        if (DEBUG) System.out.println("Inserting list: " + list.getID() + " " + list.getName());

        String query = "" +
                "INSERT INTO "+list_table+"("+list_name_col+") " +
                "VALUES(\""+list.getName()+"\"); ";

        doQuery(query);
        return;
    }

    public void updateList(ListInfo list){
        if (DEBUG) System.out.println("Updating list: " + list.getID() + " " + list.getName());

        String query = "" +
                "UPDATE "+list_table+" " +
                "   SET "+list_name_col+" = \""+list.getName()+"\" " +
                " WHERE "+list_id_col+" = "+list.getID()+"; ";

        doQuery(query);
        return;
    }

    public void deleteList(ListInfo list){
        if (DEBUG) System.out.println("Deleting list: " + list.getID() + " " + list.getName());

        String query = "" +
                "DELETE FROM "+list_table+" " +
                " WHERE "+list_id_col+" = "+list.getID()+"; ";

        doQuery(query);

        return;
    }

    public ArrayList<ListInfo> getLists(){
        // Return ALL lists in an ArrayList
        ArrayList<ListInfo> lists = new ArrayList<ListInfo>();

        String query = "" +
                "SELECT "+list_id_col+", " +
                "       "+list_name_col+" " +
                "  FROM "+list_table+"; ";

        if (DEBUG) System.out.println("Getting all lists\n" + query);

        Cursor c = db.rawQuery(query, null);

        if (DEBUG) System.out.println("Cursor size: " + c.getCount());

        c.moveToFirst();
        while(!c.isAfterLast()){
            ListInfo temp = new ListInfo();

                temp.setID(c.getInt(0));
                temp.setName(c.getString(1));

                lists.add(temp);

            c.moveToNext();
        }
        c.close();

        return lists;
    }

    private void setSettings(int[] settings){
        if (DEBUG) System.out.println("Setting settings");

        int last_list = settings[getLastListIndex()];
        int last_item = settings[getLastItemIndex()];
        int ads_enabled = settings[getAdsEnabledIndex()];
        int quick_load = settings[getQuickLoadIndex()];
        int open_tab = settings[getOpenTabIndex()];
        String query = "" +
                "UPDATE "+setting_table+"" +
                "   SET "+setting_last_list_col+" = "+last_list+", " +
                "       "+setting_last_item_col+" = "+last_item+", " +
                "       "+setting_ads_enabled_col+" = "+ads_enabled+", " +
                "       "+setting_quick_load_col+" = "+quick_load+", " +
                "       "+setting_open_tab_col+" = "+open_tab+"; ";

        doQuery(query);
        return;
    }

    private int[] getSettings(){
        if (DEBUG) System.out.println("Getting settings");

        String query = "" +
                "SELECT "+setting_last_list_col+", " +
                "       "+setting_last_item_col+", " +
                "       "+setting_ads_enabled_col+", " +
                "       "+setting_quick_load_col+", " +
                "       "+setting_open_tab_col+" " +
                "  FROM "+setting_table+"; ";

        int[] settings = null;
        Cursor c = db.rawQuery(query, null);

        if (DEBUG) System.out.println("Cursor size: " + c.getCount());

        if (c.getCount() == 0){
            setDefaults();

            settings = new int[settings_total];
            settings[getLastListIndex()] = setting_last_list_default;
            settings[getLastItemIndex()] = setting_last_item_default;
            settings[getAdsEnabledIndex()] = setting_ads_enabled_default;
            settings[getQuickLoadIndex()] = setting_quick_load_default;
            settings[getOpenTabIndex()] = setting_open_tab_default;
        }
        else {
            if (DEBUG) System.out.println("Reading settings\n" + query);

            c.moveToFirst();
            while (!c.isAfterLast()) {
                settings = new int[settings_total];
                settings[getLastListIndex()] = c.getInt(0);
                settings[getLastItemIndex()] = c.getInt(1);
                settings[getAdsEnabledIndex()] = c.getInt(2);
                settings[getQuickLoadIndex()] = c.getInt(3);
                settings[getOpenTabIndex()] = c.getInt(4);
                c.moveToNext();
            }
        }
        c.close();

        return settings;
    }

    private void setDefaults(){
        if (DEBUG) System.out.println("Setting default settings");

        String query = "" +
                "INSERT INTO " + setting_table + "("+setting_last_list_col+", "+setting_last_item_col+", " +
                "                                  "+setting_ads_enabled_col+", "+setting_quick_load_col+", " +
                "                                  "+setting_open_tab_col+") " +
                "VALUES("+setting_last_list_default+", "+setting_last_item_default+", " +
                "       "+setting_ads_enabled_default+", "+setting_quick_load_default+", " +
                "       "+setting_open_tab_default+"); ";

        doQuery(query);
        return;
    }

    private int getLastListIndex(){
        if (DEBUG) System.out.println("Getting last list index");

        return setting_last_list_index;
    }

    private int getLastItemIndex(){
        if (DEBUG) System.out.println("Getting last item index");

        return setting_last_item_index;
    }

    private int getAdsEnabledIndex(){
        if (DEBUG) System.out.println("Getting ads enabled index");

        return setting_ads_enabled_index;
    }

    private int getQuickLoadIndex(){
        if (DEBUG) System.out.println("Getting quick load index");

        return setting_quick_load_index;
    }

    private int getOpenTabIndex(){
        if (DEBUG) System.out.println("Getting open tab index");

        return setting_open_tab_index;
    }

    public int getLastList(){
        if (DEBUG) System.out.println("Getting last list");

        int[] settings = getSettings();

        return settings[getLastListIndex()];
    }

    public void setLastList(int lastList){
        if (DEBUG) System.out.println("Setting last list to " + lastList);

        int[] settings = getSettings();

        settings[getLastListIndex()] = lastList;

        setSettings(settings);
        return;
    }

    public void setLastList(){
        if (DEBUG) System.out.println("Setting last list to default, " + setting_last_list_default);

        int[] settings = getSettings();

        settings[getLastListIndex()] = setting_last_list_default;

        setSettings(settings);
        return;
    }

    public int getLastItem(){
        if (DEBUG) System.out.println("Getting last item");

        int[] settings = getSettings();

        return settings[getLastItemIndex()];
    }

    public void setLastItem(int lastItem){
        if (DEBUG) System.out.println("Setting last item to " + lastItem);

        int[] settings = getSettings();

        settings[getLastItemIndex()] = lastItem;

        setSettings(settings);
        return;
    }

    public void setLastItem(){
        if (DEBUG) System.out.println("Setting last item to default, " + setting_last_item_default);

        int[] settings = getSettings();

        settings[getLastItemIndex()] = setting_last_item_default;

        setSettings(settings);
        return;
    }

    public boolean getAdsEnabled(){
        if (DEBUG) System.out.println("Getting ads enabled");

        int[] settings = getSettings();

        return (settings[getAdsEnabledIndex()] > 0);
    }

    public void setAdsEnabled(boolean adsEnabled){
        if (DEBUG) System.out.println("Setting ads enabled to " + adsEnabled);

        int[] settings = getSettings();

        int setting;
        if (adsEnabled){
            setting = 1;
        }
        else{
            setting = 0;
        }

        settings[getAdsEnabledIndex()] = setting;

        setSettings(settings);
        return;
    }

    public boolean getQuickLoad(){
        if (DEBUG) System.out.println("Getting quick load");

        int[] settings = getSettings();

        return (settings[getQuickLoadIndex()] > 0);
    }

    public void setQuickLoad(boolean quickLoad){
        if (DEBUG) System.out.println("Setting quick load to " + quickLoad);

        int[] settings = getSettings();

        int setting;
        if (quickLoad){
            setting = 1;
        }
        else{
            setting = 0;
        }

        settings[getQuickLoadIndex()] = setting;

        setSettings(settings);
        return;
    }

    public int getOpenTab(){
        if (DEBUG) System.out.println("Getting quick load");

        int[] settings = getSettings();

        return settings[getOpenTabIndex()];
    }

    public void setOpenTab(int tab){
        if (DEBUG) System.out.println("Setting open tab to " + tab);

        int[] settings = getSettings();

        settings[getOpenTabIndex()] = tab;

        setSettings(settings);
        return;
    }

    private void doQuery(String query){
        if (DEBUG) System.out.println("Executing SQL:\n" + query);

        db.execSQL(query);
        return;
    }

    public String filterString(String input){
        if (DEBUG) System.out.println("Filtering string: " + input);
        String output = input.trim().replace("\"","").replace("\n", "").replace("\b", "").replace("\t", "");
        while(output.contains("  ")){
            if (DEBUG) System.out.println("In the space killer loop: " + output);
            output = output.replace("  ", " ");
        }
        return output;
    }

    private void printDML(){
        System.out.println();
        System.out.println(CREATESLTABLE);
        System.out.println();
        System.out.println(CREATESITABLE);
        System.out.println();
        System.out.println(CREATESETTINGTABLE);
        System.out.println();
        return;
    }

    @Override
    public void onCreate(SQLiteDatabase database) {
        if (DEBUG){
            System.out.println("Creating the DB");
            printDML();
        }

        database.execSQL(CREATESLTABLE);
        database.execSQL(CREATESITABLE);
        database.execSQL(CREATESETTINGTABLE);
        return;
    }

    @Override
    public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
        if (DEBUG) System.out.println("Upgrading the DB");

        switch(oldVersion){
            case 2:
                if (DEBUG) System.out.println("UPGRADING TO DBv3");
                String DBv3 = "" +
                        " ALTER TABLE "+setting_table+" " +
                        "   ADD "+setting_open_tab_col+" INTEGER; " +
                        "" +
                        "UPDATE TABLE "+setting_table+" " +
                        "   SET "+setting_open_tab_col+" = "+setting_open_tab_default+"; " +
                        "" +
                        " ALTER TABLE "+setting_table+" " +
                        " ALTER COLUMN "+setting_open_tab_col+" INTEGER NOT NULL; ";
                database.execSQL(DBv3);
            case 3:
                if (DEBUG) System.out.println("UPGRADING TO DBv4");
                String DBv4 = "" +
                        " ALTER TABLE "+item_table+" " +
                        "   ADD "+item_fiber_col+" REAL DEFAULT 0; ";
                database.execSQL(DBv4);

        }
        return;
    }
}
