package com.unibuy.smartdevice.database;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.unibuy.smartdevice.MyApp;
import com.unibuy.smartdevice.devices.SlotField;
import com.unibuy.smartdevice.exception.Logs;
import com.unibuy.smartdevice.exception.LogsNoSuchElementException;
import com.unibuy.smartdevice.structure.MemoStructure;
import com.unibuy.smartdevice.structure.ProductStructure;
import com.unibuy.smartdevice.structure.SlotStructure;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MemoDao {
    private Logs logs;
    private Map<String, List<MemoStructure>> memoMap;
    private final SQLiteDatabase database;

    public MemoDao(Context context) {
        logs = new Logs(this.getClass());
        DatabaseHelper dbHelper = new DatabaseHelper(context);
        database = dbHelper.getWritableDatabase();
        mapUpdate();
    }

    public void mapUpdate() {
        memoMap = getAll();
    }

    public void insertOnlyOne(MemoStructure data) {
        deleteField(data.getField());
        insertOne(data);
        logs.info("insertOnlyOne:" + data.toString());
    }

    // 插入單一 Product
    public void insertOne(MemoStructure data) {
        ContentValues values = new ContentValues();
        values.put(DatabaseHelper.memo.FIELD.getName(), data.getField());
        values.put(DatabaseHelper.memo.DATA.getName(), data.getData().toString());
        values.put(DatabaseHelper.memo.OTHER_DATA.getName(), data.getOtherData().toString());

        logs.info("insertOne:" + values.toString());

        long result = database.insert(DatabaseHelper.memo.TABLE.getName(), null, values);

        logs.info("insertOne result:" + result);
    }

    // 批量插入 Products
    public void insertAll(Map<String, List<MemoStructure>> memoMap) {
        if (memoMap.size() == 0) {
            return;
        }

        database.beginTransaction();
        try {
            for(String key: memoMap.keySet()) {
                List<MemoStructure> memoList = memoMap.get(key);
                for (MemoStructure data : memoList) {
                    insertOne(data);
                }
            }

            database.setTransactionSuccessful();
        } finally {
            database.endTransaction();
        }
    }

    public Map<String, List<MemoStructure>> getMemoData() {
        return memoMap;
    }

    public List<MemoStructure> getList(String field) {
        if (memoMap.containsKey(field)) {
            logs.debug("containsKey:" + field);
            return memoMap.get(field);
        } else {
            logs.debug("no fund:" + field);
            return new ArrayList<>();
        }
    }

    public int getCount(String field) {
        int size = getList(field).size();
        logs.debug("getCount size:" + size);
        return size;
    }

    public boolean existOnlyOne(String field) {
        int size = getCount(field);
        logs.debug("existOnlyOne size:" + size);
        return size == 1;
    }

    public MemoStructure getOnlyOne(String field) {
        return getList(field).get(0);
    }

    // 獲取所有 Products
    public Map<String, List<MemoStructure>> getAll() {
        Map<String, List<MemoStructure>> memoMap = new HashMap<>();

        Cursor cursor = database.query(
                DatabaseHelper.memo.TABLE.getName(),
                null, // 全部欄位
                null, // 無條件
                null,
                null,
                null,
                null);

        if (cursor != null) {
            while (cursor.moveToNext()) {
                int id = cursor.getInt(cursor.getColumnIndexOrThrow(DatabaseHelper.column.COLUMN_ID.getName()));
                String field = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseHelper.memo.FIELD.getName()));
                String data = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseHelper.memo.DATA.getName()));
                String otherData = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseHelper.memo.OTHER_DATA.getName()));

                JSONObject dataByJsonObject;
                try {
                    dataByJsonObject = new JSONObject(data);
                } catch (JSONException e) {
                    dataByJsonObject = new JSONObject();
                }

                JSONObject otherDataByJsonObject;
                try {
                    otherDataByJsonObject = new JSONObject(otherData);
                } catch (JSONException e) {
                    otherDataByJsonObject = new JSONObject();
                }

                if (!memoMap.containsKey(field)) {
                    memoMap.put(field, new ArrayList<>());
                }

                MemoStructure memoData = new MemoStructure(field, dataByJsonObject, otherDataByJsonObject);
                memoMap.get(field).add(memoData);
            }
            cursor.close();
        }

        logs.debug("getAll:" + memoMap.toString());

        return memoMap;
    }

    // 刪除所有 Products
    public void deleteAll() {
        database.delete(DatabaseHelper.memo.TABLE.getName(), null, null);
    }

    public void deleteField(String field) {
        logs.debug("delete:\""+DatabaseHelper.memo.FIELD.getName() + "\"="+field);
        database.delete(DatabaseHelper.memo.TABLE.getName(), "\""+DatabaseHelper.memo.FIELD.getName() + "\"=?", new String[]{field});
    }

    // 關閉資料庫
    public void close() {
        database.close();
    }
}

