import json


class Metadata:
    GUID = "guid"
    VALUE = "value"

    UPPER_GROUP_IS_CALCIFIED = "90864d1e-8b73-467c-b5af-f07ce0565e39"
    UPPER_GROUP_1_MENINGEOMA = "1daa1826-aaa5-4546-8e46-12346081adb1"
    UPPER_GROUP_2_MENINGEOMAS = "3ff1fc31-18b3-4557-880f-f53d3afff7b4"
    UPPER_GROUP_3_MENINGEOMAS = "5388556a-ae89-43a4-8693-85ad371f3cc2"
    UPPER_GROUP_MORE_THAN_3_MENINGEOMAS = "50926738-94d6-43fb-ae34-5f96c4a66292"

    LOWER_GROUP_IS_CALCIFIED = "543c6e4a-7aee-47d6-b896-3de0113dbde9"
    LOWER_GROUP_1_MENINGEOMA = "8e08e045-17d8-4021-baa8-43f3478993a8"
    LOWER_GROUP_2_MENINGEOMAS = "9135d6cf-3b42-4804-a2b1-3cebdbd4d4aa"
    LOWER_GROUP_3_MENINGEOMAS = "f4dac8f7-a73b-404f-9143-40e73aa03fea"
    LOWER_GROUP_MORE_THAN_3_MENINGEOMAS = "2a127c9f-8e6d-498b-be9a-66c5be076233"

    @staticmethod
    def create(file_path):

        lower_group_meningeomas = set()
        upper_group_meningeomas = set()

        metadata = Metadata(file_path)

        with open(file_path, "r", encoding="UTF-8") as file:
            metadata_json = json.load(file)
            for item in metadata_json["data"]:
                if metadata._is_calcified_record(item):
                    metadata._set_calcified_property(item)
                if metadata._is_meningeoma_record(item):
                    lower_group_meningeomas.add(metadata._count_meningeomas_in_lower_group(item))
                    upper_group_meningeomas.add(metadata._count_meningeomas_in_upper_group(item))

            metadata.meningeoma_count = max(lower_group_meningeomas) + max(upper_group_meningeomas)

        return metadata

    def __init__(self, file_path):
        self.file_path = file_path
        self.is_calcified = False
        self.meningeoma_count = 0

    @staticmethod
    def _is_calcified_record(item):
        item_guid = item[Metadata.GUID]
        return item_guid == Metadata.UPPER_GROUP_IS_CALCIFIED or item_guid == Metadata.LOWER_GROUP_IS_CALCIFIED

    # TODO ak je viac lozisk, tak plati to pre vsetky ?
    def _set_calcified_property(self, item):
        if item[Metadata.VALUE]:
            self.is_calcified = True

    def _is_meningeoma_record(self, item):
        item_guid = item[Metadata.GUID]
        return (self._is_1_meningeoma_record(item_guid)
                or self._is_2_meningeomas_record(item_guid)
                or self._is_3_meningeomas_record(item_guid)
                or self._is_more_than_3_meningeomas_record(item_guid))

    def _is_1_meningeoma_record(self, item_guid):
        return item_guid == Metadata.UPPER_GROUP_1_MENINGEOMA or item_guid == Metadata.LOWER_GROUP_1_MENINGEOMA

    def _is_2_meningeomas_record(self, item_guid):
        return item_guid == Metadata.UPPER_GROUP_2_MENINGEOMAS or item_guid == Metadata.LOWER_GROUP_2_MENINGEOMAS

    def _is_3_meningeomas_record(self, item_guid):
        return item_guid == Metadata.UPPER_GROUP_3_MENINGEOMAS or item_guid == Metadata.LOWER_GROUP_3_MENINGEOMAS

    def _is_more_than_3_meningeomas_record(self, item_guid):
        return item_guid == Metadata.UPPER_GROUP_MORE_THAN_3_MENINGEOMAS or item_guid == Metadata.LOWER_GROUP_MORE_THAN_3_MENINGEOMAS

    def _count_meningeomas_in_upper_group(self, item):
        return self._count_meningeomas_in_group(item,
                                                Metadata.UPPER_GROUP_3_MENINGEOMAS,
                                                Metadata.UPPER_GROUP_2_MENINGEOMAS,
                                                Metadata.UPPER_GROUP_1_MENINGEOMA)

    def _count_meningeomas_in_lower_group(self, item):

        return self._count_meningeomas_in_group(item,
                                                Metadata.LOWER_GROUP_3_MENINGEOMAS,
                                                Metadata.LOWER_GROUP_2_MENINGEOMAS,
                                                Metadata.LOWER_GROUP_1_MENINGEOMA)

    def _count_meningeomas_in_group(self, item, three_meningeomas_guid, two_meningeomas_guid, one_meningeoma_guid):
        item_guid = item[Metadata.GUID]
        item_value = item[Metadata.VALUE]



        if self._is_more_than_3_meningeomas_record(item_guid) and item_value:
            raise Exception("Unknown number of meningeomas (more than 3).")

        if (item_guid == three_meningeomas_guid) and item_value:
            return 3
        if (item_guid == two_meningeomas_guid) and item_value:
            return 2
        if (item_guid == one_meningeoma_guid) and item_value:
            return 1
        return 0

    def __repr__(self):
        return "Number of meningeomas: {}, calcified = {}".format(self.meningeoma_count, self.is_calcified)
