package com.ejie.ad74a.util.comun;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;

import com.ejie.ad74a.exceptions.ManagerErrors;
import com.ejie.ad74a.util.constantes.Constantes;

/**
 * 
 * <p>
 * Descipción: Clase que devuelve fechas en distintos formatos
 * </p>
 * 
 * @version 1.0
 **/
public abstract class UtilidadesFecha {

	private static final Logger logger = LoggerFactory.getLogger(UtilidadesFecha.class);

	/**
	 * Transforma una fecha String a java.sql.Date.
	 * 
	 * @param fecha   String con la fecha a convertir
	 * @param formato String con el formato de la fecha
	 * @return java.sql.Date fecha convertida
	 * @exception ParseException Se produce la excepciÃ³n cuando la fecha estÃ¡ mal
	 *                           formateada.
	 */
	public static java.util.Date formatearStringToDateFormat(String fecha, String formato) throws ParseException {
		SimpleDateFormat formatoDelTexto = new SimpleDateFormat(formato);
		java.util.Date dFecha = null;

		dFecha = new java.util.Date(formatoDelTexto.parse(fecha).getTime());

		return dFecha;
	}

	public static String getFechaSistema(String format) {
		SimpleDateFormat dtf = new SimpleDateFormat(format);
		Calendar calendar = Calendar.getInstance();
		Date dateObj = calendar.getTime();
		String formattedDate = dtf.format(dateObj);
		return formattedDate;
	}

	public static Date getFechaSistema() {
		Calendar calendar = Calendar.getInstance();
		Date dateObj = calendar.getTime();
		return dateObj;
	}

	/**
	 * Convierte una fecha a su string representativo
	 * 
	 * @param gcFechaHora fecha con hora
	 * @param locale      idioma
	 * @return null si el calendario es null
	 */
	public static String fechaHoraGCToString(GregorianCalendar gcFechaHora, Locale locale) {
		String sFecha = null;
		String idioma = locale.getLanguage();
		if (gcFechaHora != null) {
			Date fecha = gcFechaHora.getTime();

			SimpleDateFormat df = new SimpleDateFormat(
					(idioma.equalsIgnoreCase(Constantes.EUSKARA) ? Constantes.EU_DATETIME_MASK
							: Constantes.ES_DATETIME_MASK),
					locale);
			sFecha = df.format(fecha);
		}
		return sFecha;
	}

	/**
	 * Convierte una fecha de tipo Date a XMLGregorianCalendar
	 * 
	 * @param fecha
	 * @return
	 * @throws DatatypeConfigurationException
	 */
	public static XMLGregorianCalendar parseDate2XMLGregorianCalendar(Date fecha)
			throws DatatypeConfigurationException {
		GregorianCalendar c = new GregorianCalendar();
		c.setTime(fecha);
		return DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
	}

	/**
	 * Crea un calendario con la fecha actual, con horas minutos y segundos
	 * 
	 * @return GregorianCalendar
	 */
	public static GregorianCalendar getCalendarInstanceHMS() {
		GregorianCalendar fecha = (GregorianCalendar) Calendar.getInstance();
		return fecha;
	}

	public static Date parsearFechaPlatea(String fecha) {
		Date fechaD = null;
		try {
			if (null != fecha && fecha.contains("-")) {

				if (fecha.contains(":")) {
					fechaD = UtilidadesFecha.formatearStringToDateFormato(fecha,
							Constantes.DATE_FORMAT_PLATEA_XML_EVENTS);
				} else {
					fechaD = UtilidadesFecha.formatearStringToDateFormato(fecha, Constantes.ES_GUION_DATE_MASK);
				}

			} else if (null != fecha && fecha.contains("/")) {
				fechaD = UtilidadesFecha.formatearStringToDateFormato(fecha,
						Constantes.DATE_FORMAT_TIMESTAMP_MASK_DEFAULT);
			}

		} catch (ParseException e) {
			// ManagerErrors.manageException(e,
			// ConstantesCodeError.MENSAJE_ERROR_TRATAR_FECHA_REGISTRO, null,
			// ConstantesCodeError.CODE_ERROR_TRATAR_FECHA_REGISTRO, null);
			logger.error("Error al parsear la fecha de registro");
		}

		return fechaD;
	}

