from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot

import math
import logging

from sql.models import Category
from sql import get_current_competiton


logger = logging.getLogger('results')


class CategoryResults(QObject):

    signalUpdate = pyqtSignal(list)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pending_third = None

    @pyqtSlot(object)
    def update(self, category):
        keys, count = self.buildKeys(category)
        columns = math.ceil(count / 8) + 3
        self.buildIndexes(columns)
        self.pending_third = None

        #print(f"records {count} | columns {columns}")
        first = self.getKeysByColumn(keys, columns - 1)[0]
        if not first:
            self.__emit(None, None, None, None)
            return

        seconds = self.getKeysByColumn(keys, columns - 2)
        second = self.filterKeys(seconds, [first])[0]
        if not second:
            self.__emit(first, None, None, None)
            return
        
        third = keys.get(-1, None)
        fourth = None
        fourths = self.getKeysByColumn(keys, columns - 3, records_only=True)
        if not third:
            if len(fourths) == 2:
                third = self.filterKeys(fourths, seconds)[0]
            elif len(fourths) == 4:
                # -- If no second third is enabled, then have to fight for the third place
                # -- otherwise just pick the two members and use then as third and fourth
                competition = get_current_competiton()
                if not competition.enable_4:
                    self.pending_third = self.filterKeys(fourths, seconds)
                else:
                    third, fourth = self.filterKeys(fourths, seconds)
        else:
            fourth = self.filterKeys(fourths, seconds + [third])[0]
        self.__emit(first, second, third, fourth)
        logger.debug("%s | %s | %s | %s" % (repr(first), repr(second), repr(third), repr(fourth)))

    def __emit(self, *args):
        self.positions = args
        self.signalUpdate.emit(list(args))
        
    def filterKeys(self, items, skips):
        ignores = [i.item_id for i in skips if i]
        rc = [i for i in items if (i and i.item_id not in ignores)]
        return rc if rc else [None]

    def getKeysByColumn(self, keys, column, records_only=False):
        return [
            keys.get(i, None) for i in self.column_indexes[column]
            if (not records_only or i in keys)
        ]

    def buildIndexes(self, columns):
        indexes = {}
        current = 0
        for i in range(columns - 1, -1, -1):
            count = 2 ** i
            indexes[columns - 1 - i] = [(x + current) for x in range(0, count)]
            current += count
        self.column_indexes = indexes

    def buildKeys(self, category):
        keys = {}
        records = category.groups if category.grouped else category.members
        for k in category.fights + records:
            keys[k.index] = k
        return keys, len(records)
