"""
consumer module
"""
import re
import time
import random
from abc import ABC, abstractmethod
from ticketing_service_core.orm import SearchFilters

class Consumer(ABC):
    """The consumer class is an abstract class from which all event consumers must inherit
    """

    def __init__(self):
        super().__init__()
        self.__id_seed = (time.time_ns() // 100000)+random.randint(100000, 999999)
        self.__id_count = 0

    @abstractmethod
    def consume(self, body, mq_adapter, sql_adapter = None):
        """
        Consumes a message from the queue and takes some action as a result
        """

    def generate_id(self):
        self.__id_count = self.__id_count + 1
        return self.__id_seed + self.__id_count

    def parse_query(self, query):
        filters = SearchFilters()
        for field in query:
            statement = re.search(r"([=<>~])(.+)", query[field])
            operation = statement.group(1)
            criteria = statement.group(2).split(",")

            for i, criterion in enumerate(criteria):
                # Convert criteria to native types if necessary
                if self.cast_number(criterion):
                    criteria[i] = self.cast_number(criterion)
                elif criterion == "true":
                    criteria[i] = True
                elif criterion == "false":
                    criteria[i] = False

            match operation:
                case "=":
                    filters.equal(field, criteria[0])
                case "!":
                    filters.not_equal(field, criteria[0])
                case "<":
                    filters.at_most(field, criteria[0])
                case ">":
                    filters.at_least(field, criteria[0])
                case "~":
                    filters.is_among(field, criteria)

        return filters

    def cast_number(self, value: str):
        try:
            # Try converting to float first
            number = float(value)

            # Optionally convert to int if it's a whole number
            if number.is_integer():
                return int(number)

            return number
        except ValueError:
            return None
