# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_core.ipynb.

# %% auto 0
__all__ = ['ConsultaSCR']

# %% ../nbs/00_core.ipynb 3
import os
import json
import requests
import pandas as pd
from typing import Tuple
from pathlib import Path
from datetime import datetime

from .utils import let_only_digits
from .utils import codigos_vencimentos

# %% ../nbs/00_core.ipynb 4
class ConsultaSCR:
    def __init__(self, 
                 user: str = None,     # SCR user
                 password: str = None, # SCR password
                 code: str = None,     # SCR code
                 api_key: str = None  # SCR api key
    ):
        "Class to query SCR"
        self.user = os.environ['SCR_USER'] if user is None else user
        self.password = os.environ['SCR_PASSWORD'] if password is None else password
        self.code = os.environ['SCR_CODE'] if code is None else code
        self.key = os.environ['SCR_API_KEY'] if api_key is None else api_key
        self.headers = {'Content-Type': 'application/json'}
        self.url = "https://bmpdigital.moneyp.com.br/api/BMPDigital/ConsultaSCR"
        self.params = {
            "auth": {
                "Usuario": self.user,
                "Senha": self.password,
                "CodigoParametro": self.code,
                "Chave": self.key
            },
            "consulta": {
                "Documento": "",
                "DataBaseMes": "",
                "DataBaseAno": ""
            }
        }

        self.path_to_store_responses = Path.home() / '.neoscr'
        self.path_to_store_responses.mkdir(parents=True, exist_ok=True)
        
    def _request(self, 
                 doc: str,    # CPF or CNPJ
                 ano: int,    # Year to be consulted. Format: YYYY
                 mes: int     # Month to be consulted. Format: MM
    ) -> requests.models.Response:
        "Make a request to the SCR API"

        ano = str(ano)
        mes = f"{mes:02d}"
        self.params["consulta"]["Documento"] = doc
        self.params["consulta"]["DataBaseAno"] = ano
        self.params["consulta"]["DataBaseMes"] = mes

        # if the request was already made, just load the file from the local home storage folder .neoscr
        response_filepath = self.path_to_store_responses / f"{let_only_digits(doc)}_{ano}_{mes}.json"
        if response_filepath.exists():
            print(f"File already exist, loading it from {response_filepath}")
            with open(response_filepath) as json_file:
                response_json = json.load(json_file)
        else:
            print(f"Making a request to SCR api ...")
            response = requests.request("POST", self.url, data=json.dumps(self.params), headers=self.headers)
            response_json = response.json()
            print(f"Saving the response to the ~/.neoscr folder ...")
            with open(response_filepath, 'w') as file:
                json.dump(response_json, file)
                print('Response saved successfully.')
        return response_json

    def _get_resumo_cliente_traduzido(self, 
                                      response_json: dict, # Response from the SCR API 
                                      **kwargs: dict       # Keyword arguments
    ) -> pd.DataFrame:
        "Return a DataFrame with the translated client summary"

        df = pd.DataFrame(response_json.get("ResumoDoClienteTraduzido"), columns=response_json.get("ResumoDoClienteTraduzido").keys(), index = [0])
        df.insert(0, "doc", kwargs.get("doc"))
        df.insert(1, "data_consulta", kwargs.get("data_consulta"))
        df.insert(2, "mes_referencia", kwargs.get("mes_referencia"))
        df.insert(3, "msg", response_json.get("MensagemOperador"))
        return df


    def _get_resumo_modalidade(self, 
                               response_json: dict, # Response from the SCR API 
                               **kwargs: dict       # Keyword arguments
    ) -> pd.DataFrame:
        "Return a DataFrame with the modalities client summary"

        df = pd.DataFrame(response_json.get("ResumoModalidade"))
        df.insert(0, "doc", kwargs.get("doc"))
        df.insert(1, "data_consulta", kwargs.get("data_consulta"))
        df.insert(2, "mes_referencia", kwargs.get("mes_referencia"))
        return df


    def _get_resumo_lista_das_operacoes(self,
                                        response_json: dict, # Response from the SCR API 
                                        **kwargs: dict       # Keyword arguments
    ) -> pd.DataFrame:
        df_aux = pd.DataFrame(response_json.get('ResumoDoCliente').get('ListaDeResumoDasOperacoes'))
        df_aux_exploded = df_aux.explode('ListaDeVencimentos').reset_index(drop=True)
        df = pd.concat([
                df_aux_exploded[['Modalidade', 'VariacaoCambial']],
                df_aux_exploded['ListaDeVencimentos'].apply(pd.Series)
            ], axis=1)
        df.insert(0, "doc", kwargs.get("doc"))
        df.insert(1, "data_consulta", kwargs.get("data_consulta"))
        df.insert(2, "mes_referencia", kwargs.get("mes_referencia"))
        df = pd.merge(df, codigos_vencimentos, on='CodigoVencimento', how='left').filter([
                                                                                        'doc',
                                                                                        'data_consulta',
                                                                                        'mes_referencia',
                                                                                        'Modalidade',
                                                                                        'VariacaoCambial',
                                                                                        'CodigoVencimento',
                                                                                        'Descrição',
                                                                                        'ValorVencimento',
                                                                                        'ValorVencimentoSpecified'])

        return df


    def get_cpf_data(self, 
                     cpf: str,      # CPF
                     ano: int,      # Year to be consulted. Ex: 2022
                     mes: int       # Month to be consulted. Ex: 8, 10
    ) -> Tuple[pd.DataFrame, pd.DataFrame]:
        "Query CPFs and return a tuple of DataFrames: (df_cpf_resumo_cliente_traduzido, df_cpf_resumo_modalidade)"
        
        data_consulta = datetime.today().strftime("%d/%m/%Y")
        response_json = self._request(cpf, ano, mes)
        if response_json.get("Erro"):
            raise Exception(response_json.get("Msg").strip() + f": {cpf}")
        if response_json.get("MensagemOperador") == '(50) - Cliente não possui dados no SCR na data-base.':
            print(f"Cliente não possui dados no SCR na data-base: {cpf}")
            return pd.DataFrame(), pd.DataFrame(), pd.DataFrame()
        
        df_traduzido = self._get_resumo_cliente_traduzido(response_json, doc=cpf, data_consulta=data_consulta, mes_referencia=f"{ano}{mes:02d}")
        df_modalidade = self._get_resumo_modalidade(response_json, doc=cpf, data_consulta=data_consulta, mes_referencia=f"{ano}{mes:02d}")
        df_resumo_lista_das_operacoes = self._get_resumo_lista_das_operacoes(response_json, doc=cpf, data_consulta=data_consulta, mes_referencia=f"{ano}{mes:02d}")
        
        return df_traduzido, df_modalidade, df_resumo_lista_das_operacoes

    
    def get_cnpj_data(self, 
                      cnpj: str,     # CNPJ
                      ano: int,      # Year to be consulted. Ex: 2022
                      mes: int       # Month to be consulted. Ex: 8, 10
    ) -> Tuple[pd.DataFrame, pd.DataFrame]:
        "Query CNPJs and return a tuple of DataFrames: (df_cnpj_resumo_cliente_traduzido, df_cnpj_resumo_modalidade)"
        data_consulta = datetime.today().strftime("%d/%m/%Y")
        response_json = self._request(cnpj, ano, mes)
        if response_json.get("Erro"):
            raise Exception(response_json.get("Msg").strip() + f": {cnpj}")
        if response_json.get("MensagemOperador") == '(50) - Cliente não possui dados no SCR na data-base.':
            print(f"Cliente não possui dados no SCR na data-base: {cnpj}")
            return pd.DataFrame(), pd.DataFrame(), pd.DataFrame()
        
        df_traduzido = self._get_resumo_cliente_traduzido(response_json, doc=cnpj, data_consulta=data_consulta, mes_referencia=f"{ano}{mes:02d}")
        df_modalidade = self._get_resumo_modalidade(response_json, doc=cnpj, data_consulta=data_consulta, mes_referencia=f"{ano}{mes:02d}")
        df_resumo_lista_das_operacoes = self._get_resumo_lista_das_operacoes(response_json, doc=cnpj, data_consulta=data_consulta, mes_referencia=f"{ano}{mes:02d}")

        return df_traduzido, df_modalidade, df_resumo_lista_das_operacoes
