from peewee import IntegrityError
from ui.barcodes_step_editor import Barcodes_Step_Editor
from ui.connector_step_editor import Connector_Step_Editor
from ui.count_step_editor import Count_Step_Editor
from ui.editor import Editor
from ui.helpers import replace_widget
from ui.leak_step_editor import Leak_Step_Editor
from ui.pipe_cutter_step_editor import Pipe_Cutter_Step_Editor
from ui.print_step_editor import Print_Step_Editor
from ui.resistance_step_editor import Resistance_Step_Editor
from ui.screws_step_editor import Screws_Step_Editor
from ui.vision_step_editor import Vision_Step_Editor
from ui.instruction_step_editor import Instruction_Step_Editor


class Recipe_Spec_And_Step_Editor(Editor):
    def __init__(self, action=None, cell_widget=None, unsupported_steps=None):
        super().__init__(action=action, cell_widget=cell_widget)
        self.crud = None
        self.steps_map = {
            "count": {
                "type": "count",
                "enable": self.count_enabled_cb,
                "widget": "count_editor_w",
                "editor": Count_Step_Editor(),
                "tab": self.count_t,
            },
            "connector": {
                "type": "connector",
                "enable": self.connector_enabled_cb,
                "widget": "connector_editor_w",
                "editor": Connector_Step_Editor(),
                "tab": self.connector_t,
            },
            "barcodes": {
                "type": "barcodes",
                "enable": self.barcode_enabled_cb,
                "widget": "barcode_editor_w",
                "editor": Barcodes_Step_Editor(),
                "tab": self.barcode_t,
            },
            "resistance": {
                "type": "resistance",
                "enable": self.resistance_enabled_cb,
                "widget": "resistance_editor_w",
                "editor": Resistance_Step_Editor(),
                "tab": self.resistance_t,
            },
            "screws": {
                "type": "screws",
                "enable": self.screws_enabled_cb,
                "widget": "screws_editor_w",
                "editor": Screws_Step_Editor(),
                "tab": self.screws_t,
            },
            "instruction": {
                "type": "instruction",
                "enable": self.instruction_enabled_cb,
                "widget": "instruction_editor_w",
                "editor": Instruction_Step_Editor(),
                "tab": self.instruction_t,
            },
            "instruction_extra": {
                "type": "instruction_extra",
                "enable": self.instruction_extra_enabled_cb,
                "widget": "instruction_extra_editor_w",
                "editor": Instruction_Step_Editor(),
                "tab": self.instruction_extra_t,
            },
            "vision": {
                "type": "vision",
                "enable": self.vision_enabled_cb,
                "widget": "vision_editor_w",
                "editor": Vision_Step_Editor(),
                "tab": self.vision_t,
            },
            "leak_1": {
                "type": "leak_1",
                "enable": self.leak_enabled_1_cb,
                "widget": "leak_editor_1_w",
                "editor": Leak_Step_Editor(),
                "tab": self.leak_1_t,
            },
            "leak_2": {
                "type": "leak_2",
                "enable": self.leak_enabled_2_cb,
                "widget": "leak_editor_2_w",
                "editor": Leak_Step_Editor(),
                "tab": self.leak_2_t,
                "hidden": "second_leak_test" in unsupported_steps,
            },
            "pipe_cutter": {
                "type": "pipe_cutter",
                "enable": self.pipe_cutter_enabled_cb,
                "widget": "pipe_cutter_editor_w",
                "editor": Pipe_Cutter_Step_Editor(),
                "tab": self.pipe_cutter_t,
            },
            "print": {
                "type": "print",
                "enable": self.print_enabled_cb,
                "widget": "print_editor_w",
                "editor": Print_Step_Editor(),
                "tab": self.print_t,
            },
        }
        for step_name in unsupported_steps:
            self.steps_map.get(step_name, {})["hidden"] = True
        self.spec.update({step_name: map["enable"] for step_name, map in self.steps_map.items()})
        for map in self.steps_map.values():
            editor = map.get("editor", None)
            if editor is not None:
                replace_widget(self, map["widget"], editor)
            self.steps_tw.setTabVisible(self.steps_tw.indexOf(map["tab"]), not map.get("hidden", False))
        self.save_steps_b.clicked.connect(self.save_steps)
        self.reset_steps_b.clicked.connect(self.reset_steps)
        self.recipe = None

    def set_readonly(self, readonly=True):
        super().set_readonly(readonly=readonly)
        for map in self.steps_map.values():
            editor = map.get("editor", None)
            if editor is not None:
                editor.set_readonly(readonly=readonly)
        self.save_steps_b.setDisabled(readonly)
        self.reset_steps_b.setDisabled(readonly)

    def do_autocomplete(self, autocomplete):
        if autocomplete is None:
            return
        step_editors_autocomplete = autocomplete.get("step_editors", None)
        super().do_autocomplete(autocomplete)
        if step_editors_autocomplete is not None:
            for step_name, map in self.steps_map.items():
                editor = map.get("editor", None)
                if editor is not None:
                    editor.do_autocomplete(step_editors_autocomplete.get(step_name, None))

    def showing_dialog(self):
        self.reset_steps()

    def render(self, data, field_name=None, row_number=None, crud=None):
        super().render(data, field_name=field_name, row_number=row_number, crud=crud)
        self.crud = crud
        steps_data = data.get("steps", {})

        for step_name, step_def in self.steps_map.items():
            if not step_def.get("hidden", False):
                step_enabled = data.get(step_name, {}) in (True, 1, "x")
                step_def["enable"].setChecked(step_enabled)
                step_def["spec"] = steps_data.get(step_name, {})

        self.render_steps()

    def parse(self, action=None, row_number=None, crud=None):
        ret = super().parse(row_number=row_number, crud=crud)
        ret["steps"] = {}
        #self.save_steps()
        for step_name, step_map in self.steps_map.items():
            if not step_map.get("hidden", False):
                ret["steps"][step_name]=self.steps_map[step_name]["spec"]
        return ret

    def render_steps(self):
        for step_name, step_map in self.steps_map.items():
            spec = step_map.get("spec", None)
            if spec is not None:
                editor = step_map.get("editor", None)
                if editor is not None:
                    editor.render(spec)

    def reset_steps(self):
        self.render_steps()

    def save_steps(self):
        for step_name,step_map in self.steps_map.items():
            if not step_map.get("hidden", False):
                editor = step_map.get("editor", None)
                if editor is not None:
                    step_dict = editor.parse()
                    self.steps_map[step_name]["spec"]=step_dict
                else:
                    self.steps_map[step_name]["spec"] = {}
        if self.crud is not None:
            self.crud().set_modified()
        parsed_value=self.parse()
        self.cell_widget().value = parsed_value
        self.reset_steps()
