package com.utopiaindustries.qualitychecker.db;

import static com.utopiaindustries.qualitychecker.db.DatabaseHelper.PRODUCT_COLUMN_ASIN;
import static com.utopiaindustries.qualitychecker.db.DatabaseHelper.PRODUCT_COLUMN_MARKETPLACE;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.utopiaindustries.qualitychecker.models.Product;

import java.util.ArrayList;
import java.util.List;

public class ProductRepository {

    private final DatabaseHelper dbHelper;
    private final SQLiteDatabase database;
    private final ExecutorService executorService;


    public ProductRepository( Context context ) {
        dbHelper = new DatabaseHelper ( context );
        database = dbHelper.getWritableDatabase();
        executorService = Executors.newSingleThreadExecutor();
    }

    /*
    *   Insert list of products in batch
    * */
    public void insert( List<Product> products) {
        executorService.execute(() -> {
            database.beginTransaction();
            try {
                for (Product product : products) {
                    ContentValues values = new ContentValues();
                    values.put(PRODUCT_COLUMN_ASIN, product.getAsin());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_PARENT_ASIN, product.getParentAsin());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_MARKETPLACE, product.getMarketplace());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_SKU, product.getSku());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_TITLE, product.getTitle());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_HS_CODE, product.getHsCode());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_MODEL_NUMBER, product.getModelNumber());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_BOX, product.getItemPerBox());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_SM_COLOR, product.getSmColor());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_SM_SIZE, product.getSmSize());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_SM_ITEM_NAME, product.getSmItemName());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_PACK, product.getItemPerPack());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_INVENTORY, product.getInventory());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_CATEGORY, product.getCategory());
                    values.put(DatabaseHelper.PRODUCT_COLUMN_FNSKU, product.getFnsku() );
                    database.insertWithOnConflict(DatabaseHelper.PRODUCT_TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE);
                }
                database.setTransactionSuccessful();
            } finally {
                database.endTransaction();
                close();
            }
        });
    }

    /*
    *  insert single product
    * */
    public void insert(Product product) {
        executorService.execute(() -> {
            ContentValues values = new ContentValues();
            values.put(PRODUCT_COLUMN_ASIN, product.getAsin());
            values.put(DatabaseHelper.PRODUCT_COLUMN_PARENT_ASIN, product.getParentAsin());
            values.put(DatabaseHelper.PRODUCT_COLUMN_MARKETPLACE, product.getMarketplace());
            values.put(DatabaseHelper.PRODUCT_COLUMN_SKU, product.getSku());
            values.put(DatabaseHelper.PRODUCT_COLUMN_TITLE, product.getTitle());
            values.put(DatabaseHelper.PRODUCT_COLUMN_HS_CODE, product.getHsCode());
            values.put(DatabaseHelper.PRODUCT_COLUMN_MODEL_NUMBER, product.getModelNumber());
            values.put(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_BOX, product.getItemPerBox());
            values.put(DatabaseHelper.PRODUCT_COLUMN_SM_COLOR, product.getSmColor());
            values.put(DatabaseHelper.PRODUCT_COLUMN_SM_SIZE, product.getSmSize());
            values.put(DatabaseHelper.PRODUCT_COLUMN_SM_ITEM_NAME, product.getSmItemName());
            values.put(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_PACK, product.getItemPerPack());
            values.put(DatabaseHelper.PRODUCT_COLUMN_INVENTORY, product.getInventory());
            values.put(DatabaseHelper.PRODUCT_COLUMN_CATEGORY, product.getCategory());
            values.put(DatabaseHelper.PRODUCT_COLUMN_FNSKU, product.getFnsku());
            database.insertWithOnConflict(DatabaseHelper.PRODUCT_TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE);
            close();
        });
    }

    /*
    *  Retrieve product by sku
    * */
    @SuppressLint("Range")
    public List<Product> getProductBySkuOrAsin(String fnsku, String marketplace) {
        String selection = DatabaseHelper.PRODUCT_COLUMN_FNSKU + "=?";
        String[] selectionArgs = {fnsku};
        if( marketplace != null &&  ! marketplace.isEmpty() ){
            selection += " AND " + PRODUCT_COLUMN_MARKETPLACE + "=?";
            selectionArgs = new String[]{ fnsku, marketplace };
        }

        Cursor cursor = database.query(DatabaseHelper.PRODUCT_TABLE_NAME,
                null,
                selection,
                selectionArgs,
                null, null, null);

        List<Product> products = new ArrayList<>();

        if (cursor != null && cursor.moveToFirst()) {
            do {
                Product product = new Product();
                product.setAsin(cursor.getString(cursor.getColumnIndex(PRODUCT_COLUMN_ASIN)));
                product.setParentAsin(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_PARENT_ASIN)));
                product.setMarketplace(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_MARKETPLACE)));
                product.setSku(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SKU)));
                product.setTitle(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_TITLE)));
                product.setHsCode(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_HS_CODE)));
                product.setModelNumber(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_MODEL_NUMBER)));
                product.setItemPerBox(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_BOX)));
                product.setSmColor(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SM_COLOR)));
                product.setSmSize(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SM_SIZE)));
                product.setSmItemName(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SM_ITEM_NAME)));
                product.setItemPerPack(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_PACK)));
                product.setInventory(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_INVENTORY)));
                product.setCategory(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_CATEGORY)));
                product.setFnsku(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_FNSKU)));
                products.add( product );
            } while ( cursor.moveToNext() );
            cursor.close();
        }
        close();
        return products;
    }

    /*
    * Retrieve products
    * */
    @SuppressLint("Range")
    public Product getProduct(String asin, String marketplace, String sku) {
            String selection = PRODUCT_COLUMN_ASIN + "=? AND " +
                    DatabaseHelper.PRODUCT_COLUMN_MARKETPLACE + "=? AND " +
                    DatabaseHelper.PRODUCT_COLUMN_SKU + "=?";
            String[] selectionArgs = {asin, marketplace, sku};

            Cursor cursor = database.query(DatabaseHelper.PRODUCT_TABLE_NAME,
                    null,
                    selection,
                    selectionArgs,
                    null, null, null);

            if (cursor != null && cursor.moveToFirst()) {
                Product product = new Product();
                product.setAsin( cursor.getString( cursor.getColumnIndex(PRODUCT_COLUMN_ASIN ) ));
                product.setParentAsin( cursor.getString( cursor.getColumnIndex( DatabaseHelper.PRODUCT_COLUMN_PARENT_ASIN ) ));
                product.setMarketplace( cursor.getString( cursor.getColumnIndex( DatabaseHelper.PRODUCT_COLUMN_MARKETPLACE )));
                product.setSku(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SKU)));
                product.setTitle(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_TITLE)));
                product.setHsCode(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_HS_CODE)));
                product.setModelNumber(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_MODEL_NUMBER)));
                product.setItemPerBox(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_BOX)));
                product.setSmColor(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SM_COLOR)));
                product.setSmSize(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SM_SIZE)));
                product.setSmItemName(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_SM_ITEM_NAME)));
                product.setItemPerPack(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_ITEM_PER_PACK)));
                product.setInventory(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_INVENTORY)));
                product.setCategory(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_CATEGORY)));
                product.setFnsku(cursor.getString(cursor.getColumnIndex(DatabaseHelper.PRODUCT_COLUMN_FNSKU)));
                cursor.close();
                close();
                return product;
            }

            if (cursor != null) {
                cursor.close();
            }
        return null;
    }

    /*
    *  Close the database
     */
    public void close() {
        dbHelper.close();
        executorService.shutdown();
    }
}