	public static Date parsearFechaTelevida(String fecha) {
		Date fechaD = null;
		try {
			fechaD = UtilidadesFecha.formatearStringToDateFormato(fecha, Constantes.ES_GUION_DATE_MASK);
		} catch (ParseException e) {
			logger.error("Error al parsear la fecha de Televida");
			ManagerErrors.manageException(e);
		}
		return fechaD;
	}

	/**
	 * Transforma una fecha String a java.sql.Date.
	 * 
	 * @param fecha   String con la fecha a convertir
	 * @param formato String con el formato de la fecha
	 * @return java.sql.Date fecha convertida
	 * @exception ParseException Se produce la excepciÃ³n cuando la fecha estÃ¡ mal
	 *                           formateada.
	 */
	public static java.util.Date formatearStringToDateFormato(String fecha, String formato) throws ParseException {
		SimpleDateFormat formatoDelTexto = new SimpleDateFormat(formato);
		java.util.Date dFecha = null;

		try {
			dFecha = new java.util.Date(formatoDelTexto.parse(fecha).getTime());
		} catch (ParseException e) {
			logger.error("Error al parsear la fecha de Televida");
			ManagerErrors.manageException(e);
		}

		return dFecha;
	}

	public static String formatearDateToStringFormatoTime(Date fecha, String locale) throws ParseException {
		SimpleDateFormat formatter;
		if (Constantes.EUSKARA.equalsIgnoreCase(locale)) {
			formatter = new SimpleDateFormat(Constantes.EU_DATETIME_MASK);
		} else {
			formatter = new SimpleDateFormat(Constantes.ES_DATETIME_MASK);
		}
		return formatter.format(fecha);
	}

	public static String formatearDateToStringMasc(Date datePfFecha, String formato) throws Exception {
		StringBuilder strFechaFinal = new StringBuilder();

		SimpleDateFormat sdf = new SimpleDateFormat(formato);
		strFechaFinal.append(sdf.format(datePfFecha));
		return strFechaFinal.toString();
	}

	public static String getCurrentYear() throws Exception {
		Calendar fecha = new GregorianCalendar();
		int anyo = fecha.get(Calendar.YEAR);
		return String.valueOf(anyo);
	}

	/**
	 * Metodo que formatea la fecha teniendo en cuenta el idioma
	 * 
	 * @param str {@link String[]}
	 * @return {@link String}
	 */
	public static String formatearDateToString(Date date) {
		SimpleDateFormat parseador;
		if (com.ejie.ad74a.constantes.Constantes.ES.equals(LocaleContextHolder.getLocale().getLanguage())) {
			parseador = new SimpleDateFormat(com.ejie.ad74a.constantes.Constantes.ES_DATE_MASK);
		} else {
			parseador = new SimpleDateFormat(com.ejie.ad74a.constantes.Constantes.EU_DATE_MASK);
		}
		String fecha = parseador.format(date);
		return fecha;

	}

	/**
	 * Metodo que formatea la fecha pasando la máscara como parámetro
	 * 
	 * @param str {@link String[]}
	 * @return {@link String}
	 */
	public static String formatearDateToString(Date date, String mascara) {
		String fecha = null;
		if (date != null) {
			SimpleDateFormat parseador;
			parseador = new SimpleDateFormat(mascara);
			fecha = parseador.format(date);
		}
		return fecha;

	}

	public static String formatearDateToStringFormatoTimeSeconds(Date fecha, String locale) throws ParseException {
		SimpleDateFormat formatter;
		if (locale == null) {
			locale = LocaleContextHolder.getLocale().getLanguage();
		}
		if (Constantes.EUSKARA.equalsIgnoreCase(locale)) {
			formatter = new SimpleDateFormat(Constantes.DATE_FORMAT_TIMESTAMP_EU_MASK_DEFAULT);
		} else {
			formatter = new SimpleDateFormat(Constantes.DATE_FORMAT_TIMESTAMP_MASK_DEFAULT);
		}
		return formatter.format(fecha);
	}
}