using System;
using System.Data.OleDb;
using System.Data.SqlClient;
using banco1.persistencia;
using System.Collections;

namespace banco1.domain
{
	/// <summary>
	/// Descripción breve de Credito.
	/// </summary>
	public class Credito : Tarjeta
	{
		public Credito(String sucursal, String ccc) : base(sucursal, ccc)
		{
		}

		public Credito(Cuenta cuentaAsociada, double credito, Cliente titular) : base()
		{
			this.mCuentaAsociada=cuentaAsociada;
			this.setTitular(titular);
			this.mNumero=this.getNumeroSiguiente();
			this.mMesCaducidad=(byte) DateTime.Now.Month;
			this.mAñoCaducidad=(byte) (DateTime.Now.Year-2000+3);
			actualizaNumeroSiguiente(this.mNumero);
			this.mSucursal=cuentaAsociada.sucursal;
			this.mCCC=getCCCSiguiente(mSucursal);
			this.mFechaDeCreacion=DateTime.Now;
			this.mCuentaAsociada=cuentaAsociada;
			this.mCredito=credito;
			this.mActivo=true;
			insert();
			actualizaCCCSiguiente(sucursal, mCCC);
			mTitulares=new ArrayList();
		}

		public override void insert() 
		{
			base.insert();
			if (mCredito<=0) 
				throw new Exception("Esta tarjeta es de crédito, que debe ser mayor que cero");
			if (mTitular==null || mTitular.Trim().Length==0)
				throw new Exception("Seleccione un titular");
			String SQL="Insert into Tarjetas " +
				"(Sucursal, CCC, Número, Titular, MesCaducidad, " +
				"AñoCaducidad, Crédito, SucursalCuentaAsociada, " +
				"CCCCuentaAsociada) values (?, ?, ?, ?, ?, ?, ?, ?, ?)";
			OleDbCommand cmd = Broker.getCommand(SQL);
			cmd.Parameters.Add("", OleDbType.VarChar).Value=this.mSucursal;
			cmd.Parameters.Add("", OleDbType.VarChar).Value=this.mCCC;
			cmd.Parameters.Add("", OleDbType.VarChar).Value=this.mNumero;
			cmd.Parameters.Add("", OleDbType.VarChar).Value=this.mTitular;
			cmd.Parameters.Add("", OleDbType.TinyInt).Value=this.mMesCaducidad;
			cmd.Parameters.Add("", OleDbType.TinyInt).Value=this.mAñoCaducidad;
			cmd.Parameters.Add("", OleDbType.Double).Value=this.mCredito;
			cmd.Parameters.Add("", OleDbType.VarChar).Value=this.mCuentaAsociada.sucursal;
			cmd.Parameters.Add("", OleDbType.VarChar).Value=this.mCuentaAsociada.ccc;
			cmd.ExecuteNonQuery();
			cmd.Connection.Close();
		}

		public override void sacarDinero(double importe) 
		{
			if (creditoDisponible()<importe*1.03)
				throw new Exception("No dispone de suficiente crédito para retirar " + importe);
			Movimiento m=new Movimiento("Retirada de efectivo", 
				DateTime.Now, importe, this);
			this.movimientos.Add(m);
			m.insert();
			Movimiento m2=new Movimiento("Comisión por retirada de efectivo", 
				DateTime.Now, importe*0.03, this);
			this.movimientos.Add(m2);
			m2.insert();
		}

		public override void pagarEnComercio(double importe, String comercio) 
		{
			banco1.Visa.VisaWS visa=new banco1.Visa.VisaWS();
			if (!visa.validarCompra(this.mNumero, importe))
				throw new Exception("Operación no validada por Visa");
			if (creditoDisponible()<importe)
				throw new Exception("No dispone de suficiente crédito para retirar " + importe);
			Movimiento m=new Movimiento("Retirada de efectivo", 
				DateTime.Now, importe, this);
			this.movimientos.Add(m);
			m.insert();
		}

		public double creditoDisponible() 
		{
			String SQL="Select sum(importe) from Movimientos where " +
				"Sucursal=? and CCC=? and Month(Fecha)=?";
			OleDbCommand cmd = Broker.getCommand(SQL);
			cmd.Parameters.Add("", OleDbType.VarChar).Value=this.mSucursal;
			cmd.Parameters.Add("", OleDbType.VarChar).Value=this.mCCC;
			cmd.Parameters.Add("", OleDbType.Integer).Value=DateTime.Now.Month;
			OleDbDataReader r=cmd.ExecuteReader();
			double result=0;
			if (r.Read()) 
			{
				result=r.GetDouble(0);
				cmd.Connection.Close();
			} else throw new Exception("Error en Credito::creditoDisponible");
			return result;
		}
	}
}
