package com.fenalco.entities;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import com.fenalco.utilities.database.QueryException;
import com.fenalco.utilities.database.SQLUtilities;
import com.fenalco.utilities.database.Transaction;

/**
 * Esta clase se usa para almacenar la información de una lista de compras
 */
public class ShoppingList
{
	/**
	 * Identificador de la lista de compras
	 */
	private int id;

	/**
	 * Nombre con el que el minorista guardó la lista de compras
	 */
	private String listName;

	/**
	 * Identificador de la empresa que es dueña de la lista
	 */
	private int companyId;

	/**
	 * Nombre de la empresa que es dueña de la lista
	 */
	private String companyName;

	/**
	 * Productos que hacen parte de la lista. Este Hashtable está construido de
	 * la siguiente forma: - el key es el id del proveedor - el value es un
	 * Hashtable organizado de la siguiente forma: - Key: id del objeto
	 * ShoppingListProduct - Value: Objeto de tipo ShoppingListProduct
	 */
	private Hashtable products;

	/**
	 * Constructor por omisión. Crea una lista vacía
	 */
	public ShoppingList( )
	{
		listName = "";
		id = this.hashCode();
		products = new Hashtable();
	}

	/**
	 * Constructor que recibe el id de la lista y la carga de la base de datos
	 * llamando al método loadData
	 * 
	 * @param shoppingListId
	 *            Id de la lista para recuperarla de la base de datos
	 */
	public ShoppingList( int shoppingListId)
	{
		products = new Hashtable();
		this.loadData(shoppingListId);
	}

	/**
	 * Carga la información de la lista desde la base de datos a partir del Id
	 * 
	 * @param shoppingListId
	 *            El identificador de la lista para recuperarla de la base de
	 *            datos
	 * @return un booleano que indica si la lista se pudó cargar o no
	 */
	public boolean loadData( int shoppingListId )
	{
		boolean flag = true;
		try
		{
			String query = new String("SELECT empr_id,list_comp_nombre"
					+ " FROM lista_compra" + " WHERE list_comp_id="
					+ shoppingListId + ";");
			Vector results = new Vector();
			results = SQLUtilities.query(query);
			Hashtable temp = new Hashtable();
			temp = (Hashtable) results.elementAt(0);

			this.setId(shoppingListId);
			this.setListName((String) temp.get("list_comp_nombre"));
			this.setCompanyId(((Integer) temp.get("empr_id")).intValue());

			query = new String("SELECT empr_nombre_comercial" + " FROM empresa"
					+ " WHERE empr_id=" + this.getCompanyId() + ";");
			results = new Vector();
			temp = new Hashtable();
			results = SQLUtilities.query(query);
			temp = (Hashtable) results.elementAt(0);
			this.setCompanyName((String) temp.get("empr_nombre_comercial"));

			query = new String("SELECT empr_nombre_comercial" + " FROM empresa"
					+ " WHERE empr_id=" + this.getCompanyId() + ";");
			results = new Vector();
			temp = new Hashtable();
			results = SQLUtilities.query(query);
			temp = (Hashtable) results.elementAt(0);
			this.setCompanyName((String) temp.get("empr_nombre_comercial"));

			Vector productList = new Vector();
			Hashtable product = new Hashtable();

			query = new String("SELECT prod_list_comp_id"
					+ " FROM producto_lista_compra" + " WHERE list_comp_id="
					+ this.getId() + ";");
			productList = SQLUtilities.query(query);

			for( int i = 0; i < productList.size(); i++ )
			{
				product = (Hashtable) productList.elementAt(i);
				int idProduct = ((Integer) product.get("prod_list_comp_id"))
						.intValue();
				ShoppingListProduct tempProduct = new ShoppingListProduct(
						idProduct);

				this.getProducts().put(new Integer(idProduct), tempProduct);

			}

		}
		catch (QueryException qe)
		{
			System.out.println(qe.getMessage());
			flag = false;

		}

		return flag;
	}

	/**
	 * Almacena la información de la lista en la base de datos construyendo el
	 * sql y adicionandolo a la transacción con el método <CODE>addSql</CODE>
	 * 
	 * @return un booleano que indica si la lista se pudo almacenar en la base
	 *         de datos o no
	 * @param transaction
	 *            la transacción que se está ejecutando
	 */
	public boolean saveData( Transaction transaction )
	{
		boolean flag = true;

		id = this.hashCode();

		String query = new String("INSERT INTO lista_compra" + " VALUES("
				+ this.getId() + "," + this.getCompanyId() + "," + "\'"
				+ this.getListName() + "\'" + ");");
		transaction.addSql(query);

		Enumeration en = this.getProducts().keys();
		for( int i = 0; i < this.getProducts().size(); i++ )
		{
			ShoppingListProduct prod = (ShoppingListProduct) this.getProducts()
					.get(en.nextElement());
			prod.setShoppingListId(id);
			prod.saveData(transaction);
		}

		return flag;
	}

	/**
	 * Actualiza la información de la lista en la base de datos construyendo el
	 * sql y adicionandolo a la transacción con el método <CODE>addSql</CODE>
	 * 
	 * @return un booleano que indica si se pudo actualizar la información o no
	 * @param transaction
	 *            la transacción que se está ejecutando
	 */
	public boolean update( Transaction transaction )
	{
		String query = new String("UPDATE lista_compra" + " SET" + " empr_id="
				+ this.getCompanyId() + "," + " list_comp_nombre=\'"
				+ this.getListName() + "\'" + " WHERE list_comp_id="
				+ this.getId() + ");");
		transaction.addSql(query);
		Enumeration en = this.getProducts().keys();
		for( int i = 0; i < this.getProducts().size(); i++ )
		{
			((ShoppingListProduct) this.getProducts().get(en.nextElement()))
					.update(transaction);
		}
		return true;
	}

