package com.hikapro.backpack.model.dao;

import android.content.ContentValues;
import android.database.Cursor;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.List;
import java.util.Locale;

import com.hikapro.backpack.model.entities.Category;
import com.hikapro.backpack.model.entities.Item;
import com.hikapro.backpack.model.entities.Set;
import com.hikapro.backpack.model.entities.SharingPicture;
import com.hikapro.backpack.model.entities.Timestamp;
import com.hikapro.backpack.model.entities.UpdateLog;

/**
 * Created by tariel on 20/04/16.
 */
public class Db {

    public Db() {
    }

    public abstract static class CategoriesTable {

        public static final String TABLE_NAME = "categories";

        public static final String COLUMN_ID = "_id";
        public static final String COLUMN_NAME = "name";

        public static final String CREATE =
                "CREATE TABLE " + TABLE_NAME + " (" +
                        COLUMN_ID + " INTEGER PRIMARY KEY, " +
                        COLUMN_NAME + " TEXT NOT NULL" +
                        " ); ";

        public static ContentValues toContentValues(Category category) {
            ContentValues values = new ContentValues();
            values.put(COLUMN_ID, category.getId());
            values.put(COLUMN_NAME, category.getName());
            return values;
        }

        public static Category parseCursor(Cursor cursor) {
            Category category = new Category();
            category.setId(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_ID)));
            category.setName(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME)));
            return category;
        }

    }

    public abstract static class SharingPicsTable {

        public static final String TABLE_NAME = "sharing_pics";

        public static final String COLUMN_ID = "_id";
        public static final String COLUMN_PHOTO_URL = "photo_url";
        public static final String COLUMN_PHOTO_THUMB_URL = "photo_thumb_url";
        public static final String COLUMN_PHOTO_LOCAL = "photo_local";
        public static final String COLUMN_PHOTO_THUMB_LOCAL = "photo_thumb_local";

        public static final String CREATE =
                "CREATE TABLE " + TABLE_NAME + " (" +
                        COLUMN_ID + " INTEGER PRIMARY KEY, " +
                        COLUMN_PHOTO_URL + " TEXT, " +
                        COLUMN_PHOTO_THUMB_URL + " TEXT, " +
                        COLUMN_PHOTO_LOCAL + " TEXT, " +
                        COLUMN_PHOTO_THUMB_LOCAL + " TEXT" +
                        " ); ";

        public static ContentValues toContentValues(SharingPicture sharingPicture) {
            ContentValues values = new ContentValues();
            values.put(COLUMN_ID, sharingPicture.getId());
            if (sharingPicture.getPhotoUrl() != null)
                values.put(COLUMN_PHOTO_URL, sharingPicture.getPhotoUrl());
            if (sharingPicture.getPhotoThumbUrl() != null)
                values.put(COLUMN_PHOTO_THUMB_URL, sharingPicture.getPhotoThumbUrl());
            if (sharingPicture.getPhotoLocal() != null)
                values.put(COLUMN_PHOTO_LOCAL, sharingPicture.getPhotoLocal());
            if (sharingPicture.getPhotoThumbLocal() != null)
                values.put(COLUMN_PHOTO_THUMB_LOCAL, sharingPicture.getPhotoThumbLocal());

            return values;
        }

        public static SharingPicture parseCursor(Cursor cursor) {
            SharingPicture sharingPicture = new SharingPicture();
            sharingPicture.setId(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_ID)));
            sharingPicture.setPhotoUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_URL)));
            sharingPicture.setPhotoThumbUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL)));
            sharingPicture.setPhotoLocal(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_LOCAL)));
            sharingPicture.setPhotoThumbLocal(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_LOCAL)));
            return sharingPicture;
        }
    }

    public abstract static class ItemsTable {
        public static final String TABLE_NAME = "items";

        public static final String COLUMN_ID = "_id";
        public static final String COLUMN_NAME = "name";
        public static final String COLUMN_CATEGORY = "category";
        public static final String COLUMN_DESCRIPTION = "description";
        public static final String COLUMN_BUY_URLS = "buy_urls";
        public static final String COLUMN_PHOTO_URL = "photo_url";
        public static final String COLUMN_PHOTO_THUMB_URL = "photo_thumb_url";
        public static final String COLUMN_PHOTO_LOCAL = "photo_local";
        public static final String COLUMN_PHOTO_THUMB_LOCAL = "photo_thumb_local";
        public static final String COLUMN_USER_DEFINED = "user_defined";


        public static final String CREATE =
                "CREATE TABLE " + TABLE_NAME + " (" +
                        COLUMN_ID + " INTEGER PRIMARY KEY, " +
                        COLUMN_NAME + " TEXT NOT NULL, " +
                        COLUMN_CATEGORY + " INTEGER NOT NULL, " +
                        COLUMN_DESCRIPTION + " TEXT, " +
                        COLUMN_BUY_URLS + " TEXT, " +
                        COLUMN_PHOTO_URL + " TEXT, " +
                        COLUMN_PHOTO_THUMB_URL + " TEXT, " +
                        COLUMN_PHOTO_LOCAL + " TEXT, " +
                        COLUMN_USER_DEFINED + " NUMERIC, " +
                        COLUMN_PHOTO_THUMB_LOCAL + " TEXT" +
                        " ); ";

        public static ContentValues toContentValues(Item item) {
            ContentValues values = new ContentValues();
            values.put(COLUMN_ID, item.getId());
            values.put(COLUMN_NAME, item.getName());
            values.put(COLUMN_CATEGORY, item.getCategory());
            if (item.getDescription() != null)
                values.put(COLUMN_DESCRIPTION, item.getDescription());
            if (item.getBuyUrls() != null && !item.getBuyUrls().isEmpty()) {
                Gson gson = new Gson();
                Type type = new TypeToken<List<String>>() {}.getType();
                String json = gson.toJson(item.getBuyUrls(), type);
                values.put(COLUMN_BUY_URLS, json);
            }
            if (item.getPhotoUrl() != null)
                values.put(COLUMN_PHOTO_URL, item.getPhotoUrl());
            if (item.getPhotoThumbUrl() != null)
                values.put(COLUMN_PHOTO_THUMB_URL, item.getPhotoThumbUrl());
            if (item.getPhotoLocal() != null)
                values.put(COLUMN_PHOTO_LOCAL, item.getPhotoLocal());

            values.put(COLUMN_USER_DEFINED, item.isUserDefined());

            return values;
        }

        public static Item parseCursor(Cursor cursor) {
            Item item = new Item();
            item.setId(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_ID)));
            item.setName(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME)));

            item.setCategory(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_CATEGORY)));

            item.setDescription(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_DESCRIPTION)));
            String urls = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_BUY_URLS));
            if (urls != null && !urls.isEmpty()) {
                Gson gson = new Gson();
                Type type = new TypeToken<List<String>>() {}.getType();
                List<String> fromJson = gson.fromJson(urls, type);
                item.setBuyUrls(fromJson);
            }
            item.setPhotoUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_URL)));
            item.setPhotoThumbUrl(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL)));
            item.setPhotoLocal(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_LOCAL)));
            short buf = cursor.getShort(cursor.getColumnIndexOrThrow(COLUMN_USER_DEFINED));
            item.setUserDefined(buf != 0);
            int check = cursor.getColumnIndex(SetItemsTable.COLUMN_PENDING_REMOVAL);
            if (check != -1) {
                buf = cursor.getShort(check);
                item.setPendingRemoval(buf != 0);
            }
            check = cursor.getColumnIndex(SetItemsTable.COLUMN_PACKED);
            if (check != -1) {
                buf = cursor.getShort(check);
                item.setPacked(buf != 0);
            }
            return item;
        }

    }

    public abstract static class SetsTable {
        public static final String TABLE_NAME = "sets";

        public static final String COLUMN_ID = "_id";
        public static final String COLUMN_NAME = "name";
        public static final String COLUMN_ITEMS = "items";
        public static final String COLUMN_PHOTO_URL = "photo_url";
        public static final String COLUMN_PHOTO_THUMB_URL = "photo_thumb_url";
        public static final String COLUMN_PHOTO_LOCAL = "photo_local";
        public static final String COLUMN_PHOTO_THUMB_LOCAL = "photo_thumb_local";
        public static final String COLUMN_PHOTO_THUMBNAIL_URL = "photo_thumbnail_url";
        public static final String COLUMN_PHOTO_THUMBNAIL_LOCAL = "photo_thumbnail_local";
        public static final String COLUMN_LINE_NUMBER = "line_num";
        public static final String COLUMN_PACKED_QTY = "packed_qty";
        public static final String COLUMN_ACTIVE_QTY = "active_qty";


        public static final String CREATE =
                "CREATE TABLE " + TABLE_NAME + " (" +
                        COLUMN_ID + " INTEGER PRIMARY KEY, " +
                        COLUMN_NAME + " TEXT NOT NULL, " +
                        COLUMN_ITEMS + " TEXT, " +
                        COLUMN_PHOTO_URL + " TEXT, " +
                        COLUMN_PHOTO_THUMB_URL + " TEXT, " +
                        COLUMN_PHOTO_LOCAL + " TEXT, " +
                        COLUMN_PHOTO_THUMB_LOCAL + " TEXT, " +
                        COLUMN_PHOTO_THUMBNAIL_URL + " TEXT, " +
                        COLUMN_LINE_NUMBER + " INTEGER, " +
                        COLUMN_PACKED_QTY + " INTEGER, " +
                        COLUMN_ACTIVE_QTY + " INTEGER, " +
                        COLUMN_PHOTO_THUMBNAIL_LOCAL + " TEXT" +
                        " ); ";

        public static ContentValues toContentValues(Set set, int lineNumber) {
            ContentValues values = new ContentValues();
            values.put(COLUMN_ID, set.getId());
            values.put(COLUMN_NAME, set.getName());

            List<Integer> items = set.getItems();
            if (items != null && !items.isEmpty()) {
                Gson gson = new Gson();
                Type type = new TypeToken<List<Integer>>() {}.getType();
                String json = gson.toJson(items, type);
                values.put(COLUMN_ITEMS, json);
            }
            values.put(COLUMN_PHOTO_URL, set.getPhoto());
            values.put(COLUMN_PHOTO_THUMB_URL, set.getPhotoThumb());
            values.put(COLUMN_PHOTO_THUMBNAIL_URL, set.getPhotoThumbnail());
            values.put(COLUMN_LINE_NUMBER, lineNumber);
            values.put(COLUMN_ACTIVE_QTY, items.size());

            return values;
        }

        public static Set parseCursor(Cursor cursor) {
            Set set = new Set();
            set.setId(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_ID)));
            set.setName(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME)));

            String items = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_ITEMS));
            if (items != null && !items.isEmpty()) {
                Gson gson = new Gson();
                Type type = new TypeToken<List<Integer>>() {}.getType();
                List<Integer> fromJson = gson.fromJson(items, type);
                set.setItems(fromJson);
            }
            set.setPhoto(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_URL)));
            set.setPhotoThumb(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMB_URL)));
            set.setPhotoThumbnail(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_PHOTO_THUMBNAIL_URL)));
            set.setLineNumber(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_LINE_NUMBER)));
            set.setPackedQty(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_PACKED_QTY)));
            set.setActiveQty(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_ACTIVE_QTY)));

            return set;
        }
    }

    public abstract static class LogTable {

        public static final String TABLE_NAME = "update_log";

        public static final String COLUMN_ID = "_id";
        public static final String COLUMN_MODIFIED_DATETIME = "modified_datetime";
        public static final String COLUMN_TIMESTAMP = "timestamp";
        public static final String COLUMN_LOCALE = "locale";

        public static final String CREATE =
                "CREATE TABLE " + TABLE_NAME + " (" +
                        COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                        COLUMN_TIMESTAMP + " INTEGER NOT NULL, " +
                        COLUMN_LOCALE + " TEXT, " +
                        COLUMN_MODIFIED_DATETIME + " INTEGER NOT NULL DEFAULT current_timestamp" +
                        " ); ";

        public static ContentValues toContentValues(Timestamp timestamp) {
            ContentValues values = new ContentValues();

            values.put(COLUMN_TIMESTAMP, timestamp.timestamp);
            values.put(COLUMN_LOCALE, Locale.getDefault().getLanguage());

            return values;
        }
        public static UpdateLog parseCursor(Cursor cursor) {
            UpdateLog log = new UpdateLog();
            log.setId(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_ID)));
            log.setTimestamp(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_TIMESTAMP)));
            log.setModifiedDatetime(cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_MODIFIED_DATETIME)));
            log.setLocale(cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_LOCALE)));
            return log;
        }
    }

    public abstract static class SetItemsTable {

        public static final String TABLE_NAME = "set_items";

        public static final String COLUMN_ID = "_id";
        public static final String COLUMN_SET = "setId";
        public static final String COLUMN_ITEM = "itemId";
        public static final String COLUMN_DELETED = "deleted";
        public static final String COLUMN_PENDING_REMOVAL = "pending_removal";
        public static final String COLUMN_PACKED = "packed";
        public static final String COLUMN_USER_DEFINED = "user_defined";

        public static final String CREATE =
                "CREATE TABLE " + TABLE_NAME + " (" +
                        COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                        COLUMN_SET + " INTEGER NOT NULL, " +
                        COLUMN_DELETED + " NUMERIC, " +
                        COLUMN_PENDING_REMOVAL + " NUMERIC, " +
                        COLUMN_PACKED + " NUMERIC, " +
                        COLUMN_USER_DEFINED + " NUMERIC, " +
                        COLUMN_ITEM + " INTEGER NOT NULL" +
                        " ); ";

        public static ContentValues toContentValues(int setId, int itemId) {
            ContentValues values = new ContentValues();
            values.put(COLUMN_SET, setId);
            values.put(COLUMN_ITEM, itemId);
            values.put(COLUMN_DELETED, 0);
            values.put(COLUMN_PENDING_REMOVAL, 0);
            values.put(COLUMN_PACKED, 0);
            values.put(COLUMN_USER_DEFINED, 0);
            return values;
        }

        public static ContentValues toContentValues(int setId, int itemId, boolean userDefined) {
            ContentValues values = new ContentValues();
            values.put(COLUMN_SET, setId);
            values.put(COLUMN_ITEM, itemId);
            values.put(COLUMN_DELETED, 0);
            values.put(COLUMN_PENDING_REMOVAL, 0);
            values.put(COLUMN_PACKED, 0);
            values.put(COLUMN_USER_DEFINED, userDefined);
            return values;
        }
    }
}
