import uuid
from typing import List

from opentrons.protocol_api import Well, TrashBin, WasteChute
from opentrons.types import Location

from ..data.data import Data

from ..data.dbo.module import ModuleWrapper
from helpers import get_location_from_str


class ModuleCommonLogic:
    def __init__(self, data: Data):
        self.data = data

    @staticmethod
    def module_is_valid(module: ModuleWrapper | None):
        return module is not None and module.module_instance is not None

    def verify_module(self, module_id):
        module = self.data.static_items.get_module_by_id(module_id)
        if not self.module_is_valid(module):
            raise RuntimeError("Module id not valid")
        return module

    def load_adapter(self, module_id: uuid.UUID, load_name: str, location: str, namespace: str | None):
        module = self.verify_module(module_id)

        old_adapter = self.data.static_items.get_labware_by_deck_location(module.module_instance.parent)
        if len(old_adapter) is not 0:
            for key, value in old_adapter.items():
                if value.data.load_name == load_name and value.data.namespace == namespace:
                    return key

        adapter = module.load_adapter(load_name=load_name,
                                                  location=get_location_from_str(location),
                                                  namespace=namespace)

        return self.data.static_items.register_labware(labware=adapter)

    def load_labware(self, module_id: uuid.UUID, load_name: str, location: str, namespace: str | None = None, adapter_name: str | None = None):
        module = self.verify_module(module_id)

        old_labware = self.data.static_items.get_labware_by_deck_location(module.module_instance.parent)
        if len(old_labware) is not 0:
            for key, value in old_labware.items():
                if value.data.load_name == load_name and value.data.namespace == namespace:
                    return key

        labware = module.load_labware(load_name=load_name,
                                                  location=get_location_from_str(location),
                                                  namespace=namespace,
                                                  adapter=adapter_name
                                                  )

        self.data.dynamic_items.register_wells_by_labware(labware=labware)

        return self.data.static_items.register_labware(labware=labware)

    def labware(self, module_id: uuid.UUID):
        module = self.verify_module(module_id)

        if module.module_instance.labware is None:
            return None

        return self.data.static_items.get_generic_id_by_reference(module.module_instance.labware)

    def parent(self, module_id: uuid.UUID):
        module = self.verify_module(module_id)

        if module.labware_instance is None:
            return None

        return module.module_instance.parent