package eu.eudat.models.data.admin.components.datasetprofile;

import eu.eudat.models.data.components.commons.DefaultValue;
import eu.eudat.models.data.components.commons.ViewStyle;
import eu.eudat.models.data.components.commons.Visibility;
import eu.eudat.logic.utilities.interfaces.ViewStyleDefinition;
import eu.eudat.logic.utilities.builders.ModelBuilder;
import org.apache.commons.lang3.RandomStringUtils;

import java.util.List;
import java.util.stream.Collectors;

public class Field implements ViewStyleDefinition<eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field>, Comparable {

    public enum ValidationType {
        NONE((short) 0), REQUIRED((short) 1), URL((short) 2);
        private short value;

        private ValidationType(short value) {
            this.value = value;
        }

        public short getValue() {
            return value;
        }

        public static ValidationType fromInteger(int value) {
            switch (value) {
                case 0:
                    return NONE;
                case 1:
                    return REQUIRED;
                case 2:
                    return URL;
                default:
                    return NONE;

            }
        }

        public static List<ValidationType> fromIntegers(List<Integer> values) {
            return values.stream().map(ValidationType::fromInteger).collect(Collectors.toList());
        }
    }

    private String id;
    private Integer ordinal;
    private String rdaCommonStandard;
    private String value;
    private ViewStyle viewStyle;
    private String datatype;
    private int page;
    private DefaultValue defaultValue;
    private Object data;
    private Visibility visible;
    private List<ValidationType> validations;
    private Boolean export;

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    public int getOrdinal() {
        return ordinal;
    }
    public void setOrdinal(int ordinal) {
        this.ordinal = ordinal;
    }

    public String getRdaCommonStandard() {
        return rdaCommonStandard;
    }
    public void setRdaCommonStandard(String rdaCommonStandard) {
        this.rdaCommonStandard = rdaCommonStandard;
    }

    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }

    public ViewStyle getViewStyle() {
        return viewStyle;
    }
    public void setViewStyle(ViewStyle viewStyle) {
        this.viewStyle = viewStyle;
    }

    public int getPage() {
        return page;
    }
    public void setPage(int page) {
        this.page = page;
    }

    public DefaultValue getDefaultValue() {
        return defaultValue;
    }
    public void setDefaultValue(DefaultValue defaultValue) {
        this.defaultValue = defaultValue;
    }

    public String getDatatype() {
        return datatype;
    }
    public void setDatatype(String datatype) {
        this.datatype = datatype;
    }

    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }

    public Visibility getVisible() {
        return visible;
    }
    public void setVisible(Visibility visible) {
        this.visible = visible;
    }

    public List<Integer> getValidations() {
        return this.validations.stream().map(item -> (int) item.getValue()).collect(Collectors.toList());
    }
    public void setValidations(List<Integer> validations) {
        this.validations = ValidationType.fromIntegers(validations);
    }

    public Boolean getExport() {
        return export;
    }

    public void setExport(Boolean export) {
        this.export = export;
    }

    @Override
    public eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field toDatabaseDefinition(eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field field) {
        if (this.id == null || this.id.isEmpty()) this.id = "field_" + RandomStringUtils.random(5, true, true);

        field.setId(this.id);
        field.setOrdinal(this.ordinal);
        field.setViewStyle(this.viewStyle);
        field.setData(new ModelBuilder().toFieldData(data, this.viewStyle.getRenderStyle()));
        field.setVisible(this.visible);
        field.setDefaultValue(this.defaultValue);
        field.setValidations(this.validations);
        field.setRdaCommonStandard(this.rdaCommonStandard);
        field.setExport(this.export);
        return field;
    }

    @Override
    public void fromDatabaseDefinition(eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field item) {
        this.id = item.getId();
        this.ordinal = item.getOrdinal();
        this.viewStyle = item.getViewStyle();
        this.data = item.getData();
        this.visible = item.getVisible();
        this.defaultValue = item.getDefaultValue();
        this.validations = item.getValidations();
        this.rdaCommonStandard = item.getRdaCommonStandard();
        this.export = item.getExport();
    }

    @Override
    public int compareTo(Object o) {
        return this.ordinal.compareTo(((Field) o).ordinal);
    }

}
