"""
/***************************************************************************
                                 A QGIS plugin
 Набор инструментов для работы с материалами документации территориального планирования
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                             -------------------
        begin                : 2024-03-18
        git sha              : $Format:%H$
        copyright            : (C) 2024 by I.Bukharin/Mirproekt
        email                : iabukharin@gmail.com
 ***************************************************************************/
 Функции создания слоев
"""

from qgis.PyQt.QtCore import QVariant
from qgis.core import QgsCoordinateReferenceSystem, QgsVectorLayer, QgsField, QgsProject, QgsLayerTreeGroup, QgsLayerTreeNode, QgsMapLayer
import json

def move_to_group(thing, group, pos=0, expanded=False):
    tree_root = QgsProject.instance().layerTreeRoot()
    node_object = None

    # 1. Поиск или создание узла (Node) для перемещения
    if isinstance(thing, str):
        # Сначала ищем как группу, потом как слой по ID
        node_object = tree_root.findGroup(thing) or tree_root.findLayer(thing)
    elif isinstance(thing, QgsMapLayer):
        node_object = tree_root.findLayer(thing.id())
        if not node_object:
            # Если слоя нет в дереве, добавляем его в проект
            QgsProject.instance().addMapLayer(thing, False)
            node_object = tree_root.addLayer(thing)
    elif isinstance(thing, QgsLayerTreeNode):
        node_object = thing

    if not node_object:
        return None, None

    # 2. Поиск или создание целевой группы
    if isinstance(group, QgsLayerTreeGroup):
        group_object = group
    else:
        group_object = tree_root.findGroup(str(group))
        if not group_object:
            # Создаем группу в начале списка, если её нет
            group_object = tree_root.insertGroup(0, str(group))

    # 3. Проверка: не пытаемся ли мы переместить группу в саму себя 
    # (проверка актуальна только если перемещаемый объект сам является группой)
    if node_object == group_object:
        return node_object, group_object
        
    if isinstance(node_object, QgsLayerTreeGroup):
        if node_object.findGroup(group_object.name()):
            # Если целевая группа уже находится внутри перемещаемой — выходим, 
            # чтобы не создать бесконечную рекурсию
            return node_object, group_object

    # 4. Выполнение перемещения через клонирование
    node_clone = node_object.clone()
    node_clone.setExpanded(expanded)
    
    # Вставляем клон в целевую группу
    group_object.insertChildNode(pos, node_clone)
    
    # Удаляем оригинал из старого места
    parent = node_object.parent()
    if parent:
        parent.removeChildNode(node_object)
        
    group_object.setExpanded(expanded)
    
    return node_clone, group_object

def getLayersName(elementTypes, complexTypes, layersNamesForCreate=[]):
    errorLayerNames = []
    layersTypesDict = {}
    # проверка layersNamesForCreate на наличие описания структуры слоя в elementTypes, complexTypes
    if len(layersNamesForCreate) == 0:
        for layerName in elementTypes.keys():
            complexTypesKeysList = list(complexTypes.keys())

            if elementTypes[layerName]['elementType'] in complexTypesKeysList or elementTypes[layerName]['elementType'].replace('fgistp:', '') in complexTypesKeysList:
                layerType = complexTypes.get(elementTypes[layerName]['elementType'],
                                                     elementTypes[layerName]['elementType'].replace('fgistp:', ''))

                geomTypesNum = len(complexTypes[layerType]['geometryTypes'])
                attribsNum = len(complexTypes[layerType]['attributes'])
                if geomTypesNum > 0 and attribsNum > 0:
                    layersNamesForCreate.append(layerName)
                    layersTypesDict[layerName] = layerType
    else:
        for layerName in layersNamesForCreate:
            complexTypesKeysList = list(complexTypes.keys())
            if layerName not in elementTypes.keys():
                errorLayerNames.append(layerName)
                continue
            if elementTypes[layerName]['elementType'] in complexTypesKeysList or elementTypes[layerName]['elementType'].replace('fgistp:', '') in complexTypesKeysList:
                layerType = complexTypes.get(elementTypes[layerName]['elementType'],
                                                     elementTypes[layerName]['elementType'].replace('fgistp:', ''))

                geomTypesNum = len(complexTypes[layerType]['geometryTypes'])
                attribsNum = len(complexTypes[layerType]['attributes'])
                if geomTypesNum > 0 or attribsNum > 0:
                    layersTypesDict[layerName] = layerType
    # удаление наименования слоев для которых нет описания
    for errorLayerName in errorLayerNames:
        layersNamesForCreate.remove(errorLayerName)
    
    return layersTypesDict

