package control;

import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;

import utiles.Archivo;

/**
 * Esta clase se dedica al control de la ventana Principal y sus distintos
 * paneles
 */
public class ControlPrincipal {

	Archivo archivo;

	/**
	 * Constructor de la clase el cual inicia una clase archivo y llama a los
	 * metodos ordenar, actId y actSaldos
	 * 
	 * @param usuario
	 *            Usuario al que corresponde el archivo que se abrira
	 */

	public ControlPrincipal(String usuario) {

		archivo = new Archivo(usuario);
		ordenar();
		actId();
		actSaldos();
	}

	/**
	 * Genera el id para la nueva linea, calcula el saldo y aņade la linea
	 * generada al archivo
	 * 
	 * @param fecha
	 *            Fecha con formato dd/mm/yyyy
	 * @param documento
	 *            Forma de pago
	 * @param fd
	 *            Fuente o destino
	 * @param desc
	 *            Descripcion
	 * @param ing
	 *            Ingreso, debe corresponder al formato de un int
	 * @param egr
	 *            Egreso, debe corresponder al formato de un int
	 */

	public void aņadir(String fecha, String documento, String fd, String desc, String ing, String egr) {

		int id = 1;
		int saldo = 0;

		String[] arch = archivo.entregarProcesado();
		String[] lastRow = arch[arch.length - 1].split(";");
		if (isFiled()) {

			id = Integer.parseInt(lastRow[0]) + 1;
			saldo = Integer.parseInt(lastRow[lastRow.length - 1]) + Integer.parseInt(ing) - Integer.parseInt(egr);
		} else {

			saldo = Integer.parseInt(ing) - Integer.parseInt(egr);

		}

		String fila = id + ";" + fecha + ";" + documento + ";" + fd + ";" + desc + ";" + ing + ";" + egr + ";" + saldo;

		archivo.escribirArchivo(fila);

	}

	/**
	 * Modifica una fila que contenga el id entregado
	 * 
	 * @param id
	 *            Identificador de la fila a modificar
	 * @param fecha
	 *            Fecha con formato dd/mm/yyyy
	 * @param documento
	 *            Forma de pago
	 * @param fd
	 *            Fuente o destino
	 * @param desc
	 *            Descripcion
	 * @param ing
	 *            Ingreso, debe corresponder al formato de un int
	 * @param egr
	 *            Egreso, debe corresponder al formato de un int
	 */

	public void modificarFila(String id, String fecha, String documento, String fd, String desc, String ing,
			String egr) {

		String[] arch = archivo.entregarProcesado();

		for (int x = 0; x < arch.length; x++) {

			if (arch[x].split(";")[0].equals(id)) {

				arch[x] = id + ";" + fecha + ";" + documento + ";" + fd + ";" + desc + ";" + ing + ";" + egr + ";"
						+ "0";

			}

		}

		actSaldos();
		archivo.actArchivo(arch);
	}

	/**
	 * Elimina la fila que contenga el id entregado
	 * 
	 * @param id
	 *            Identificador de la fila a eliminar
	 */

	public void eliminarFila(String id) {

		archivo.borrarLinea(id);
		actSaldos();

	}

	/**
	 * Ordena las filas del archivo respecto a sus fechas
	 */

	public void ordenar() {

		String[] arch = archivo.entregarProcesado();

		boolean swapped = true;
		int j = 0;
		String tmp;

		while (swapped) {

			swapped = false;
			j++;

			for (int i = 0; i < arch.length - j; i++) {

				Calendar f1 = new GregorianCalendar(Integer.parseInt(arch[i].split(";")[1].split("/")[2]),
						Integer.parseInt(arch[i].split(";")[1].split("/")[1]),
						Integer.parseInt(arch[i].split(";")[1].split("/")[0]));
				Calendar f2 = new GregorianCalendar(Integer.parseInt(arch[i + 1].split(";")[1].split("/")[2]),
						Integer.parseInt(arch[i + 1].split(";")[1].split("/")[1]),
						Integer.parseInt(arch[i + 1].split(";")[1].split("/")[0]));

				if (f1.after(f2)) {

					tmp = arch[i];
					arch[i] = arch[i + 1];
					arch[i + 1] = tmp;
					swapped = true;

				}

			}

		}
		archivo.actArchivo(arch);
	}

	/**
	 * Actualiza todos los saldos dentro del archivo para que sean
	 * correspondientes. Esto es por que cualquier reordenamiento en las filas
	 * del archivo rompe el contenido de la columna de saldos.
	 */

	public void actSaldos() {

		String[] arch = archivo.entregarProcesado();
		if (isFiled()) {

			for (int x = 0; x < arch.length; x++) {

				int saldoAnterior = 0;
				int saldo = 0;

				if (x > 0) {

					String[] aux = arch[x - 1].split(";");
					saldoAnterior = Integer.parseInt(aux[aux.length - 1]);

				}

				String textAux = "";
				String[] aux = arch[x].split(";");

				if (arch[x].length() > 1) {

					saldo = saldoAnterior + Integer.parseInt(aux[5]) - Integer.parseInt(aux[6]);

				}

				for (int z = 0; z < aux.length - 1; z++) {

					textAux += aux[z] + ";";

				}

				textAux += saldo;
				arch[x] = textAux;

			}

			archivo.actArchivo(arch);

		}

	}

