import os
import sys
from glob import glob

from lib.db import Recipes, Users
from PyQt5.QtCore import QTimer, pyqtSignal
from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import QShortcut
from ui.crud import Crud, Json_External_Dialog_Editor_Cell_Widget
from ui.helpers import replace_widget
from ui.recipe_spec_and_step_editor import Recipe_Spec_And_Step_Editor
from ui.widget import Widget


class Recipe_Selection(Widget):
    ok = pyqtSignal(Recipes)

    def __init__(self, unsupported_steps=None):
        super().__init__()
        session = Users.get_session()
        if session.is_admin:
            # readonly = ["id"]
            readonly = False
            crud_aliases = {
                # "id": "Id",
                "name": "Ricetta",
                "client": "Cliente",
                "part_number": "N° disegno",
                "spec": "Specifica",
                "description": "Descrizione",
                # "archived": "Archiviata",
            }
            filters = None
        else:
            readonly = True
            crud_aliases = {
                "name": "Ricetta",
                "client": "Cliente",
                "part_number": "N° disegno",
                "spec": "Specifica",
                "description": "Descrizione",
                # "archived": "Archiviata",
            }
            filters = {"archived": False}
        self.crud = Crud(
            "recipes",
            display_name="SELEZIONE RICETTA",
            readonly=readonly,
            select=list(crud_aliases.keys()),
            filters=filters,
            fields_aliases=crud_aliases,
            autocomplete={
                "spec": {
                    "step_editors": {
                        "resistance": {
                            "scale": 500,
                            "expected": 0,
                            "tolerance": 20,
                        },
                        "leak_1": {
                            "pre_filling_time": 1,
                            "pre_filling_pressure": 1000,
                            "filling_time": 1,
                            "settling_time": 1,
                            "settling_pressure_min_percent": 5,
                            "settling_pressure_max_percent": 5,
                            "test_time": 5,
                            "test_pressure_min_delta": 100,
                            "test_pressure": 1000,
                            "test_pressure_max_delta": 100,
                            "flush_time": 1,
                            "flush_pressure": 100,
                        },
                        "leak_2": {
                            "pre_filling_time": 1,
                            "pre_filling_pressure": 1000,
                            "filling_time": 1,
                            "settling_time": 1,
                            "settling_pressure_min_percent": 5,
                            "settling_pressure_max_percent": 5,
                            "test_time": 5,
                            "test_pressure_min_delta": 100,
                            "test_pressure": 1000,
                            "test_pressure_max_delta": 100,
                            "flush_time": 1,
                            "flush_pressure": 100,
                        },
                        "vision": {
                            # "recipe": sorted(glob("*.ini", root_dir="./config/vision/recipes/")), # only in python3.10
                            "recipe": sorted(map(os.path.basename, glob("./config/vision/recipes/*.ini"))),
                        },
                        "print": {
                            # "template": sorted(glob("*.prn", root_dir="./config/label_templates/")), # only in python3.10
                            "template": sorted(map(os.path.basename, glob("./config/label_templates/*.prn"))),
                        },
                    },
                },
                "archived": False,
            },
            widget_classes={"spec": lambda *args, **kwargs: Json_External_Dialog_Editor_Cell_Widget(Recipe_Spec_And_Step_Editor, *args, **kwargs, unsupported_steps=unsupported_steps), },
            pagination=25,
        )
        self.crud.delete_b.setEnabled(False)
        self.crud.delete_b.setVisible(False)
        replace_widget(self, "crud_w", self.crud)
        self.crud_modified = None
        self.selected = None
        self.select_b.setEnabled(False)
        self.select_b.clicked.connect(self.select)
        QShortcut(QKeySequence("Return"), self).activated.connect(self.select_b.click)
        QShortcut(QKeySequence("Enter"), self).activated.connect(self.select_b.click)
        self.crud.modified.connect(self.check_modified)
        self.crud.selected.connect(self.check_selected)
        self.crud.emit()
        self.crud.db_tw.setColumnWidth(0, 200)
        self.crud.db_tw.setColumnWidth(1, 200)
        self.crud.db_tw.setColumnWidth(2, 200)
        self.crud.db_tw.setColumnWidth(3, 200)
        self.crud.db_tw.setColumnWidth(4, 200)
        self.crud.db_tw.setColumnWidth(5, 400)
        # TESTING
        if "--auto-select" in sys.argv or "--test" in sys.argv:
            recipe = "TEST"
            cn = self.crud.select_index["name"]
            self.crud.db_tw.clearSelection()
            for rn in range(1, self.crud.db_tw.rowCount()):
                if self.crud.db_tw.cellWidget(rn, cn).text() == recipe:
                    selection = self.crud.db_tw.model().index(rn, cn)
                    self.crud.db_tw.setCurrentIndex(selection)
                    break
            self.test_timer = QTimer()
            self.test_timer.setSingleShot(True)
            self.test_timer.timeout.connect(self.select_b.clicked.emit)
            self.test_timer.start(500)
        # /TESTING

    def check_modified(self, modified):
        self.crud_modified = modified
        self.check(self.crud_modified, self.selected)

    def check_selected(self, selected=None):
        if selected is not None and len(selected) == 1:
            selected = selected[0] - 1   # - 1 because rn starts from 1 (filters line)
            if selected >= 0 and selected < len(self.crud.data_index):
                selected = self.crud.data_index[selected]
                if selected is not None:
                    self.selected = selected
                else:
                    self.selected = None
        else:
            self.selected = None
        self.check(self.crud_modified, self.selected)

    def check(self, modified, selected):
        self.select_b.setEnabled(modified is False and selected is not None)

    def select(self):
        if self.selected is not None:
            self.ok.emit(self.crud.db.table_model.get_by_id(self.selected))
