
import re, json
from   generic.gn_api       import   gn_api # 
from   generic.gn_request   import   Request # 
from  datetime              import datetime, timedelta
import base64

class woocommerce(gn_api):
    def __init__(self, argv:list):
        self.db = False
        
        setup   = self.setup(argv)
        
        consumers = "{}:{}".format(
            self.get_token_data('KEY_WOO'),
            self.get_token_data('SECRET_WOO')
        ).encode()

        auth = base64.b64encode(consumers).decode()
        
        #self.ApplicationToken  = setup[0][  'NMTOKEN1API']#002e6fc5f068d6323874
        #self.CompanyToken      = setup[0]['NMTOKEN1DADOS']#b42241b9-0f49-4177-814d-ba3d30883bb3
        self.woocommerce_request = Request(
                base_url = "{}/wp-json/wc/v3/".format(self.get_token_data("URL"))
            ,   headers={
                'Authorization'     : f'Basic {auth}',
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
            }) 
        
        super(woocommerce, self, ).__init__()
        
        print('Fim')
        
    # QUANDO FOR FILTRAR POR PEDIDOS ESPECIFICOS, PRECISA DESATIVAR ESSA FUNÇÃO
    def pagination_rules(self, req, data):
        #'pedidos/?status=2&alterado_apos=2021-07-12 15:41:29'
        alterado_ate = datetime.strftime(datetime.now(),'%Y-%m-%dT%H:%M:%S')
        
        if req.headers._store.get('x-wp-totalpages') and self.rote == 'orders':
            
            last = data[-1]
            params = self.mountRouteParams({
                  "status[0]" : 'completed'
                , "status[1]" : 'processing'
                , "modified_after" : last.get('date_modified','')
                , "modified_before": alterado_ate
                , "per_page" : 20
                , "order" : "asc"
                , "orderby"  : "id"
                

            })
            return f"orders/?{params}"
            
        
        
        return None
    #--------------------------------------------------------#
    #--------------- TRATAMENTO CUSTOM ----------------------#
    #--------------------------------------------------------#
    
    
    #--------------------------------------------------------#
    #--------------- TRATAMENTO CUSTOM SQL  -----------------#
    #--------------------------------------------------------#
    def quantidade_estoque(self, data):
        return "( SELECT IF(TBPRODUTO.NMUNIDADE IN ('MT','M2'), TBPRODUTO.VLQTDEATUAL * 100, TBPRODUTO.VLQTDEATUAL ) )"
        
    def quantidade_em_estoque(self, data):
        return "( SELECT 2 )"
        
    def quantidade_sem_estoque(self, data):
        return "( SELECT IF(TBPRODUTO.VLTEMPOREPOSICAO > 0, TBPRODUTO.VLTEMPOREPOSICAO, -1) )"
        
    
    def valor_produto(self, data):
        field = data.get('dbfield')
        return f"(SELECT IF(TBPRODUTO.NMUNIDADE IN ('MT','M2'), {field} / 100, {field} ) )"
        #if 'VLPROMOCIONAL' in field:
        #    sql = f" (SELECT IF({sql} > 0, {sql}, 'null' ))"
        #    
        #return sql
        
    
    def cliente_tipo(self, field) :
        return """(SELECT IF({}='J', 'PJ', 'PF') )""".format(field['dbfield'])
        
    
    def imagens_produto_principal(self, field) :
        return """(SELECT IF({}='S', 'true', 'false') )""".format(field['dbfield'])
        
    
    def situacao_pedido_pedido_id(self, field) :
        
        pass
        
    
    #--------------------------------------------------------#
    #--------------- TRATAMENTO BEFORESEND  -----------------#
    #--------------------------------------------------------#
    
    def beforeSend_categoria(self, data) :
        
        if self.current_data['sub_grupo'] == 0 :
            data['categoria_pai'] = None
            
        else :
            data['categoria_pai'] = '/api/v1/categoria/' + self.translate(id = data['categoria_pai'], table = "TBGRUPO")
            
            
        
        return data
    
    def beforeSend_products(self, data):
        category_ids = []

        category = self.select("SELECT IDAPI FROM TBRELACIONAID WHERE NMTABELA='TBGRUPO' AND IDSOFTDIB = '{}' AND NMNOMEAPI = '{}'".format(f"{self.current_data['grupo']}.{self.current_data['subgrupo']}", self.apiName))
        
        if category:
            category_ids.append({
                "id": category[0].get('IDAPI')
            })

        data['categories'] = category_ids
        
        if (float(data['stock_quantity']) <= 0):
            data['stock_quantity'] = 0

        print(data)
    
    def beforeSend_products_categories(self, data): 
        if self.current_data['subgrupo'] != 0:
            parent_id = self.select("SELECT IDAPI FROM TBRELACIONAID WHERE NMTABELA='TBGRUPO' AND IDSOFTDIB = '{}' AND NMNOMEAPI = '{}'".format(f"{self.current_data['grupo']}.0", self.apiName))[0].get('IDAPI')
            data['parent'] = parent_id
    
    def beforeSend_cliente(self, data) :
        
        tipo = data['tipo']
        
        if tipo == 'PF' :
            
            data['cnpj'] = None
            data['nome'] = data['razao_social']  
            data['razao_social'] = None
            data['ie'] = None
            
        elif tipo == 'PJ':
            
            data['cpf'] = None
            data['rg'] = None
            
        return data
        
    
    def beforeSend_produto(self, data) :
        
        res = self.api_request.doRequest(
            rote = "produto/?sku={}".format(data.get('sku'))
        )
        
        if res and not res.json().get('objects'):
            return data
        
    
    def before_handle_db_data_(self, data):
        data = []
        print(data)
        return ""
        
    
    #--------------------------------------------------------#
    #------------------ TRATAMENTO RESPONSE  ----------------#
    #--------------------------------------------------------#
    
    def response_code_200(self, req) :
        return super().response_code_201(req)
        
    def response_code_400(self, req) :
        return super().response_code_400(req)
        
        
    #--------------------------------------------------------#
    #--------------- TRATAMENTO FILTROS DE ROTA -------------#
    #--------------------------------------------------------#
    
    def rote_filter_orders(self):
        
        sql =  """
            SELECT 
                DTULTIMAALTERACAO 
            FROM 
                TBRELACIONAID
            WHERE 
                1=1 
            AND 
                NMTABELA = '{table}'
            AND NMNOMEAPI = '{nomeApi}'                
            ORDER BY 
                DTULTIMAALTERACAO DESC 
            LIMIT 1;
        """.format(table=self.atualWs['table'],nomeApi=self.apiName)
        
        fetch = self.getDb().select(sql)
        
        if len(fetch) :
            alterado_apos = fetch[0]['DTULTIMAALTERACAO']
        else :
            alterado_apos = "2024-09-01T00:00:00"
        
        #alterado_apos = "2024-09-01T00:00:00"
            
        alterado_ate = datetime.strftime(datetime.now(),'%Y-%m-%dT%H:%M:%S')
        
        ### return  self.mountRouteParams( { "since_numero": 11776    } )
        #                  "status" : 'completed'
        #                  "status" : 'captured'
        
        return  self.mountRouteParams(
            {
                  "status[0]" : 'completed'
                , "status[1]" : 'processing'
                , "modified_after" : alterado_apos
                , "modified_before": alterado_ate
                , "per_page" : 20
                , "order" : "asc"
                , "orderby"  : "id"
                #,"since_numero": 8840
  
            }
        )
    
    
    #--------------------------------------------------------#
    #---------- TRATAMENTO AFTERSEND  & BEFORESEND ----------#
    #--------------------------------------------------------#
    
    def beforeSend_situacao_pedido_pedido_id(self, data) :
        codigo = data.get('codigo')
        if (codigo and codigo == 'pedido_cancelado') :
            self.atualWs['send'] = False
            
            
        return data
        
    
    def afterSend_situacao_pedido_pedido_id(self, data) :
        
        self.getDb().delete(
                    "TBPEDIDOSSTATUS"
            ,   ["IDTBPEDIDOSSTATUS={}".format(self.current_data['softdib_id'] )]
            )
        codigo = data.get('codigo')
        if (codigo and codigo == 'pedido_cancelado') :
            self.getDb().delete(
                    "TBPEDIDOSRETORNO"
            ,   [
                        "CDPEDIDOEXTERNO={}".format(self.current_data['pedido_id'] )
                    ,   "NMAPI='{}'".format(self.apiName)
                ]
            )
        
    
    #--- ----------------------------------------------------#
    #--------------- TRATAMENTO ITEMS/PEDIDO ----------------#
    #--------------------------------------------------------#
    
    def get_order_items(self, order):
        return [ self.extractValues(item, "itenscarrinho_fields") for item in order.get('line_items',[])]
        
    
    def get_order_data(self, order) :
        
        req = self.woocommerce_request.doRequest(
            rote="orders/{id}".format(id=order['number'])
        )
        
        if req.status_code == 200 :
            self.current_order =  self.tryJson(req)
            return [ self.extractValues(self.current_order, 'pedido_fields') ]
            
        return False
        
    # returne false caso queira sair
    def afterGet_orders_search(self, data) :
        data = data.get('objects')
        return data
    
    def afterGet_orders(self, data):    
        return data
        
    
        
    
    def sku_to_codigo_produto(self, value) :
        # salvo codigo para usar em outras fucoes
        self.codigo_produto = value or '2000000000901'
        
        value =  self.codigo_produto
        
        #code_pieces = self.codigo_produto.split('-')
        # Segundo o suporte sempre que existir um P tera um C no SKU
        # Por isso sempre testamos apenas o c
        
        
        #if (len(code_pieces) > 1 and re.match(r'^([cp]\d{1,3}){1,2}$',code_pieces[-1])):
        #    value = "-".join(code_pieces[:-1])
        value = value.upper()
        return re.sub(r'(-C([2-9]|1[0-2]?)(P([2-9]|1[0-2]?))?)$','',value)
        
    
    def carrinho_quantidade(self, value) :
        value = 0
        if re.match(r'.*-(C([2-9]|1[0]?)(P([2-9]|1[0]?))?)$', self.codigo_produto.upper()):
            value = 100
            
        return str(value)
        
    def only_numbers(self, data):
        return  re.sub(r'[^\d]','',data)
    # Apenas para recuperar o id externo do cliente
    def customer_data(self, data) :

        if self.current_order['customer_id'] == 0:
            data["ENDERECO"      ] = self.current_order['billing'].get("address_1",'')
            data["ENDERECO_NRO"  ] = self.current_order['billing'].get("number",0)
            data["COMPLEMENTO"   ] = self.current_order['billing'].get("address_2",'')
            data["CEP"           ] = self.only_numbers(self.current_order['billing'].get("postcode",''))
            data["BAIRRO"        ] = self.current_order['billing'].get("neighborhood",'')
            data["CIDADE"        ] = self.current_order['billing'].get("city",'')
            data["ESTADO"        ] = self.current_order['billing'].get("state",'')

            return data

        params = {
            "method" : "GET",
            "rote": f"customers/{self.current_order['customer_id']}"
        }
        
        response = self.throttling(**params) 
        if response.ok :
            dados_cliente = response.json()
            #endereco_principal = list(filter(lambda endereco: endereco['principal'],dados_cliente['enderecos']))
            #if(endereco_principal):
            data["ENDERECO"      ] = dados_cliente['billing'].get("address_1",'')
            data["ENDERECO_NRO"  ] = dados_cliente['billing'].get("number",0)
            data["COMPLEMENTO"   ] = dados_cliente['billing'].get("address_2",'')
            data["CEP"           ] = self.only_numbers(dados_cliente['billing'].get("postcode",''))
            data["BAIRRO"        ] = dados_cliente['billing'].get("neighborhood",'')
            data["CIDADE"        ] = dados_cliente['billing'].get("city",'')
            data["ESTADO"        ] = dados_cliente['billing'].get("state",'')
            
            
        #data['IDCLIENTEEXTERNO'] = self.current_order['cliente']['id']
        return data
        
        
    
    def tipo_pessoa(self, value) :
        return self.current_order['billing'].get('persontype') or "F"
        
        
    
    def previsao_entrega_pedido(self, value):
        if value:
            return max(map(lambda v: v.get('disponibilidade', 0), value))
            
        return 2
        
        
        
    
    
    
    #--------------------------------------------------------#
    #------------------- TRATAMENTO GAMARRA -----------------#
    #--------------------------------------------------------#

    def cd_vendedor_gamarra(self, value, item):
        order_source = list(filter(lambda ind: ind['key'] in '_gamarra_order_source' ,  self.current_order['meta_data']))
        gamarra_source = ""
        vendedor = ""

        if order_source != []:
            gamarra_source = order_source[0]['value']

        _url = self.environment_config['tokens']['URL']

        if _url == "https://gamarraoficial.com":
            vendedor = "V10000"

        if _url == "https://cliente.gamarraoficial.com":
            vendedor = "V10001"

            if gamarra_source == "aplicativoGamarra": 
                vendedor = "V10002"

        return vendedor
    
    def razao_social_gamarra(self, value, props):
        return value + ' ' + self.current_order['billing'].get('last_name')
    
    def observacao_gamarra(self, data, props) :
        #print(data)
        return re.sub(r'\r\n',"|",data)
        
    def pagamentos_gamarra(self, value, props) :
        
        forma_pagto     = list(filter(lambda ind: ind['key'] in '_pagarme_payment_method' ,  self.current_order['meta_data']))
        parcelamentos = None
        
        try:
            self.forma_pagamento = forma_pagto[0]['value'] or ""

            if self.forma_pagamento == "credit_card":
                parcelas    = list(filter(lambda ind: ind['key'] in '_pagarme_installments_card1' ,  self.current_order['meta_data']))
                parcelamentos   = parcelas[0]['value'] or 1
        except:
            self.forma_pagamento = self.pagarme_current_order['data'][-1:][0]['last_transaction']['transaction_type']

            if self.forma_pagamento == "credit_card":
                parcelamentos   = self.pagarme_current_order['data'][-1:][0]['last_transaction']['installments']
            
        if self.forma_pagamento == "pix":
           parcelamentos = ''
        
        #if self.cliente_origem :
        #    forma_pagamento = self.cliente_origem
            
        
        dictionary = {
                'pagsegurov2'               : "Cartao Lj Virtual" 
            ,   'paypal'                    : "Paypal" 
            ,   'mercadopago'               : "Mercado Pago" 
            ,   'mercadopagov1'             : "Mercado Pago" 
            ,   'paghiper'                  : "BOLETO PAGHIPER" 
            ,   'pagseguro'                 : "PAGSEGURO" 
            ,   'pagarmev2'                 : "PAGAR.ME" 
            ,   'proxy-pagarme-v4-cartao'   : "PAGAR.ME" 
            ,   'pmboletov2'                : "BOLETO PAGAR.ME" 
            ,   'proxy-pagarme-v4-boleto'   : "BOLETO PAGAR.ME" 
            ,   'shopee'                    : "SHOPEE" 
            ,   'mercadolivre'              : "Mercado Pago" 
            ,   'magalu'                    : "MAGAZINE LUIZA" 
            ,   'americanas'                : "AMERICANAS" 
            ,   'olist'                     : "OLIST" 
            ,   'via'                       : "VIA VAREJO" 
            ,   'pagali-pix'                : "PIX - PAGALI"
            ,   'amazon'                    : "AMAZON"
            ,   'pix'                       : 'PIX'
            ,   'credit_card'               : "CARTAO DE CREDITO"
            
        }
        
        
        _forma_pagamento = dictionary.get(self.forma_pagamento) or ''
        parcelamentos   = " {}X".format(parcelamentos or '1')
        
        # 'BOLETO' in  forma_pagamento or 'SHOPEE' in forma_pagamento or 'PIX' in forma_pagamento  :
        #if forma_pagamento in ['BOLETO', 'VIA VAREJO', 'SHOPEE','PIX','AMERICANAS'] :
        if re.findall(r'(BOLETO|VIA VAREJO|SHOPEE|PIX - PAGALI|AMERICANAS|MAGAZINE LUIZA|OLIST|PIX)', _forma_pagamento):
            parcelamentos = ''
        
        desc_pagamento = f"{_forma_pagamento}{parcelamentos}"
        
        result =  self.getDb().simple_select(
            fields=["CDCONDPGTO"]
            , table="TBCONDPGTO"
            , where=["DSCONDPGTO='{}'".format(desc_pagamento)], onlyFirst=True)
        
        return result.get('CDCONDPGTO','0')
    
    def __nsu_gamarra(self, value, props) :
        
        _nsu    = list(filter(lambda ind: ind['key'] in '_pagarme_response_data' ,  self.current_order['meta_data']))
        
        cpos = json.loads(_nsu[0]['value'])
        
        if self.forma_pagamento == "credit_card":
           nsu   = cpos['charges'][0]['transactions'][0]['acquirerNsu']  or ""       
    
        if self.forma_pagamento == "pix":
           nsu   = cpos['charges'][0]['transactions'][0]['postData'].get('gateway_id')  or ""
    
        return nsu 
    
    def __tid_gamarra(self, value, props) :
        
        _tid    = list(filter(lambda ind: ind['key'] in '_pagarme_response_data' ,  self.current_order['meta_data']))
        
        cpos = json.loads(_tid[0]['value'])
        
        if self.forma_pagamento == "credit_card":
           tid   = cpos['charges'][0]['transactions'][0]['acquirerTid']  or ""       
    
        if self.forma_pagamento == "pix":
           tid   = cpos['charges'][0]['transactions'][0]['pagarmeId'] or ""
    
        # testando com este retorno abaixo, os 2 IFs acima estou mantendo pra depois verificar qual � o correto
        #tid   = cpos['charges'][0]['transactions'][0]['pagarmeId'] or ""
    
        return tid 
    
    
    
    
    
    def forma_envio_frete_gamarra(self, value, props) :
        return "9" if value == "local_pickup" else "1"
        
    
    def envios_gamarra(self, data, props) :
        if not data: return ''
             
        id = data.get('method_id', '')
        
        transportadoras = {
                'correios-cws'                  : 'T00001' # Correios (Nova API)
            ,   'local_pickup'                  : 'T00002' # Retirar no Local
            ,   'free_shipping'                 : 'T00003' # Frete Gratis
            ,   'flat_rate'                     : 'T00004' # Taxa fixa cobrada na entrega
            ,   'correios-cws-international'    : 'T00005' # Correios Internacional (Nova API)
            ,   'correios-carta-registrada'     : 'T00006' # Carta Registrada
            ,   'correios-impresso-normal'      : 'T00007' # Impresso Normal
            ,   'correios-impresso-urgente'     : 'T00008' # Impresso Urgente
            ,   'correios-pac'                  : 'T00009' # PAC (Antigo)
            ,   'correios-sedex'                : 'T00010' # SEDEX (Antigo)
            ,   'correios-sedex10-envelope'     : 'T00011' # SEDEX 10 Envelope (Antigo)
            ,   'correios-sedex10-pacote'       : 'T00012' # SEDEX 10 Pacote (Antigo)
            
        }
        # Procura o codido no dicionario
        _codTransp = transportadoras.get(str(id),0)
        
        if (_codTransp == 0):
            self.createLog("999", "transportadora nao relacionada: {} ".format(data))
            
        
        return _codTransp

    
    
    
    # ---------------------------------------- #
    # ---------------------------------------- #
    # ---------------------------------------- #
    
    def origem_gamarra(self, value, props):
        
        _url = self.environment_config['tokens']['URL']
        
        origem_map = {
             "https://gamarraoficial.com"         : "103"
           , "https://cliente.gamarraoficial.com" : "108"
        }        
        #self.cliente_origem = self.get_origem(_url)
        
        return origem_map.get(_url, '102')
        
    
    
    def get_origem(self, value=''):
        if "@mail.mercadolivre.com" in value or "@mercadolibre.com" in value:
            return 'mercadolivre'
            
        if "@shopee.com.br" in value:
            return 'shopee'
        
        if "@marketplace.amazon.com.br" in value:
            return 'amazon'
        
        if "@alias.integracommerce.com.br" in value:
            return 'magalu'
            
        if "@mktp.extra.com.br" in value:
            return 'via'
            
        if "@olist.com" in value :
            return 'olist'
            
        if "@email.com.br" in value :
            return 'americanas'
            
        return ''
        
    
    
    """ def custom_control_id_produto_estoque_produto_id(self, response):
        response        = self.tryJson(response)
        return response.get('produto', '').split('/')[-1] """
        
        
    # ------------------------------------------------------ #
    # -------------------- HANDLERS ------------------------ #
    # ------------------------------------------------------ #
    
    def customers_handler(self, data):
        return data
    
    
    def custom_control_id(self, response):
        resposta        = self.tryJson(response)
        return resposta.get('id', '')

        
    
    
    def __del__(self):
        self.createLog("999","Final da exportacao")
    
    
    
    
    
    
    
    
    