#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from Interfaces.OpoTestsInterface import OpoTestsInterface
from typing import Self, Any, Optional
from Models.QuestionModel import QuestionModel
from Models.SetModel import SetModel

class QuestionsManager:

    def __init__(self:Self, ot:OpoTestsInterface) -> None:
        self.ot:OpoTestsInterface = ot
        self.__sets:list[SetModel] = []
        self.__groups:list[str] = []
        self.__groups_variables:list[dict[str, Any]] = []
        self.__questions:list[QuestionModel] = []
        self.__variables:dict[str, Any] = {}

    def start(self:Self) -> None:
        pass

    def update(self:Self) -> None:
        pass

    def empty(self:Self) -> None:
        self.__sets = []
        self.__groups = []
        self.__groups_variables:list[dict[str, Any]] = []
        self.__questions = []

    def add(self:Self, 
        inputs:dict[str, Any|None]|list[Any|None]|tuple[Any|None]|str, 
        overwrite:bool = False
    ) -> None:
        
        set_data:dict[str, Any|None]

        for set_data in self.ot.load_json_data(inputs):

            set:SetModel = SetModel(set_data, len(self.__sets))
            group_done:bool = False
            key:str
            question_data:dict[str, Any|None]
            group_variables:dict[str, Any|None]|None = set_data.get("group_variables")
            variables:dict[str, Any|None]|None = set_data.get("variables")

            variables and self.__variables.update(variables)

            for set.group_i, key in enumerate(self.__groups):
                if key == set.group:
                    group_done = True
                    group_variables and self.__groups_variables[set.group_i].update(group_variables)
                    break

            if not group_done:
                set.group_i += 1
                self.__groups += [set.group]
                if group_variables:
                    self.__groups_variables += [group_variables]

            for question_data in set_data.get("queries", []):

                variables:dict[str, Any|None]|None = question_data.get("variables")
                question:QuestionModel = QuestionModel(question_data, set)
                allowed:bool = True

                variables and self.__variables.update(variables)

                for i, existing_question in enumerate(self.__questions):
                    if (
                        existing_question.set == question.set and 
                        existing_question.group == question.group and 
                        len(existing_question.questions) == len(question.questions) and 
                        not any(question_string != question.questions[j] for j, question_string in enumerate(existing_question.questions))
                    ):
                        if overwrite:
                            self.__questions[i] = question
                        allowed = False
                        break

                if allowed:
                    self.__questions += [question]

    def get_value(self:Self, key:str, i:Optional[int] = None) -> Any|None:

        set:dict[str, Any]

        for set in ([] if i is None else [
            self.__questions[i].own_variables, 
            self.__groups_variables[self.__questions[i].group]
        ]) + [self.__variables]:
            if key in set:
                return set[key]
        return None