# (c) cavaliba - data - field - float


from .field import Field


# -------------
# FLOAT
# -------------
class FieldFloat(Field):
    def __init__(self, fieldname, fieldschema, alljson):
        super().__init__(fieldname, fieldschema, alljson)

        # if no json, unpack default_value
        if not alljson:
            if self.default_value:
                ml = self.default_value.split()
                try:
                    self.value = [float(i) for i in ml]
                except Exception:
                    self.value = []

    def get_datapoint_ui_detail(self):
        datapoint = super().get_datapoint_ui_detail()
        a = [str(i) for i in self.value]
        datapoint["value"] = " ".join(a)
        return datapoint

    def get_datapoint_ui_edit(self):
        datapoint = super().get_datapoint_ui_edit()
        # force to string and separate multi value with space
        a = [str(i) for i in self.value]
        datapoint["value"] = " ".join(a)
        return datapoint

    def merge_request(self, request):
        """data is a list of string ["3 5", ...] from request.POST.getlist"""

        data = request.POST.getlist(self.fieldname, default=[])
        self.value = []
        try:
            values = data[0].split()
        except Exception:
            return
        for i in values:
            try:
                self.value.append(float(i))
            except Exception:
                pass

    def merge_import(self, data):
        """
        source: csv/json/yaml, mono or multi value
        data=[a,b,c, ...] / data=a
        a="3.5" / a="20.2 32.7" / a=3.5
        no thousand white separator allowed (strip in pipeline)
        """
        self.value = []
        if type(data) is float or type(data) is int:
            self.value.append(float(data))
        elif type(data) is str:
            xi = data.split()
            for i in xi:
                try:
                    self.value.append(float(i))
                except Exception:
                    pass
        elif type(data) is list:
            for x in data:
                if type(x) is float or type(x) is int:
                    self.value.append(float(x))
                elif type(x) is str:
                    xi = data.split()
                    for i in xi:
                        try:
                            self.value.append(float(i))
                        except Exception:
                            pass
        if not self.is_multi():
            if len(self.value) > 1:
                self.value = [self.value[0]]

    def is_valid(self):
        r = super().is_valid()
        for v in self.value:
            if type(v) is str:
                if len(v) == 0:
                    continue
            try:
                float(v)
            except Exception:
                return False

            options = self.dataformat_ext
            if options:
                dictopt = options.split()

                for opt in dictopt:
                    # greater or equal
                    if opt.startswith("gte_"):
                        (tmp, valopt) = opt.split("_")
                        for v in self.value:
                            try:
                                if v < float(valopt):
                                    return False
                            except Exception:
                                pass

                    # greater strict
                    if opt.startswith("gte_"):
                        (tmp, valopt) = opt.split("_")
                        for v in self.value:
                            try:
                                if v <= float(valopt):
                                    return False
                            except Exception:
                                pass

                    # lesser or equal
                    if opt.startswith("lte_"):
                        (tmp, valopt) = opt.split("_")
                        for v in self.value:
                            try:
                                if v > float(valopt):
                                    return False
                            except Exception:
                                pass

                    # lesser strict
                    if opt.startswith("lt_"):
                        (tmp, valopt) = opt.split("_")
                        for v in self.value:
                            try:
                                if v >= float(valopt):
                                    return False
                            except Exception:
                                pass

        return r
