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.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 SlotsDao {
    private Logs logs;
    private final SQLiteDatabase database;

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

    // 插入單一 Product
    public void insertOne(SlotStructure data) {
        ContentValues values = new ContentValues();
        values.put(DatabaseHelper.slot.FIELD.getName(), data.getField());
        values.put(DatabaseHelper.slot.SLOT.getName(), data.getSlot());
        values.put(DatabaseHelper.slot.PRODUCT_ID.getName(), data.getProduct().getProductID());
        values.put(DatabaseHelper.slot.COUNT.getName(), data.getCount());
        values.put(DatabaseHelper.slot.LOCK.getName(), data.isLock());
        values.put(DatabaseHelper.slot.OTHER_DATA.getName(), data.getOtherData().toString());

        database.insert(DatabaseHelper.slot.TABLE.getName(), null, values);
    }

    // 更新指定 field 和 slot 的數量（count）
    public void updateCount(int field, int slot, int newCount) {
        ContentValues values = new ContentValues();
        values.put(DatabaseHelper.slot.COUNT.getName(), newCount);

        String whereClause = DatabaseHelper.slot.FIELD.getName() + "=? AND " + DatabaseHelper.slot.SLOT.getName() + "=?";
        String[] whereArgs = { String.valueOf(field), String.valueOf(slot) };

        database.update(DatabaseHelper.slot.TABLE.getName(), values, whereClause, whereArgs);
    }


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

        database.beginTransaction();
        try {
            for(SlotField slotField: SlotField.values()) {
                if (slotMap.containsKey(slotField.getField())) {
                    List<SlotStructure> slotList = slotMap.get(slotField.getField());
                    for (SlotStructure data : slotList) {
                        insertOne(data);
                    }
                }
            }

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

    // 獲取所有 Products
    public Map<Integer, List<SlotStructure>> getAll() {
        Map<Integer, List<SlotStructure>> slotMap = new HashMap<>();

        Cursor cursor = database.query(
                DatabaseHelper.slot.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()));
                int field = cursor.getInt(cursor.getColumnIndexOrThrow(DatabaseHelper.slot.FIELD.getName()));
                int slot = cursor.getInt(cursor.getColumnIndexOrThrow(DatabaseHelper.slot.SLOT.getName()));
                String productId = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseHelper.slot.PRODUCT_ID.getName()));
                int count = cursor.getInt(cursor.getColumnIndexOrThrow(DatabaseHelper.slot.COUNT.getName()));
                boolean lock = cursor.getInt(cursor.getColumnIndexOrThrow(DatabaseHelper.slot.LOCK.getName())) == 1;
                String otherData = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseHelper.slot.OTHER_DATA.getName()));

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

                ProductStructure product = null;

                try {
                    product = MyApp.getInstance().getProduct(productId);
                } catch (LogsNoSuchElementException e) {
                    product = new ProductStructure("?", "","",0,0,0,8, "", "","","");
                }

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

                slotMap.get(field).add(new SlotStructure(field, slot, product, count, lock, jsonObject));
            }
            cursor.close();
        }

        return slotMap;
    }

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

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

