# -*- coding: utf-8 -*-

"""
Easy_SelectByKeyAtt.py
***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************
"""
__author__ = 'Leandro França'
__date__ = '2024-11-10'
__copyright__ = '(C) 2024, Leandro França'

from qgis.core import *
import numpy as np
from lftools.geocapt.imgs import Imgs
from lftools.geocapt.cartography import LayerIs3D
from lftools.translations.translate import translate
from lftools.geocapt.dip import Interpolar
import os, processing
from qgis.PyQt.QtGui import QIcon

class SelectByKeyAtt(QgsProcessingAlgorithm):

    LOC = QgsApplication.locale()[:2]

    def tr(self, *string):
        return translate(string, self.LOC)

    def createInstance(self):
        return SelectByKeyAtt()

    def name(self):
        return 'SelectByKeyAtt'.lower()

    def displayName(self):
        return self.tr('Select by key attribute', 'Selecionar por atributo chave')

    def group(self):
        return self.tr('Easy', 'Mão na Roda')

    def groupId(self):
        return 'easy'

    def tags(self):
        return 'GeoOne,selecionar,pimary,key,foreing,estrangeira,chave,selected,relação,relation'.split(',')

    def icon(self):
        return QIcon(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images/easy.png'))

    txt_en = '''This tool allows you to select features that share the same foreign key attribute from multiple layers based on the primary key attribute of a selected feature from another layer.
    Note: Enter the foreign key field name if it is not the same as the primary key field name.'''
    txt_pt = '''Esta ferramenta permite selecionar feições que compartilham o mesmo atributo de chave estrangeira de diversas camadas com base no atributo de chave primária de uma feição selecionada de outra camada.
    Nota: Insira o nome do campo de chave estrangeira se não for igual ao nome do campo de chave primária.'''
    figure = 'images/tutorial/easy_selectByKey.jpg'

    def shortHelpString(self):
        social_BW = Imgs().social_BW
        footer = '''<div align="center">
                      <img src="'''+ os.path.join(os.path.dirname(os.path.dirname(__file__)), self.figure) +'''">
                      </div>
                      <div align="right">
                      <p align="right">
                      <b>'''+self.tr('Author: Leandro Franca', 'Autor: Leandro França')+'''</b>
                      </p>'''+ social_BW + '''</div>
                    </div>'''
        return self.tr(self.txt_en, self.txt_pt) + footer

    PRIMARY = 'PRIMARY'
    PRIMARY_FIELD = 'PRIMARY_FIELD'
    FOREIGNS ='FOREIGNS'
    FOREIGNS_FIELD = 'FOREIGNS_FIELD'

    def initAlgorithm(self, config=None):

        # INPUT
        self.addParameter(
            QgsProcessingParameterVectorLayer(
                self.PRIMARY,
                self.tr('Input Layer', 'Camada de entrada'),
                [Qgis.ProcessingSourceType.TypeVectorAnyGeometry]
            )
        )

        self.addParameter(
            QgsProcessingParameterField(
                self.PRIMARY_FIELD,
                self.tr('Primary key', 'Chave primária'),
                parentLayerParameterName = self.PRIMARY
            )
        )

        self.addParameter(
            QgsProcessingParameterMultipleLayers(
                self.FOREIGNS,
                self.tr('Layers', 'Camadas'),
                layerType = Qgis.ProcessingSourceType.TypeVectorAnyGeometry
            )
        )

        self.addParameter(
            QgsProcessingParameterString(
                self.FOREIGNS_FIELD,
                self.tr('Foreign key', 'Chave estrangeira'),
                optional = True
            )
        )


    def processAlgorithm(self, parameters, context, feedback):

        camada = self.parameterAsVectorLayer(
            parameters,
            self.PRIMARY,
            context
        )
        if camada is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.PRIMARY))

        campo = self.parameterAsFields(
            parameters,
            self.PRIMARY_FIELD,
            context
        )
        if campo is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.PRIMARY_FIELD))

        # Verificar se existe apenas uma feição selecionada
        if camada.selectedFeatureCount() != 1:
            raise QgsProcessingException(self.tr('At least one feature must be selected!', 'Pelo menos uma feição deve ser selecionada!'))

        campo_indice_pk = camada.fields().indexFromName(campo[0])
        campo_nome_pk = campo[0]

        layers = self.parameterAsLayerList(
            parameters,
            self.FOREIGNS,
            context
        )

        campo_nome_fk = self.parameterAsString(
            parameters,
            self.FOREIGNS_FIELD,
            context
        )

        if campo_nome_fk is None or campo_nome_fk == '':
            campo_nome_fk = campo_nome_pk

        # Obtendo o atributo chave
        for feat in camada.getSelectedFeatures():
            att = feat[campo_nome_pk]

        # Expressão para seleção
        expressao =  QgsExpression('"{}" = \'{}\''.format(campo_nome_fk, att))

        for layer in layers:
            if campo_nome_fk in [field.name() for field in layer.fields()]:
                ids_selecionados = []
                for feat in layer.getFeatures(QgsFeatureRequest(expressao)):
                    ids_selecionados.append(feat.id())
                layer.selectByIds(ids_selecionados)
            else:
                feedback.pushInfo(self.tr('Layer {} has no key field!', 'A camada {} não possui campo chave!').format(layer.name()))

        feedback.pushInfo(self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!'))
        feedback.pushInfo(self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart'))

        return {}