def createDPTlayersOrder10(elementTypes, complexTypes, simpleTypes, CRS_for_layers=QgsCoordinateReferenceSystem("EPSG:3857"), baseGeometry=True, layersNamesForCreate=dict()):
    
    layersTypesDict = getLayersName(elementTypes, complexTypes, list(layersNamesForCreate.keys()))

    resultListLayers = []

    for layerName in layersTypesDict.keys():
        layerNameForCreate = layerName
        classType = layersTypesDict[layerName]
        for ind, geomType in enumerate(complexTypes[classType]['geometryTypes']):
            if geomType in ['gml:Polygon', 'gml:Surface']:
                layerGeomType = 'Polygon'
                if 'Polygon' not in layersNamesForCreate.get(layerName, ['Point', 'Point', 'Polygon']):
                    continue
            elif geomType in ['gml:MultiSurface']:
                layerGeomType = 'multipolygon'
                if 'Polygon' not in layersNamesForCreate.get(layerName, ['Point', 'Polyline', 'Polygon']):
                    continue
            elif geomType in ['gml:Curve', 'gml:LineString']:
                layerGeomType = 'LineString'
                if 'Polyline' not in layersNamesForCreate.get(layerName, ['Point', 'Polyline', 'Polygon']):
                    continue
            elif geomType in ['gml:MultiCurve']:
                layerGeomType = 'multilinestring'
                if 'Polyline' not in layersNamesForCreate.get(layerName, ['Point', 'Polyline', 'Polygon']):
                    continue
            elif geomType in ['gml:Point']:
                layerGeomType = 'Point'
                if 'Point' not in layersNamesForCreate.get(layerName, ['Point', 'Polyline', 'Polygon']):
                    continue
            elif geomType in ['gml:MultiPoint']:
                layerGeomType = 'multipoint'
                if 'Point' not in layersNamesForCreate.get(layerName, ['Point', 'Polyline', 'Polygon']):
                    continue
            else:
                continue
            if ind > 0:
                layerNameForCreate = layerName + '_' + layerGeomType
            
            createdLayer = QgsVectorLayer(layerGeomType, layerNameForCreate, "memory")

            layerAttributes = []
            for attributeName in complexTypes[classType]['attributes'].keys():
                attributeComment = complexTypes[classType]['attributes'][attributeName].get('typeUserName', '')
                attributeType = complexTypes[classType]['attributes'][attributeName].get('baseType', '')
                if attributeType in simpleTypes.keys() or attributeType.replace('fgistp:', '') in simpleTypes.keys():
                    attributeType = simpleTypes.get(attributeType,
                                                    simpleTypes[attributeType.replace('fgistp:', '')])['baseType']
                if attributeType in ['fgistp:UUID','fgistp:OKTMO','xs:string']:
                    attributeTypeForCreate = QVariant.String
                elif attributeType == 'xs:double':
                    attributeTypeForCreate = QVariant.Double
                elif attributeType in ['xs:positiveInteger', 'xs:integer']:
                    attributeTypeForCreate = QVariant.Int
                else:
                    print(f'!!!! Error in attribute type layerType:{classType} attribute:{attributeName}')
                    break

                layerAttributes.append(QgsField(attributeName, attributeTypeForCreate, comment=attributeComment))

            createdLayer.dataProvider().addAttributes(layerAttributes)
            createdLayer.updateFields()
            createdLayer.setCrs(CRS_for_layers)
            createdLayer.setTitle(elementTypes[layerName]['typeUserName'])
            resultListLayers.append(createdLayer)
            if baseGeometry and len(layersNamesForCreate) < 1:
                break
    return resultListLayers

    
                        