package org.jboss.resteasy.test.providers.jaxb.resource;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;

import static java.util.Calendar.YEAR;

@XmlRootElement
@XmlSeeAlso({
        AbstractJaxbClassCompanyCustomer.class,
        AbstractJaxbClassPrivatCustomer.class
})
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class AbstractJaxbClassCustomer implements java.io.Serializable {
    private static final long serialVersionUID = 8488010636885492122L;

    public static final int NACHNAME_LENGTH_MIN = 2;
    public static final int NACHNAME_LENGTH_MAX = 32;
    public static final int VORNAME_LENGTH_MAX = 32;
    public static final int CUSTOMERNNR_LENGTH_MAX = 32;
    public static final int DETAILS_LENGTH_MAX = 128 * 1024;
    public static final int PASSWORD_LENGTH_MAX = 256;

    public static final String PRIVATCUSTOMER = "P";
    public static final String COMPANYCUSTOMER = "F";

    static final String FIND_CUSTOMERS = "findcustomers";
    static final String FIND_CUSTOMERS_BY_NACHNAME = "findCustomersByNachname";
    static final String FIND_CUSTOMERS_BY_NACHNAME_FETCH_BESTELLUNGEN = "findCustomersByNachnameFetchBestellungen";
    static final String FIND_CUSTOMER_BY_ID_FETCH_BESTELLUNGEN = "findCustomersByIdFetchBestellungen";
    static final String FIND_CUSTOMERS_BY_PLZ = "findCustomersByPlz";

    static final String PARAM_CUSTOMER_ID = "customerId";
    static final String PARAM_CUSTOMER_NACHNAME = "nachname";
    static final String PARAM_CUSTOMER_ADRESSE_PLZ = "plz";

    // Alternativen: TABLE, SEQUENCE, IDENTITY, AUTO, NONE (=default)
    @XmlAttribute(name = "id", required = true)
    protected Long id = -1L;

    @XmlTransient
    protected int version = 0;

    @XmlElement(required = true)
    protected String nachname = "";

    protected String vorname = "";

    @XmlAttribute(required = true)
    protected String customersnr = "NnVn-001";

    protected Date seit = null;

    @XmlTransient
    protected int anzJahre;

    @XmlElement(name = "betreuer")
    protected String betreuerKey;

    @XmlElementWrapper(name = "bestellungen")
    @XmlElement(name = "bestellung")
    protected List<String> bestellungenKeys;

    protected String details;

    @XmlTransient
    protected String password = "";

    @XmlTransient
    protected Date erzeugt = null;

    @XmlTransient
    protected Date aktualisiert = null;

    public AbstractJaxbClassCustomer() {
        super();
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public String getNachname() {
        return nachname;
    }

    public void setNachname(String nachname) {
        this.nachname = nachname;
    }

    public String getVorname() {
        return vorname;
    }

    public void setVorname(String vorname) {
        this.vorname = vorname;
    }

    public String getCustomersnr() {
        return customersnr;
    }

    public void setCustomersnr(String customersnr) {
        this.customersnr = customersnr;
    }

    public Date getSeit() {
        return seit;
    }

    public void setSeit(Date seit) {
        this.seit = seit;
    }

    public int getAnzJahre() {
        final GregorianCalendar now = new GregorianCalendar();
        final GregorianCalendar seitCal = new GregorianCalendar();
        Date temp = seit;
        if (temp == null) {
            temp = new Date();
        }
        seitCal.setTime(temp);

        anzJahre = now.get(YEAR) - seitCal.get(YEAR);

        return anzJahre;
    }

    public String getSeitAsString(int style, Locale locale) {
        Date temp = seit;
        if (temp == null) {
            temp = new Date();
        }
        final DateFormat f = DateFormat.getDateInstance(style, locale);
        return f.format(temp);
    }

    public void setSeit(String seit, int style, Locale locale) {
        final DateFormat f = DateFormat.getDateInstance(style, locale);
        try {
            this.seit = f.parse(seit);
        } catch (ParseException e) {
        }
    }

    public String getBetreuerKey() {
        return betreuerKey;
    }

    public void setBetreuerKey(String betreuerKey) {
        this.betreuerKey = betreuerKey;
    }

    public List<String> getBestellungenKeys() {
        return bestellungenKeys;
    }

    public void setBestellungenKeys(List<String> bestellungenKeys) {
        this.bestellungenKeys = bestellungenKeys;
    }

    public abstract String getArt();

    public String getDetails() {
        return details;
    }

    public void setDetails(String details) {
        this.details = details;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String passwort) {
        this.password = passwort;
    }

    public Date getAktualisiert() {
        return aktualisiert;
    }

    public void setAktualisiert(Date aktualisiert) {
        this.aktualisiert = aktualisiert;
    }

    public Date getErzeugt() {
        return erzeugt;
    }

    public void setErzeugt(Date erzeugt) {
        this.erzeugt = erzeugt;
    }

    @Override
    public String toString() {
        return "id=" + id + ", version=" + version +
                ", nachname=" + nachname + ", vorname=" + vorname +
                ", nr=" + customersnr +
                ", seit=" + getSeitAsString(DateFormat.MEDIUM, Locale.GERMANY) +
                ", anzJahre=" + getAnzJahre() +
                ", password=" + password +
                ", erzeugt=" + erzeugt +
                ", aktualisiert=" + aktualisiert;
    }

    @Override
    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result = PRIME * result + ((nachname == null) ? 0 : nachname.hashCode());
        result = PRIME * result + ((seit == null) ? 0 : seit.hashCode());
        result = PRIME * result + ((vorname == null) ? 0 : vorname.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final AbstractJaxbClassCustomer other = (AbstractJaxbClassCustomer) obj;
        if (nachname == null) {
            if (other.nachname != null) {
                return false;
            }
        } else if (!nachname.equals(other.nachname)) {
            return false;
        }
        if (seit == null) {
            if (other.seit != null) {
                return false;
            }
        } else if (!seit.equals(other.seit)) {
            return false;
        }
        if (vorname == null) {
            if (other.vorname != null) {
                return false;
            }
        } else if (!vorname.equals(other.vorname)) {
            return false;
        }
        return true;
    }
}
