from   tray.tray       import   tray # 
import json
from datetime import datetime
import re
import unidecode

class cialimp(tray):
    
    
    def format_rote_sincronizar_products(self, rote):
        return "products"
    
    def afterGet_sincronizar_products(self, data):
        # 'https://www.sommalimp.com.br/web_api/products?access_token=APP_ID-2427-STORE_ID-1397150-67e15e4cc3fe5eec0b2abf6e8050e01b49cded75de90ec66873d4892c6bf2227'
        page = 2
        products = data['Products']
        searchMoreProducts = True

        while searchMoreProducts:
            moreProducts = self.tray_request.doRequest(rote=f"products?page={page}")

            if moreProducts.ok:
                moreProducts = moreProducts.json()

                products.extend(moreProducts['Products'])

                if len(moreProducts['Products']) > 0:
                    page += 1
                else:
                    searchMoreProducts = False

        return products
    
    def sincronizar_products_handler(self, products):
        products_softdib = self.select(f"SELECT * FROM TBPRODUTO WHERE CDEMPRESA IN ({int(self.cdempresa)}, 0) AND CDFILIAL IN ({int(self.cdfilial)}, 0)")

        for product in products_softdib:
            # Preciso de uma função usando lambda que eu consiga dentro de products achar o produto que contenha o CDPRODUTO no products[index]['Product']['reference'] 
            print("Verificando se o produto existe na Tray...")
            print(product['CDPRODUTO'])

            existProduct = next((p for p in products if product['CDPRODUTO'] in p['Product']['reference']), None)
            
            if not existProduct:
                self.createLog(404, f"Produto {product['CDPRODUTO']} não encontrado na Tray.")
                continue

            checkExistInRelatement = self.select(f"SELECT * FROM TBRELACIONAID WHERE NMNOMEAPI = 'tray' AND NMTABELA = 'TBPRODUTO' AND IDSOFTDIB = {product['CDPRODUTO']} AND IDAPI = {existProduct['Product']['id']}")

            if not checkExistInRelatement and existProduct:
                self.relatement({
                    "NMNOMEAPI"         : "tray",
                    "NMTABELA"          : "TBPRODUTO",
                    "IDAPI"             : existProduct['Product']['id'],
                    "IDSOFTDIB"         : product['CDPRODUTO'],
                    "DTULTIMAALTERACAO" : datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                    "HASHMD5"           : "INTEGRADO"
                })

                self.createLog(201, f"Produto {product['CDPRODUTO']} integrado com sucesso. ID Tray: {existProduct['Product']['id']}")
            elif checkExistInRelatement:
                self.createLog(200, f"Produto {product['CDPRODUTO']} já está integrado. ID Tray: {existProduct['Product']['id']}")
            else:
                self.createLog(404, f"Produto {product['CDPRODUTO']} não encontrado na Tray.")

    def format_rote_sincronizar_categories(self, rote):
        return "categories"
    
    def afterGet_sincronizar_categories(self, data):
        # 'https://www.sommalimp.com.br/web_api/categories?access_token=APP_ID-2427-STORE_ID-1397150-67e15e4cc3fe5eec0b2abf6e8050e01b49cded75de90ec66873d4892c6bf2227'
        page = 2
        categories = data['Categories']
        searchMoreCategories = True

        while searchMoreCategories:
            moreCategories = self.tray_request.doRequest(rote=f"categories?page={page}")

            if moreCategories.ok:
                moreCategories = moreCategories.json()

                categories.extend(moreCategories['Categories'])

                if len(moreCategories['Categories']) > 0:
                    page += 1
                else:
                    searchMoreCategories = False

        return categories
    
    
    def sincronizar_categories_handler(self, categories):    
        categories_softdib = self.select(f"SELECT * FROM TBGRUPO WHERE CDEMPRESA IN ({int(self.cdempresa)}, 0) AND CDFILIAL IN ({int(self.cdfilial)}, 0)")

        def categoria_na_string(string, valor_procurado):
            # Padronizando a expressão regular para buscar o valor específico
            regex = r'\b' + re.escape(valor_procurado) + r'\b'
            # Procurando por correspondências na string
            correspondencias = re.findall(regex, string)
            
            return bool(correspondencias) 
        
        for category_softdib in categories_softdib:
            grupo = category_softdib['CDGRUPO']
            subgrupo = category_softdib['CDSUBGRUPO']

            softdib_id = f"{grupo}.{subgrupo}"
            
            category = list(filter(lambda obj: categoria_na_string(obj.get('Category')['small_description'], softdib_id), categories))

            if not category:
                self.createLog(404, f"Categoria {softdib_id} não encontrada na Tray.")
                continue

            category_id = category[0].get('Category').get('id')

            checkExistInRelatement = self.select(f"SELECT * FROM TBRELACIONAID WHERE NMNOMEAPI = 'tray' AND NMTABELA = 'TBGRUPO' AND IDSOFTDIB = '{softdib_id}' AND IDAPI = {category_id}")

            if not checkExistInRelatement and category:
                self.relatement({
                    "NMNOMEAPI"         : "tray",
                    "NMTABELA"          : "TBGRUPO",
                    "IDAPI"             : category_id,
                    "IDSOFTDIB"         : softdib_id,
                    "DTULTIMAALTERACAO" : datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                    "HASHMD5"           : "INTEGRADO"
                })

                self.createLog(201, f"Categoria {softdib_id} integrada com sucesso. ID Tray: {category_id}")
            elif checkExistInRelatement:
                self.createLog(200, f"Categoria {softdib_id} já está integrada. ID Tray: {category_id}")
            else:
                self.createLog(404, f"Categoria {softdib_id} não encontrada na Tray.")

    def beforeSend_categories(self, data):
        if self.current_method == "PUT":
            self.ignore_request = True
            self.createLog(201, "Categoria não pode ser atualizada na Tray. Operação ignorada.")

    def beforeSend_products(self, data):   
        if self.current_method == "PUT":
            # Para a CIA Limp só é permitido atualizar estoque e preço dos produtos (até o momento)
            
            data = {
                "Product": {
                    "stock": data['Product']['stock'],
                    "price": data['Product']['price']
                }
            }

            # Se o preço estiver vazio, remove o campo para evitar erro na API
            if data['Product']['price'] == '':
                del data['Product']['price'] 
            
            return data
        
    def send_handler(self, data) :
        """
            Metodo para manipular o envio
        """
        
        # o data pode ser alterado aqui dentro
        self.prepare_send(data)
        
        # Faz um tratamento no dados antes de enviar
        func_rote = self.fixed_rote()
        func = f"beforeSend_{func_rote}"#.format(func_rote)
        # Tratamento de dados antes de enviar
        beforeSend = self.call(func, data, is_required= self.atualWs.get('need_beforeSend',False))

        #if self.hasAttr(func, self) :
        #    data = getattr(self, func)( data )
        #print("stop")
        if hasattr(self, 'ignore_request') and self.ignore_request == True:
            self.ignore_request = False
            return
        
        if beforeSend is not None:
            data = beforeSend
        
        self.send( data )
        
        # Executa apoas enviar - cada rota tem a sua especifica - deve-se criar dentro da arquivo da api
        
        if not self.atualWs['send'] or self.send_response.status_code in range(200,300) :
            func = f"afterSend_{func_rote}"#format(func_rote)
            # Tratamento de dados depois de enviar
            #if self.hasAttr(func, self) :
            #    getattr(self, func)( data )
            self.call(func, data )
            
        self.current_data = {}

    def consultar_tid(self, value):
        try:
            if "PagBank" in self.current_order['Payment'][0]['Payment']['method']:
                nsu = self.current_order['Payment'][0]['Payment']['note'].split("|") 
                return nsu[4].strip()
            else:
                return self.current_order['Payment'][0]['Payment']['unique_number']
            
        except Exception as e:
            return ''
        
    def cdproduto_cialimp(self, value, item):
        import re
        
        return re.sub(r'\D', '', value)
    
    def shipment_transp(self, value):
        if "JADLOG" in value.upper():
            return "T00063"
        elif "CORREIOS" in value.upper():
            return "T00064"

        return value
    
    def payment_code(self, value):
        value = unidecode.unidecode(value)
        cond_pgto = {}
        if value:
            parcelas = int(self.current_order.get('installment',0))
            if parcelas and parcelas > 1:
                value = f"{value} {parcelas}X"
                
            value = value.strip().upper()
            
            cond_pgto = self.getDb().simple_select(
                    fields      = ["CDCONDPGTO"]
                ,   table       = "TBCONDPGTO"
                ,   where       = [f"DSCONDPGTO ='{value}'"]
                ,   onlyFirst   = True
            )
        
        return cond_pgto.get('CDCONDPGTO', '')
    
    def rote_filter_orders(self):
        
        sql =  """
            SELECT 
                DTULTIMAALTERACAO 
            FROM 
                TBRELACIONAID
            WHERE 
                1=1 
            AND 
                NMTABELA = '{table}'
            ORDER BY 
                DTULTIMAALTERACAO DESC 
            LIMIT 1;
        """.format(table=self.atualWs['table'])
        
        date = self.getDb().select(sql)
        
        if date:
            alterado_apos = date[0]['DTULTIMAALTERACAO']
        else :
            alterado_apos = "1980-01-01" 
        
        return  self.mountRouteParams({}
            #{}
            #{"status" : "Aguardando envio","modified": alterado_apos } # Padrão
            # {"status" : "A enviar", "modified": alterado_apos } # CIA LIMP testes
            #{"status" : "A ENVIAR" }
            #{"id" : 33   }
        )