
package de.ivu.elect.jee.faces;

import java.io.Serializable;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import javax.annotation.Nullable;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RequestScoped
@Named(UserLocale.COMPONENT_NAME)
public class UserLocale implements Serializable {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "userLocale";

  private static final Logger LOG = LoggerFactory.getLogger(UserLocale.class);

  @Inject
  private transient UserLocaleStore userLocaleStore;

  public UserLocale() {
    super();
  }

  public Locale getLocale() {
    try {
      return userLocaleStore.getLocale();
    } catch (Exception ex) {
      LOG.warn("Fehler beim Lesen des Locales", ex);
    }

    return Locale.getDefault(); // fallback
  }

  public void setLocale(Locale locale) {
    try {
      userLocaleStore.setLocale(locale);
    } catch (Exception ex) {
      LOG.warn("Fehler beim Setzen des Locales [locale = {}]", locale, ex);
    }
  }

  public String getLanguage() {
    return getLocale().getLanguage();
  }

  @Nullable
  public String formatDate(Date date) {
    return formatDateMedium(date, getLocale());
  }

  @Nullable
  public String formatTime(Date dateTime) {
    return formatTimeHHmmss(dateTime, getLocale());
  }

  @Nullable
  public String formatTimeHHmm(Date dateTime) {
    return formatTimeHHmm(dateTime, getLocale());
  }

  @Nullable
  public String formatTimeHHmmss(Date dateTime) {
    return formatTimeHHmmss(dateTime, getLocale());
  }

  @Nullable
  public String formatDateTime(Date dateTime) {
    return formatDateTimeMedium(dateTime, getLocale());
  }

  @Nullable
  public String formatNumber(Long number) {
    return formatNumber(number, getLocale());
  }

  // Textrichtung Rechts-nach-Links
  public Boolean isRTL() {
    return getLocale().getLanguage().toLowerCase().startsWith("ar".toLowerCase());
  }

  // Textrichtung Links-nach-Rechts
  public Boolean isLTR() {
    return !isRTL();
  }

  public String getTextDirection() {
    if (Boolean.TRUE.equals(isRTL())) {
      return "RTL";
    }

    return "LTR";
  }

  @Nullable
  public static String formatDatePattern(@Nullable Date date, Locale locale, String pattern) {
    if (date != null) {
      try {
        return new SimpleDateFormat(pattern, locale).format(date);
      } catch (Exception ex) {
        LOG.error("Fehler bei der Datumsformatierung [date = {}, locale = {}, pattern = {}]", date, locale, pattern, ex);
      }
    }

    return null;
  }

  @Nullable
  public static String formatDateShort(@Nullable Date date, Locale locale) {
    if (date == null) {
      return null;
    }

    return DateFormat.getDateInstance(DateFormat.SHORT, locale).format(date);
  }

  @Nullable
  public static String formatDateMedium(@Nullable Date date, Locale locale) {
    if (date == null) {
      return null;
    }

    return DateFormat.getDateInstance(DateFormat.MEDIUM, locale).format(date);
  }

  @Nullable
  public static String formatDateLong(@Nullable Date date, Locale locale) {
    if (date == null) {
      return null;
    }

    return DateFormat.getDateInstance(DateFormat.LONG, locale).format(date);
  }

  @Nullable
  public static String formatDateTimeMedium(Date dateTime, Locale locale) {
    if (dateTime == null) {
      return null;
    }

    return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale).format(dateTime);
  }

  @Nullable
  public static String formatTimeHHmm(Date dateTime, Locale locale) {
    if (dateTime == null) {
      return null;
    }

    return DateFormat.getTimeInstance(DateFormat.SHORT, locale).format(dateTime);
  }

  @Nullable
  public static String formatTimeHHmmss(Date dateTime, Locale locale) {
    if (dateTime == null) {
      return null;
    }

    return DateFormat.getTimeInstance(DateFormat.MEDIUM, locale).format(dateTime);
  }

  @Nullable
  public static String formatNumber(Long number, Locale locale) {
    if (number == null) {
      return null;
    }

    return NumberFormat.getInstance(locale).format(number);
  }
}
