import FreeCAD as App
import Spreadsheet

from .helper.is_solid import is_object_solid

def createSpreadsheet():

    if App.ActiveDocument.getObject("BoM_List") == None:

        sheet = App.activeDocument().addObject('Spreadsheet::Sheet', 'BoM_List')
        sheet.set('A1', 'п.п.')
        sheet.set('B1', 'Наименование детали')
        sheet.set('C1', 'Количество')
    else:

        sheet = App.ActiveDocument.getObject("BoM_List")
        App.ActiveDocument.BoM_List.clear('A1:ZZ16384')
        sheet.set('A1', 'п.п.')
        sheet.set('B1', 'Наименование детали')
        sheet.set('C1', 'Количество')

    return (sheet)


class SolidBodiesParcer:
    _asmThere = []

    def __init__(self) -> None:
        if (self._asmThere.__len__() == 0):

            self.initParse()
        pass

    def initParse(self):
        for el in App.ActiveDocument.RootObjects:
            if (is_object_solid(el) and hasattr(el, 'Group')):
                self.getSubPartsLink(el.Group, el.Label)

    def getSubPartsLink(self, group, label):
        groupLink = {label: []}
        for el in group:
            if (is_object_solid(el)):
                groupLink[label].append(
                    {'label': el.Label, 'isGroup': hasattr(el, 'Group'), 'solid': el})

        for el in groupLink[label]:
            if ('isGroup' in el):
                if (el['isGroup'] == False):
                    self._asmThere.append(el['solid'].Label)
                if (el['isGroup']):
                    self.getSubPartsLink(el['solid'].Group, el['label']),

        return groupLink


def uniquePartsSort(labelParts):

    uniquePartsLabels = {}

    for el in labelParts:
        for k in labelParts:
            if (App.ActiveDocument.getObjectsByLabel(str(el))[0].Shape.isPartner(App.ActiveDocument.getObjectsByLabel(str(k))[0].Shape)):

                if uniquePartsLabels.get(el) == None:
                    uniquePartsLabels[el] = k

    sortedParts = {}

    for k, v in uniquePartsLabels.items():

        if sortedParts.get(v) == None:
            sortedParts[v] = [k]
        else:
            sortedParts[v].append(k)

    return sortedParts


def countForUniques(sortedParts):
    countedParts = {}
    for k in sortedParts:
        countedParts[k] = len(sortedParts[k])
    return countedParts


def fillInBoMList(sheet, countedParts):

    a = 1

    for label, count in countedParts.items():
        a += 1
        b = label
        c = count
        sheet.set('A' + str(a), str(a-1))
        sheet.set('B' + str(a), str(b))
        sheet.set('C' + str(a), str(c))

    total_count = sum(countedParts.values())
    sheet.set('B'+str(a+1), 'Итого')

    sheet.set('C' + str(a+1), str(total_count))


def run_BoM_list():
    createSpreadsheet()
    sheet = App.ActiveDocument.getObject("BoM_List")
    labelParts = SolidBodiesParcer()._asmThere
    sortedParts = uniquePartsSort(labelParts)
    countedParts = countForUniques(sortedParts)
    fillInBoMList(sheet, countedParts)
