from   bling.bling       import   bling # 
import traceback
from  generic.gn_request  import Request
import json, datetime, re


class papapa(bling):
    def depositos_handler(self, depositos):
        saida_cobol = ""

        if len(depositos) > 0:
            #id_geral = next((deposito["id"] for deposito in depositos if deposito["descricao"] == "Amplo - Geral"), None)
            id_geral = next((deposito["id"] for deposito in depositos if deposito["descricao"] == self.DepositoPadrao), None)
            

            saida_cobol = "OK||{}".format(id_geral)
        else:
            saida_cobol = "ER|Nenhum depósito encontrado"

        with open(self.saida_cobol, 'w') as file:
            
            file.write(saida_cobol)

    def pedidos_handler(self, data) :
        self.formas_pagamentos = self.get_formas_pagamento()

        """Funcao para manipular os dados vim do GET de pedidos de todas as integraçoes
            - Ela grava os dados dos pedidos no sistema Softdib
        Args:
            data (dict): []
        """        

        data = list(reversed(data))

        bugfix_cliente = False
        notas = None

        if self.rote_data and 'params' in self.rote_data and 'notas' in self.rote_data['params']:
            bugfix_cliente = True
            notas = self.rote_data['params']['notas']

        #for order in filter(lambda order: order['id'] in [24559916531], data): # - bling
        for order in data:

            code = self.jsonValueByPath(self.atualWs.get('identifier','id'),order)
            
            order_already_exists = self.exists(
                    "IDTBPEDIDOSRETORNO"
                ,   "TBPEDIDOSRETORNO"
                ,   [ 
                        f"CDPEDIDOEXTERNO='{code}'"#.format(order[self.atualWs['identifier']])
                    ,   f"NMAPI='{self.apiName}'"#.format(self.apiName)
                ]
            
            )

            # Bugfix para não criar cliente no Softdib quando for buscar os dados da nota fiscal, pois nesse cenário o cliente já existe e o pedido já existe, então não tem necessidade de criar um novo cliente ou um novo pedido, apenas seguir para próxima iteração do loop.
            if bugfix_cliente and not order_already_exists:
                continue
            
            if order_already_exists:
                # Mesmo o pedido existindo se o bugfix_cliente estiver ativo ele irá continuar o processo para atualizar os dados da nota fiscal, caso contrário ele irá pular para próxima iteração do loop.
                if not bugfix_cliente:
                    continue
            
            order_to_send   = dict()
            try:
                self.current_order = order
                # Ira extrair dodos os dados referente a pedidos e aos items
                # Ele extrai os valores relacionado ao que foi definido no map
                order_to_send['pedido'       ]  = self.call("get_order_data" , self.current_order, is_required = True) #[ self.extractValues(order, 'pedido_fields') ]

                if not order_to_send['pedido']:
                    continue

                # status, tid, nsu = self.status_paid(self.current_order)

                # if status == 'paid':
                # metodo_pagamento = self.jsonValueByPath("pagamentos/0/forma_pagamento/codigo", self.current_order)

                parcelas = self.current_order.get('data', {}).get('parcelas', [])

                if len(parcelas) > 0:
                    observacoes = self.current_order['data'].get('parcelas', [])[0].get('observacoes', '')

                    numero = re.search(r"Número do Pedido:\s*(\d+)", observacoes)

                    if numero:
                        # T1385143 - Número do pedido no lugar dos campos NSU e TID
                        order_to_send['pedido'][0]['NSU'] = numero.group(1) # nsu
                        order_to_send['pedido'][0]['TID'] = numero.group(1) # tid

                # Existe um tratamento no Ideris, que se o pedido for Mercado Livre e o tipo for igual a FULL ele não irá importar o pedido
                if order_to_send['pedido'       ][0]['CDFRETE'] == 0:
                    continue
            
                order_to_send['itenscarrinho']  = self.call("get_order_items", self.current_order, is_required = True) 
                order_to_send['volumes']        = self.call("get_order_volumes", self.current_order, is_required = False) 
                order_to_send['nota_fiscal']    = self.call("get_order_nf", self.current_order, is_required = False) 
                # order_to_send['etiquetas']      = self.call("get_order_etiquetas", self.current_order, is_required = False) 

                # if not order_to_send['etiquetas']:
                #     continue
                
                #continue 
                # funcao para verificar se o codigo do cliente existe no sistema softdib
                if len( order_to_send['pedido'] ) and ( not order_to_send['pedido'][0]['CDCLIENTE']  or self.atualWs.get('alwaysUpdateClient')):

                    if bugfix_cliente and len(order_to_send['nota_fiscal']):
                        nro_nota = order_to_send['nota_fiscal'][0]['NRONOTA']
                        nro_nota = str(int(nro_nota))

                        if notas and nro_nota in notas:
                            print("Achamos um pedido com nota para ser verificado: {}".format(nro_nota))
                            cli_data, = order_to_send['pedido']
                            customer_data = self.call('customer_data', cli_data)

                            get_cdclient = self.select(f"SELECT CDCLIENTE FROM TBPEDIDOSRETORNO WHERE CDPEDIDO = '{nro_nota}' AND NMAPI = 'bling' AND CDEMPRESA = '{int(self.cdempresa)}' AND CDFILIAL = '{int(self.cdfilial)}'")

                            if get_cdclient and len(get_cdclient) > 0:
                                customer_data['ANT_CDCLIENTE'] = get_cdclient[0]['CDCLIENTE']
                            else: 
                                continue

                            order_to_send['pedido'][0]['CDCLIENTE'] = self.salvar_cliente_softdib(customer_data or cli_data)

                        else:
                            print('Parando o código para não criar cliente no Softdib, pois o pedido já existe e o bugfix_cliente está ativo')
                            continue

                        print('Parando o código para não criar cliente no Softdib, pois o pedido já existe e o bugfix_cliente está ativo')
                        continue
                    

                    cli_data, = order_to_send['pedido']
                    #cli_data['IDCLIENTEEXTERNO'] = ''
                    #if self.hasAttr("customer_data", self) :
                        # Funcao para recuperar os dados do cliente caso nao venha os dados completo para cadastro e recuperar id do cliente
                        #data = getattr(self, "customer_data")( data )
                    #else :
                    customer_data = self.call('customer_data', cli_data)
                    order_to_send['pedido'][0]['CDCLIENTE'] = self.salvar_cliente_softdib(customer_data or cli_data)

                if not len(order_to_send['nota_fiscal']):
                    continue

                order_to_send['pedido'][0]['NRONF'] = order_to_send['nota_fiscal'][0]['NRONOTA'] or "0"
                order_to_send['pedido'][0]['SERIENF'] = order_to_send['nota_fiscal'][0]['SERIENOTA'] or ""
                    
                    
                self.salvar_pedido_softdib(order_to_send)
                    
            except ZeroDivisionError:
                print(traceback.format_exc())        
            # except Exception as error:
            #     self.createLog("999", str(error))
            #     continue
                #print(error)
                
            
            
            # Limpa a variavel
            self.current_order = {}

    def salvar_pedido_softdib(self, data) :
        """ 
            Metodo para salvar pedidos na softdib
        
        """
        pedido, =  data['pedido'] 
        
        self.createLog('001',f"Inicio da gravacao do pedido: {pedido.get('IDTBPEDIDO','')}")
        
        
        response = self.softdib_request.doRequest(
                rote    = "/integracao/pedido/pedido"
            ,   data    = json.dumps(data)
            ,   method  = "POST"
        )
        
        retorno_cobol = self.tryJson(response)

        if response.status_code != 200 and retorno_cobol :
            self.createLog( response.status_code, retorno_cobol ) 
            return False
            
        
        # Mesmo salvo o cobol pode retornar vazio
        # Sempre verificar o save_status, criar o deletar status 
        if retorno_cobol :
            # Geralmente ocorra o UPDATE pois o Cobol ja salva esses dados
            
            dtulitmaalteracao = self.call("dateLastChanges") or pedido.get('DTULTIMAALTERACAO') or 'now()'
            #if self.hasattr("dateLastChanges", self) :
            #    retorno_cobol[-1]['DTULITMAALTERACAO'] = self.dateLastChanges()
                
            #dtulitmaalteracao = retorno_cobol[-1].get('DTULITMAALTERACAO')
            dataFields = {
                    "NMNOMEAPI"         : self.apiName                          
                ,   "NMTABELA"          : "TBPEDIDOSRETORNO"                     
                ,   "IDAPI"             : retorno_cobol[0]['CDPEDIDOEXTERNO']     
                ,   "IDSOFTDIB"         : str(retorno_cobol[0]['CDEMPRESA']) +"-"+ str(retorno_cobol[0]['CDFILIAL']) +"-"+str(retorno_cobol[0]['CDPEDIDO'])     
                ,   "DTULTIMAALTERACAO" : dtulitmaalteracao                       
                ,   "HASHMD5"           : "NFE_PEDIDO"
            }

            # Exibir ID Pedido | ID Softdib
            # print("{}=>{}".format(dataFields['IDAPI'], dataFields['IDSOFTDIB']))

            self.relatement(dataFields)
            return True

    # def relatement(self, data):
        
    #     cond_params = [
    #                 f"NMTABELA   = '{data.get('NMTABELA'  )}'" # .format(table   = data['NMTABELA'  ])
    #             ,   f"IDAPI      = '{data.get('IDAPI'     )}'" #.format(id_api  = data['IDAPI'     ])
    #             ,   f"IDSOFTDIB  = '{data.get('IDSOFTDIB' )}'" # .format(id_sd   = data['IDSOFTDIB' ])
    #             ,   f"NMNOMEAPI  = '{data.get('NMNOMEAPI' )}'"
    #         ]
        
    #     exists = self.exists("IDAPI", "TBRELACIONAID", cond_params)
        
    #     #table = self.atualWs['table'] if not 'alias' in self.atualWs else self.atualWs['alias']
    #     if not exists :
            
    #         #dataFields['IDAPI'] = idapi
    #         self.getDb().insert( "TBRELACIONAID", data)
            
    #     else:
    #         query = self.getDb().update( "TBRELACIONAID", data, cond_params)
    #         #print(f"{query[0]._result.message}")
    #         #self.createLog(200, f"{query[0]._result.message}")
            
       

    def get_order_nf(self, order_nf):
        import requests

        if self.rote_data and 'params' in self.rote_data and 'upload' in self.rote_data['params']:
            pasta_salvar_nfe = self.rote_data['params']['upload']

            order_nf = order_nf['data']
            notaFiscal = order_nf.get('notaFiscal', {})

            if not notaFiscal or notaFiscal.get('id') == 0:
                return []
            
            notaFiscal = notaFiscal.get('id', '')

            dadosNotaFiscal = self.bling_request.doRequest(rote=f"nfe/{notaFiscal}")

            if dadosNotaFiscal.status_code != 200:
                return []
            
            dadosNotaFiscal = dadosNotaFiscal.json().get('data', {})
            xml_nota = dadosNotaFiscal.get('xml', '')
            
            if not xml_nota:
               return []
           
            nro_nota = dadosNotaFiscal.get('numero', '0')
            serie_nota = dadosNotaFiscal.get('serie', '')
            
            xml_nota = requests.get(xml_nota)
                    
            arquivo = "{}_{}-nfe.xml".format(order_nf['loja']['id'], dadosNotaFiscal.get('chaveAcesso', ''))
            arquivo_saida = "{}/{}".format(pasta_salvar_nfe, arquivo)
                                             
            with open(arquivo_saida, 'wb') as file:
                file.write(xml_nota.content)

            return [ self.extractValues({
                "arquivo": arquivo,
                "caminho": pasta_salvar_nfe,
                "nro_nota": nro_nota,
                "serie_nota": serie_nota
                
            }, "nfe_fields")]
        else:
            return []
    
    def rote_filter_pedidos_vendas(self):
        
        sql =  """
            SELECT 
                DTULTIMAALTERACAO 
            FROM 
                TBRELACIONAID
            WHERE 
                1=1 
            AND 
                NMTABELA = '{table}'
            AND 
                NMNOMEAPI = 'bling'
            ORDER BY 
                DTULTIMAALTERACAO DESC 
            
            LIMIT 1;
        """.format(table=self.atualWs['table'])
        
        fetch = self.getDb().select(sql)
        
        if len(fetch) :
            alterado_apos = fetch[0]['DTULTIMAALTERACAO']
            alterado_apos = (alterado_apos - datetime.timedelta(seconds=1)).strftime("%Y-%m-%d")
        else :
            alterado_apos = "2025-10-01"
            
        #self.createLog("000",alterado_apos)

        alterado_apos = '2026-03-18' # Forçar pegar todos os pedidos a partir de 01/10/2025

        return  self.mountRouteParams(
            {
                    #"idsSituacoes[]" : '21' # Em digitacao
                     "idsSituacoes[0]" : '15' # Em andamento
                 ,    "idsSituacoes[1]" : '468475' # eship - coletado
                 ,    "idsSituacoes[2]" : '468474' # eship - ag coleta
                 ,    "idsSituacoes[3]" : '22549' # ecommerce - nf gerada
                 ,    "idsSituacoes[4]" : '6' # autorizada
                    
                 #,   "numero": "149361" # Teste
                 ,   "dataAlteracaoInicial" : f"{alterado_apos}"
                 ,   "dataAlteracaoFinal" :  datetime.datetime.now().strftime("%Y-%m-%d")
                 ,   "dataInicial" : f"{alterado_apos}"
                 ,   "dataFinal" :  datetime.datetime.now().strftime("%Y-%m-%d")

            }
        )
    
    def get_formas_pagamento(self):
        req = self.bling_request.doRequest(rote="formas-pagamentos")

        if req.status_code == 200:
            return req.json().get('data', [])
    
    def define_sd_request(self,rota='/integracao/pedido/authentication'):
        """ 
            Monta a estrutura base de headers e paramentros para consumir ou enivar dados para api softdib
        """
        
        prot = "http://"
        base = "192.168.1.3" if self.debug else self.softdib_ip
        port = f':{self.softdib_port or 3000}'#.format()
        base_url = f"{prot}{base}{port}"
        #""" .format(
        #            prot=prot
        #        ,   base=base
        #        ,   port=port
        #) """

        user = ""

        if int(self.cdempresa) == 1 and int(self.cdfilial) == 1:
            user = "DIBAPI"
        elif int(self.cdempresa) == 1 and int(self.cdfilial) == 2:
            user = "SACFIL"

        auth = Request(
            base_url  =   base_url 
        )
        auth_res = auth.doRequest(
            rote  = rota,
            method  =   "post", 
            json    =
            {
                    #"user"      : "SACFIL" # Exclusivo para integração com o sistema Softdib - PAPAPA
                    "user"      : user # Exclusivo para integração com o sistema Softdib - PAPAPA
                ,   "lkgp"      : self.nmlkgrupo
                ,   "banco"     : self.nmbanco
                ,   "apiname"   : self.apiName 
            } 
        )
        
        if auth_res.status_code != 200 :
            print('Falha ao autenticar na Softdib')
            print(f"Falhou: {auth_res.status_code} - {auth_res.text} - {auth_res.reason}")#.format(auth_res.status_code))
            exit()
            
        
        self.softdib_request = Request(
            base_url = base_url,
            headers = {
                "Content-Type": "application/json"
                ,"Accept": "application/json"
                ,"x-access-token": auth_res.text.replace('"','')
            }
        )
        print(self.softdib_request)
        