from db import Database
from PySide2 import QtWidgets as qtw
from PySide2 import QtCore as qtc
from PySide2 import QtGui as qtg


class FreqTable:
    def __init__(self, parent, ui, trial_id):
        self.parent = parent
        self.num_treatments = None
        self.num_levels = None
        self.ui = ui
        self.grid = ui.freqGridLayout
        self.trial_id = trial_id
        self.database = Database.get_instance(parent)

    def on_save_preload(self):
        can_save = True
        if self.ui.frequenciesCheckBox.isChecked():
            can_save = False
        if not self.ui.preloadCheckBox.isChecked():
            can_save = False
        if not self.ui.editPreloadCheckBox.isChecked():
            can_save = False
        if not can_save:
            qtw.QMessageBox.information(
                self.parent, self.parent.tr('Save not available!'),
                self.parent.tr('Select only preload and edit')
            )
            return
        preload = self.extract_counts()
        if self.valid_counts(preload):
            pixmap = qtg.QPixmap("images/tick_mark.png")
            self.database.clear_preload(self.trial_id)
            self.database.save_preload(self.trial_id, preload)
        else:
            pixmap = qtg.QPixmap("images/error.png")
        self.valid_preload_image.setPixmap(pixmap)

    def add_to_preload(self):
        preload = self.database.get_preload(self.trial_id)
        freq = self.extract_counts()
        for key in freq:
            freq[key] += preload[key]
        self.database.clear_preload(self.trial_id)
        self.database.save_preload(self.trial_id, freq)

    def extract_counts(self):
        count = {}
        for r in range(2, self.num_treatments + 2):
            for c in range(1, self.num_levels + 1):
                item = self.grid.itemAtPosition(r, c)
                entry = item.widget()
                key = self.left_top_key[(r, c)]
                count[key] = int(entry.text().strip())
        return count

    def valid_counts(self, count):
        treatments = self.database.read_treatments(self.trial_id)
        factors = self.database.read_factors(self.trial_id)
        tfl = []
        f_total = []
        for factor in factors:
            levels = self.database.factor_levels(factor[0])
            fl = [[] for i in range(len(levels))]
            f_total.append(fl)
        valid = True
        for treatment in treatments:
            s = set()
            row = []
            for i, factor in enumerate(factors):
                t, f = treatment[0], factor[0]
                levels = self.database.factor_levels(f)
                lst = []
                for j, level in enumerate(levels):
                    lv = level[0]
                    cnt = count[(t, f, lv)]
                    f_total[i][j].append(cnt)
                    lst.append(cnt)
                row.append(lst)
                s.add(sum(lst))
                if len(s) > 1:
                    valid = False
            tfl.append(row)
        gt = 0
        for i in range(len(self.total_treatment_buttons)):
            sm = sum(tfl[i][0])
            self.total_treatment_buttons[i].setText(str(sm))
            gt += sm
        self.grand_total_button.setText(str(gt))
        for i, f_t in enumerate(f_total):
            s = []
            for j, f_l in enumerate(f_t):
                sm = sum(f_l)
                self.total_level_button[i][j].setText(str(sm))
                s.append(sm)
            self.total_factorButtons[i].setText(str(sum(s)))
        return valid

    def on_clear_preload(self):
        err = False
        if self.ui.frequenciesCheckBox.isChecked():
            err = True
        if not self.ui.preloadCheckBox.isChecked():
            err = True
        if not self.ui.editPreloadCheckBox.isChecked():
            err = True
        if err:
            qtw.QMessageBox.warning(self.parent, self.parent.tr('Clear preload'),
                                    self.parent.tr('To clear preload, select preload and check edit'))
            return
        button = qtw.QMessageBox.question(self.parent, self.parent.tr("Confirm clear"),
                                          self.parent.tr('Are you sure you want to clear preload'),
                                          qtw.QMessageBox.Yes | qtw.QMessageBox.No)
        if button != qtw.QMessageBox.Yes:
            return
        for r in range(2, self.num_treatments + 2):
            for c in range(1, self.num_levels + 1):
                item = self.grid.itemAtPosition(r, c)
                item.widget().setText('0')
        self.database.clear_preload(self.trial_id)

    def toggleReadOnly(self):
        readOnly = not self.ui.editPreloadCheckBox.isChecked()
        if self.num_treatments is None or self.num_levels is None:
            return
        for r in range(2, self.num_treatments + 2):
            for c in range(1, self.num_levels + 1):
                item = self.grid.itemAtPosition(r, c)
                item.widget().setReadOnly(readOnly)
                style = self.entryCountReadOnly if readOnly else self.entryCount
                item.widget().setStyleSheet(style)

    def set_counts(self, cur_count):
        if self.num_treatments is None or self.num_levels is None:
            return
        for r in range(2, self.num_treatments + 2):
            for c in range(1, self.num_levels + 1):
                item = self.grid.itemAtPosition(r, c)
                key = self.left_top_key[(r, c)]
                item.widget().setText(str(cur_count[key]))
        self.valid_counts(self.extract_counts())

    def build(self):
        for i in reversed(range(self.grid.count())):
            self.grid.itemAt(i).widget().setParent(None)
        factors = self.database.read_factors(self.trial_id)
        if len(factors) < 1:
            return
        treatments = self.database.read_treatments(self.trial_id)
        self.num_treatments = len(treatments)
        if len(treatments) < 2:
            return
        flc = self.database.get_factor_level(self.trial_id)
        for lvs in flc:
            if len(lvs) < 2:
                return
        self.left_top_key = {}
        offset = 1
        self.total_factorButtons = []
        self.total_level_button = []
        fixedStyle = 'background-color: #EEEEEE; color: #000000; border: 1px solid #000000;'
        self.entryCountReadOnly = 'color: #999999; border: 1px solid #000000;'
        self.entryCount = 'color: blue; border: 1px solid #000000;'
        for i in range(len(factors)):
            factor = factors[i]
            factor_button = qtw.QLabel(factor[1])
            factor_button.setStyleSheet(fixedStyle)
            factor_button.setAlignment(qtc.Qt.AlignCenter)
            if i > 0:
                offset += len(flc[i - 1])
            self.grid.addWidget(factor_button, 0, offset, 1, len(flc[i]))
            total_factorButton = qtw.QLabel('0')
            total_factorButton.setAlignment(qtc.Qt.AlignCenter)
            self.total_factorButtons.append(total_factorButton)
            total_factorButton.setStyleSheet(fixedStyle)
            self.grid.addWidget(total_factorButton, len(treatments) + 3, offset, 1, len(flc[i]))
            level_button_list = []
            for j in range(len(flc[i])):
                level = flc[i][j]
                level_button = qtw.QLabel(level[1])
                level_button.setAlignment(qtc.Qt.AlignCenter)
                level_button.setStyleSheet(fixedStyle)
                self.grid.addWidget(level_button, 1, offset + j, 1, 1)
                total_level_button = qtw.QLabel('0')
                total_level_button.setAlignment(qtc.Qt.AlignCenter)
                level_button_list.append(total_level_button)
                total_level_button.setStyleSheet(fixedStyle)
                self.grid.addWidget(total_level_button, len(treatments) + 2, offset + j, 1, 1)
                for x in range(len(treatments)):
                    treatment = treatments[x]
                    cell_entry = qtw.QLineEdit()
                    cell_entry.setMinimumHeight(50)
                    cell_entry.setStyleSheet(self.entryCountReadOnly)
                    cell_entry.setText('0')
                    cell_entry.setAlignment(qtc.Qt.AlignCenter)
                    cell_entry.setReadOnly(True)
                    self.grid.addWidget(cell_entry, x + 2, offset + j, 1, 1)
                    self.left_top_key[(x + 2, offset + j)] = (treatment[0], factor[0], level[0])
            self.total_level_button.append(level_button_list)
        total_button = qtw.QLabel(self.parent.tr('Total'))
        total_button.setAlignment(qtc.Qt.AlignCenter)
        total_button.setStyleSheet(fixedStyle)
        offset += len(flc[-1])
        self.num_levels = offset - 1
        self.grid.addWidget(total_button, 0, offset + 2, 2, 1)
        self.total_treatment_buttons = []
        for i in range(len(treatments)):
            treatment = treatments[i]
            treatment_button = qtw.QLabel(treatment[1])
            treatment_button.setStyleSheet(fixedStyle)
            self.grid.addWidget(treatment_button, i + 2, 0, 1, 1)
            total_treatment_button = qtw.QLabel('0')
            total_treatment_button.setAlignment(qtc.Qt.AlignCenter)
            self.total_treatment_buttons.append(total_treatment_button)
            total_treatment_button.setStyleSheet(fixedStyle)
            total_treatment_button.setMinimumWidth(100)
            self.grid.addWidget(total_treatment_button, i + 2, offset + 2, 1, 1)
        total_button = qtw.QLabel(self.parent.tr('Total'))
        total_button.setStyleSheet(fixedStyle)
        self.grid.addWidget(total_button, len(treatments) + 2, 0, 2, 1)
        self.grand_total_button = qtw.QLabel('0')
        self.grand_total_button.setAlignment(qtc.Qt.AlignCenter)
        self.grand_total_button.setStyleSheet(fixedStyle)
        self.grid.addWidget(self.grand_total_button, len(treatments) + 2, offset + 2, 2, 1)
        self.valid_preload_image = qtw.QLabel()
        self.grid.addWidget(self.valid_preload_image, 0, 0, 2, 1)