	/**
	 * Actualiza los id de las filas del archivo esto para que despues de
	 * cualquier reordenamiento se mantenga el orden en los ids
	 */
	public void actId() {

		String[] arch = archivo.entregarProcesado();
		int id = 1;
		for (int x = 0; x < arch.length; x++) {

			String[] aux = arch[x].split(";");
			aux[0] = String.valueOf(id);
			id++;

			String linea = "";
			for (int z = 0; z < aux.length; z++) {

				linea += aux[z] + ";";

			}

			arch[x] = linea;

		}
		archivo.actArchivo(arch);
	}

	/**
	 * @return La ultima fila del archivo dividida en los ;
	 */

	public String[] getLastRow() {

		String[] arch = archivo.entregarProcesado();
		return arch[arch.length - 1].split(";");

	}

	/**
	 * Entrega la fila correspondiente al id
	 * 
	 * @param id
	 *            Identificador de la fila
	 * @return La fila que contenga ese id
	 */

	public String[] getRow(int id) {

		String[] arch = archivo.entregarProcesado();
		return arch[id].split(";");

	}

	/**
	 * @return Cantidad total de filas en el archivo
	 */

	public int getRowCount() {

		String[] arch = archivo.entregarProcesado();
		return arch.length;

	}

	/**
	 * Comprueba si el archivo tiene contenido, se considera eso como verdadero
	 * cuando el archivo contiene mas de 5 caracteres
	 * 
	 * @return Booleano indicando si tiene contenido o no
	 */

	public boolean isFiled() {

		return (archivo.leerArchivo().length() > 5);

	}

	/**
	 * Genera un String[][] con un resumen por mes de cada archivo, teniendo en
	 * siendo el primer indice correspondiente a fecha/saldo/ingresos/egresos y
	 * el segundo indice correspondiente a cada mes contenido en el archivo
	 * 
	 * @return String[][] con los datos del resumen
	 */

	public String[][] resumenMes() {

		String[][] fin = new String[4][1];

		if (archivo.leerArchivo().length() > 5) {

			String[] arch = archivo.entregarProcesado();
			ArrayList<String> fechas = new ArrayList<String>();
			ArrayList<String> ings = new ArrayList<String>();
			ArrayList<String> egrs = new ArrayList<String>();

			for (int x = 0; x < arch.length; x++) {

				String fecha = arch[x].split(";")[1].split("/")[2] + "-" + arch[x].split(";")[1].split("/")[1];

				if (!fechas.contains(fecha)) {

					fechas.add(fecha);
					ings.add("0");
					egrs.add("0");

				}

			}

			for (int x = 0; x < arch.length; x++) {

				String fecha = arch[x].split(";")[1].split("/")[2] + "-" + arch[x].split(";")[1].split("/")[1];
				String ing = arch[x].split(";")[5];
				String egr = arch[x].split(";")[6];
				int index = fechas.indexOf(fecha);

				ings.set(index, String.valueOf(Integer.parseInt(ings.get(index)) + Integer.parseInt(ing)));
				egrs.set(index, String.valueOf(Integer.parseInt(egrs.get(index)) + Integer.parseInt(egr)));

			}

			fin = new String[4][fechas.size()];

			for (int x = 0; x < fechas.size(); x++) {

				fin[0][x] = fechas.get(x);
				fin[1][x] = String.valueOf(Integer.parseInt(ings.get(x)) - Integer.parseInt(egrs.get(x)));
				fin[2][x] = ings.get(x);
				fin[3][x] = egrs.get(x);

			}

			fin = ordenarSaldos(fin);

		}

		return fin;

	}

	/**
	 * Ordena los saldos del resumen generado por el metodo resumenMes
	 * @param saldos String[][] entregado por resumenMes
	 * @return String[][] ordenado respecto a los meses
	 */
	private String[][] ordenarSaldos(String[][] saldos) {

		boolean swapped = true;
		int j = 0;
		String tmp;
		String tmp1;
		String tmp2;
		String tmp3;

		while (swapped) {

			swapped = false;
			j++;

			for (int i = 0; i < saldos[0].length - j; i++) {

				YearMonth f1 = YearMonth.parse(saldos[0][i]);
				YearMonth f2 = YearMonth.parse(saldos[0][i + 1]);

				if (f1.isAfter(f2)) {

					tmp = saldos[0][i];
					tmp1 = saldos[1][i];
					tmp2 = saldos[2][i];
					tmp3 = saldos[3][i];

					saldos[0][i] = saldos[0][i + 1];
					saldos[1][i] = saldos[1][i + 1];
					saldos[2][i] = saldos[2][i + 1];
					saldos[3][i] = saldos[3][i + 1];

					saldos[0][i + 1] = tmp;
					saldos[1][i + 1] = tmp1;
					saldos[2][i + 1] = tmp2;
					saldos[3][i + 1] = tmp3;

					swapped = true;

				}

			}

		}

		return saldos;

	}

	/**
	 * Genera un resumen de los datos en el archivo respecto a el tipo de documento.
	 * @return int[] con los saldos respecto al documento utilizado
	 */
	
	public int[] resumenDoc() {

		String[] arch = archivo.entregarProcesado();
		int[] docs = { 0, 0, 0 };

		if (archivo.leerArchivo().length() > 5) {

			for (int x = 0; x < arch.length; x++) {

				String[] aux = arch[x].split(";");

				switch (aux[2]) {

				case "Efectivo":

					docs[0] += Integer.parseInt(aux[5]) - Integer.parseInt(aux[6]);
					break;

				case "Transferencia":

					docs[1] += Integer.parseInt(aux[5]) - Integer.parseInt(aux[6]);
					break;

				case "Credito":

					docs[2] += Integer.parseInt(aux[5]) - Integer.parseInt(aux[6]);
					break;

				}

			}

		}

		return docs;

	}

}