	/**
	 * Elimina una lista de compras de la base de datos construyendo el sql y
	 * adicionandolo a la transacción con el método <CODE>addSql</CODE>
	 * 
	 * @return un booleano que indica si se pudo eliminar o no
	 * @param transaction
	 *            la transacción que se está ejecutando
	 */
	public boolean delete( Transaction transaction )
	{
//		Enumeration en = this.getProducts().keys();
//		for( int i = 0; i < this.getProducts().size(); i++ )
//		{
//			((ShoppingListProduct) this.getProducts().get(en.nextElement()))
//					.delete(transaction);
//		}
		
		String products = "DELETE FROM producto_lista_compra WHERE list_comp_id=" + getId() + ";";
		transaction.addSql( products );

		String query = "DELETE FROM lista_compra WHERE list_comp_id=" + this.getId() + ";";
		transaction.addSql(query);

		return true;
	}

	/**
	 * Arma un objeto de tipo <CODE>ShoppingCart</CODE> a partir de la
	 * información de la lista y lo retorna
	 * 
	 * @return Carrito de compras que tiene todos los productos que están en la
	 *         lista
	 */
	public ShoppingCart loadListSession( int storeId )
	{
		ShoppingCart cart = new ShoppingCart();
		Enumeration en = this.getProducts().keys();
		//      System.out.println("el tamaño-->"+ this.getProducts().size());
		for( int i = 0; i < this.getProducts().size(); i++ )
		{

			ShoppingListProduct temp = (ShoppingListProduct) this.getProducts()
					.get(en.nextElement());

			int productId = temp.getSupplierProductId();
			int communityId = DataAccess.getStoreCommunity(storeId, temp
					.getSupplierId());
			if( communityId != 0 )
			{
				PriceScale scale = new PriceScale(productId, communityId);
				temp.setPrice(scale);

				String productCode = temp.getCode();
				String productName = temp.getName();
				int productQuantity = temp.getQuantity();
				double productPrice = temp.getPrice();
				int supplierId = temp.getSupplierId();
				String supplierName = temp.getSupplierName();
				int supplierProductId = temp.getSupplierProductId();

				SupplierProduct sp = new SupplierProduct();
				sp.loadMinimalData(supplierProductId);
				String brand = sp.getBrand();
				String category = sp.getCategoryName();

				ShoppingCartProduct product = new ShoppingCartProduct();
				product.setCode(productCode);
				product.setName(productName);
				product.setQuantity(productQuantity);
				product.setPrice(scale);
				product.setSupplierId(supplierId);
				product.setSupplierName(supplierName);
				product.setSupplierProductId(supplierProductId);
				product.setBrand(brand);
				product.setCategory(category);
				
				SupplierProduct product2 = new SupplierProduct( );
				product2.loadMinimalData( supplierProductId );
				
				product.setTax( product2.getTax() );

				cart.addProduct(product);
			}

		}

		return cart;
	}

	/**
	 * Consultor para el atributo id.
	 * 
	 * @return valor del atributo id.
	 */
	public int getId( )
	{
		return id;
	}

	/**
	 * Modificador para el atributo id.
	 * 
	 * @param id
	 *            Nuevo valor del atributo id.
	 */
	public void setId( int id )
	{
		this.id = id;
	}

	/**
	 * Consultor para el atributo listName.
	 * 
	 * @return valor del atributo listName.
	 */
	public java.lang.String getListName( )
	{
		return listName;
	}

	/**
	 * Modificador para el atributo listName.
	 * 
	 * @param listName
	 *            Nuevo valor del atributo listName.
	 */
	public void setListName( java.lang.String listName )
	{
		this.listName = listName;
	}

	/**
	 * Consultor para el atributo companyId.
	 * 
	 * @return valor del atributo companyId.
	 */
	public int getCompanyId( )
	{
		return companyId;
	}

	/**
	 * Modificador para el atributo companyId.
	 * 
	 * @param companyId
	 *            Nuevo valor del atributo companyId.
	 */
	public void setCompanyId( int companyId )
	{
		this.companyId = companyId;
	}

	/**
	 * Consultor para el atributo companyName.
	 * 
	 * @return valor del atributo companyName.
	 */
	public java.lang.String getCompanyName( )
	{
		return companyName;
	}

	/**
	 * Modificador para el atributo companyName.
	 * 
	 * @param companyName
	 *            Nuevo valor del atributo companyName.
	 */
	public void setCompanyName( java.lang.String companyName )
	{
		this.companyName = companyName;
	}

	/**
	 * Consultor para el atributo products.
	 * 
	 * @return valor del atributo products.
	 */
	public java.util.Hashtable getProducts( )
	{
		return products;
	}

	/**
	 * Modificador para el atributo products.
	 * 
	 * @param products
	 *            Nuevo valor del atributo products.
	 */
	public void setProducts( java.util.Hashtable products )
	{
		this.products = products;
	}

	public int hashCode( )
	{
		return Math.abs(listName.hashCode() + companyId);
	}

}