import re
import sistema_origem.ipm_cloud_postgresql.model as model
import bth.interacao_cloud as interacao_cloud
from datetime import datetime


def iniciar_processo_envio(params_exec, *args, **kwargs):
    lista_contratos = [885145]
    busca_dados_contrato(params_exec, lista_contratos)


def busca_dados_contrato(params_exec, id_contratacoes):
    for c in id_contratacoes:
        criterio = f'id = {c}'
        url = 'https://contratos.betha.cloud/contratos/dados/api/contratacoes'
        campos = 'id, observacao, numeroProcesso, anoProcesso, fornecedor.pessoa.cpfCnpj'
        registro_cloud = interacao_cloud.busca_api_fonte_dados(params_exec, url=url, campos=campos, criterio=criterio)
        print(registro_cloud)
        if registro_cloud is not None:
            j = registro_cloud[0]
            anotacao = get_dados_anotacao(j['observacao'])
            # print('Observação: ', j['observacao'], ' | Anotação:', anotacao)
            inicia_busca_id(params_exec, params_exec['clicodigo'], j['anoProcesso'], j['numeroProcesso'], j['fornecedor']['pessoa']['cpfCnpj'], c)


def inicia_busca_id(params_exec, clicodigo, minano, minnro, cpfcnpj, id_contrato):
    q = get_query(clicodigo, str(minano), str(minnro), str(cpfcnpj))
    dados = coletar_dados_ipm(q)
    print(q)
    if dados is not None:
        for item in dados:
            criterio = f'material.descricao like \'{item["prddescricao"]}%\' and quantidade = {item["cmiqtde"]} and contratacao.fornecedor.pessoa.cpfCnpj = \'{cpfcnpj}\' and contratacao.id = {id_contrato}'
            # print('criterio', criterio)
            url = 'https://contratos.betha.cloud/contratos/dados/api/contratacoesitens'
            campos = 'id, contratacao.id, contratacao.observacao, especificacao.descricao'
            registro_cloud = interacao_cloud.busca_api_fonte_dados(params_exec, url=url, campos=campos, criterio=criterio)
            # print('registro_cloud', registro_cloud)
            if registro_cloud is not None and len(registro_cloud) != 0:
                if len(registro_cloud) == 1:
                    j = registro_cloud[0]
                    anotacao = get_dados_anotacao(j['contratacao']['observacao'])
                    insert = f'select bth_insert_cmr(305, \'contratacao-item\', \'Cadastro de Item da Contratação - Util\', {j["id"]},  \'{params_exec["clicodigo"]}\', \'{anotacao["exercicio"]}\', \'{anotacao["identificador"]}\', \'@\', \'{item["cmiid"]}\');'
                    print(insert)
                    exec_query(insert)
                else:
                    encontrou = False
                    for j in registro_cloud:
                        anotacao = get_dados_anotacao(j['contratacao']['observacao'])
                        possui_cmiid_espec = re.search(f'CMIID {item["cmiid"]}', j['especificacao']['descricao'])
                        if possui_cmiid_espec:
                            encontrou = True
                            insert = f'select bth_insert_cmr(305, \'contratacao-item\', \'Cadastro de Item da Contratação - Util\', {j["id"]},  \'{params_exec["clicodigo"]}\', \'{anotacao["exercicio"]}\', \'{anotacao["identificador"]}\', \'@\', \'{item["cmiid"]}\');'
                            print(insert)
                            exec_query(insert)
                            break
                    if encontrou is False:
                        print('Registro desconsiderado devido a ambiguidade. ', criterio)
                        print(f'select bth_insert_cmr(305, \'contratacao-item\', \'Cadastro de Item da Contratação - Util\', ???,  \'{params_exec["clicodigo"]}\', \'{anotacao["exercicio"]}\', \'{anotacao["identificador"]}\', \'@\', \'{item["cmiid"]}\');')


def exec_query(q):
    pgcnn = model.PostgreSQLConnection()
    df = pgcnn.exec_insert(q)


def get_dados_anotacao(a):
    modelo_anotacao = re.search("Identificador:", a)

    if modelo_anotacao:
        identificador = re.findall("(\d+)", str(re.findall("Identificador:.+$", a)[0]))[0]
    else:
        identificador = re.findall("(\d+)", a)[0]

    total_barras = len(re.findall("/", a))
    if total_barras > 1:
        exercicio = re.findall("(/\d+)", a)[1]
    else:
        exercicio = re.findall("(/\d+)", a)[0]

    exercicio = exercicio.replace('/', '')
    return {
        'identificador': identificador,
        'exercicio': exercicio
    }


def get_query(clicodigo, minano, minnro, cpfcnpj):
    base_query = """
    select 
        1 as id,
        q.cmiid,
        m.cmiqtde,
        m.prddescricao
    from wco.vw_qcp_vencedor q
    inner join wun.tbunico u using (unicodigo)
    inner join wco.vw_item_minuta m using (clicodigo, minano, minnro, cmiid)
    where q.clicodigo = {{clicodigo}}
    and q.minano = {{minano}}
    and q.minnro = {{minnro}}
    and regexp_replace(u.unicpfcnpj,'[/.-]|[ ]','','g') = '{{cpfcnpj}}'   
    """
    query = base_query.replace('{{clicodigo}}', clicodigo)\
        .replace('{{minano}}', minano)\
        .replace('{{minnro}}', minnro) \
        .replace('{{cpfcnpj}}', cpfcnpj)
    return query


def get_identificador_contrato(clicodigo, copano, copnro):
    base_query = """
    select
        c.clicodigo,
        c.minano,
        c.minnro,
        c.ctrano,
        c.ctridentificador,
        coalesce(ct.ctranosup, c.ctrano) as exercicio_contrato,
        coalesce(ct.ctridentsup, c.ctridentificador) as ident_conttrato
    from wco.tbcompra c
    inner join wco.tbcontrato ct using (clicodigo, ctrano, ctridentificador)
    where c.clicodigo = {{clicodigo}}
    and c.copano = {{copano}} 
    and c.copnro = {{copnro}}
    and c.ctridentificador is not null 
    """
    query = base_query.replace('{{clicodigo}}', clicodigo)\
        .replace('{{copano}}', copano)\
        .replace('{{copnro}}', copnro)
    return query


def coletar_dados_ipm(q):
    df = None
    try:
        tempo_inicio = datetime.now()
        query = q
        pgcnn = model.PostgreSQLConnection()
        df = pgcnn.exec_sql(query, index_col='id')
        df = df.to_dict('records')
        # qtd = df[0]['qtd_total']

    except Exception as error:
        print(f'Erro ao executar função "coletar_dados_ipm". {error}')

    finally:
        return df
