package com.mohamnag.inappbilling.helper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;

/**
 * Represents a block of information about in-app items. An Inventory is
 * returned by such methods as {@link IabHelper#queryInventory}.
 */
public class Inventory {

    Map<String, SkuDetails> mSkuMap = new HashMap<String, SkuDetails>();
    Map<String, Purchase> mPurchaseMap = new HashMap<String, Purchase>();
    String base64EncodedPublicKey;

    public Inventory(String licenceKey) {
        base64EncodedPublicKey = licenceKey;
    }

    /**
     * Returns the listing details for an in-app product.
     */
    public SkuDetails getSkuDetails(String sku) {
        return mSkuMap.get(sku);
    }

    public void addSkuDetails(SkuDetails sku) {
        mSkuMap.put(sku.getSku(), sku);
    }

    /**
     * Returns purchase information for a given product, or null if there is no
     * purchase.
     */
    public Purchase getPurchase(String sku) {
        return mPurchaseMap.get(sku);
    }
    
    public Purchase getPurchaseByOrderId(String id) {
        for(Purchase purchase : mPurchaseMap.values()) {
            if(id.equals(purchase.getOrderId())) {
                return purchase;
            }
        }
        
        return null;
    }

    /**
     * Returns whether or not there exists a purchase of the given product.
     */
    public boolean hasPurchase(String sku) {
        return mPurchaseMap.containsKey(sku);
    }

    /**
     * Return whether or not details about the given product are available.
     */
    public boolean hasDetails(String sku) {
        return mSkuMap.containsKey(sku);
    }

    /**
     * Erase a purchase (locally) from the inventory, given its product ID. This
     * just modifies the Inventory object locally and has no effect on the
     * server! This is useful when you have an existing Inventory object which
     * you know to be up to date, and you have just consumed an item
     * successfully, which means that erasing its purchase data from the
     * Inventory you already have is quicker than querying for a new Inventory.
     */
    public void erasePurchase(String sku) {
        if (mPurchaseMap.containsKey(sku)) {
            mPurchaseMap.remove(sku);
        }
    }
    
    public void erasePurchaseByOrderId(String id) {
        for(Purchase purchase : mPurchaseMap.values()) {
            if(id.equals(purchase.getOrderId())) {
                mPurchaseMap.remove(purchase.getSku());
            }
        }
    }

    /**
     * Returns a list of all owned product IDs.
     */
    public List<String> getAllOwnedSkus() {
        return new ArrayList<String>(mPurchaseMap.keySet());
    }

    /**
     * Returns a list of all owned product IDs of a given type
     */
    List<String> getAllOwnedSkus(String itemType) {
        List<String> result = new ArrayList<String>();
        for (Purchase p : mPurchaseMap.values()) {
            if (mSkuMap.get(p.getSku()).getType().equals(itemType)) {
                result.add(p.getSku());
            }
        }
        return result;
    }

    /**
     * Returns a list of all purchases.
     */
    public ArrayList<Purchase> getAllPurchases() {
        return new ArrayList<Purchase>(mPurchaseMap.values());
    }

    /**
     * Returns a list of all products.
     */
    public List<SkuDetails> getAllProducts() {
        return new ArrayList<SkuDetails>(mSkuMap.values());
    }

    /**
     * Builds up a JSON array of products loaded in inventory
     *
     * @return
     */
    public JSONArray getAllProductsJSON() throws JSONException {
        JSONArray jsonProductDetailsList = new JSONArray();
        for (SkuDetails product : mSkuMap.values()) {
            jsonProductDetailsList.put(product.toJson());
        }

        return jsonProductDetailsList;
    }
    
    /**
     * Builds up a JSON array of purchases loaded in inventory
     *
     * @return
     */
    public JSONArray getAllPurchasesJSON() throws JSONException {
        JSONArray jsonProductDetailsList = new JSONArray();
        for (Purchase purchase : mPurchaseMap.values()) {
            jsonProductDetailsList.put(purchase.toJavaScriptJson());
        }

        return jsonProductDetailsList;
    }

    public int getProductCount() {
        return mSkuMap.size();
    }

    public int getPurchaseCount() {
        return mPurchaseMap.size();
    }

    public void addPurchase(Purchase p) {
        mPurchaseMap.put(p.getSku(), p);
    }
}
