# -*- coding: utf-8 -*-
# /var/www/html/fluxo_financeiro.py

import json
import re
import requests
import time
from datetime import datetime
from utils_hibrido import (
    registrar_log, enviar_whatsapp, obter_mensagem_db, buscar_config,
    cobrancas_cliente_atraso, cobrancas_cliente_nao_pagas, gerar_boleto
)

def extrair_cobrancas(resultado, tipo_chamada=""):
    """
    Extrai a lista de cobranças da resposta da API.
    Os dados principais (data_vencimento, linha_digitavel, qrcode) estão no nível do row,
    não dentro de itensPlano.
    """
    cobrancas = []
    
    if not resultado:
        registrar_log('FINANCEIRO', f"extrair_cobrancas: resultado vazio para {tipo_chamada}")
        return cobrancas
    
    if isinstance(resultado, dict):
        rows = resultado.get('rows', [])
        registrar_log('FINANCEIRO', f"extrair_cobrancas ({tipo_chamada}): {len(rows)} rows encontrados")
        
        for idx_row, row in enumerate(rows):
            # Os dados principais estão no próprio row
            cobranca = {
                'id_cobranca': row.get('id_cobranca'),
                'id_cobranca_plano': None,
                'id_cliente_plano': row.get('id_cliente_plano'),
                'plano': row.get('plano'),
                'data_vencimento': row.get('data_vencimento', ''),
                'periodo_prestacao': row.get('periodo_prestacao', ''),
                'valor': row.get('valor_total_cobranca', '0.00'),
                'valor_ate_vencimento': row.get('valor_ate_vencimento', '0.00'),
                'valor_total_a_pagar': row.get('valor_total_a_pagar', '0.00'),
                'linha_digitavel': row.get('linha_digitavel', ''),
                'qrcode_copy_paste': row.get('qrcode_copy_paste', ''),
                'tipoPagamento': row.get('tipoPagamento', ''),
                'pago': row.get('pago', '0'),
                'isVencido': row.get('isVencido', False)
            }
            
            # Se tiver itensPlano, pega o primeiro para complementar
            itens_plano = row.get('itensPlano', [])
            if itens_plano and isinstance(itens_plano[0], dict):
                item = itens_plano[0]
                cobranca['id_cobranca_plano'] = item.get('id_cobranca_plano')
                if not cobranca['plano']:
                    cobranca['plano'] = item.get('plano')
                if cobranca['valor'] == '0.00' or not cobranca['valor']:
                    cobranca['valor'] = item.get('valor', '0.00')
            
            cobrancas.append(cobranca)
            
            registrar_log('FINANCEIRO', f"  Row {idx_row}: id_cobranca={cobranca.get('id_cobranca')}, plano={cobranca.get('plano')}, venc={cobranca.get('data_vencimento')}, valor={cobranca.get('valor')}")
    
    return cobrancas

def esta_no_mes_corrente(data_vencimento):
    """Verifica se a data de vencimento é no mês corrente."""
    if not data_vencimento:
        return False
    try:
        data = datetime.strptime(data_vencimento, '%Y-%m-%d')
        agora = datetime.now()
        return data.year == agora.year and data.month == agora.month
    except:
        return False

def formatar_data(data_vencimento):
    """Formata a data para exibição (DD/MM/YYYY)."""
    if not data_vencimento:
        return 'data não informada'
    try:
        data = datetime.strptime(data_vencimento, '%Y-%m-%d')
        return data.strftime('%d/%m/%Y')
    except:
        return data_vencimento

def processar(conn, cursor, job, atendimento, configs, mensagem_bruta):
    atendimento_id = atendimento['id']
    numero = atendimento['cliente_numero']
    estado = atendimento.get('estado_atual', 'INICIO')
    
    raw_ctx = atendimento.get('contexto_json')
    ctx = json.loads(raw_ctx) if raw_ctx else {}
    id_cliente = ctx.get('id_cliente')
    
    registrar_log('FINANCEIRO', f"Estado: {estado}, ID Cliente: {id_cliente}")
    
    if estado == 'INICIO':
        if not id_cliente:
            registrar_log('FINANCEIRO', "ID do cliente não encontrado no contexto")
            enviar_whatsapp(configs, numero, "Não foi possível identificar seu cadastro. Transferindo para atendente.")
            cursor.execute("UPDATE atendimentos SET status = 'fila', fluxo_atual = 'HUMANO' WHERE id = %s", (atendimento_id,))
            conn.commit()
            return
        
        msg_espera = obter_mensagem_db(cursor, 'msg_financeiro_buscando')
        enviar_whatsapp(configs, numero, msg_espera)
        
        # Busca cobranças
        resultado_atraso = cobrancas_cliente_atraso(cursor, id_cliente)
        resultado_nao_pagas = cobrancas_cliente_nao_pagas(cursor, id_cliente)
        
        # Extrai cobranças
        cobrancas_atraso = extrair_cobrancas(resultado_atraso, "atraso")
        cobrancas_nao_pagas = extrair_cobrancas(resultado_nao_pagas, "nao_pagas")
        
        registrar_log('FINANCEIRO', f"Cobranças em atraso: {len(cobrancas_atraso)}")
        registrar_log('FINANCEIRO', f"Cobranças não pagas: {len(cobrancas_nao_pagas)}")
        
        # Filtra cobranças não pagas: apenas as do mês corrente
        cobrancas_mes_corrente = []
        for item in cobrancas_nao_pagas:
            vencimento = item.get('data_vencimento', '')
            if esta_no_mes_corrente(vencimento):
                cobrancas_mes_corrente.append(item)
                registrar_log('FINANCEIRO', f"  → Do mês corrente: {item.get('plano')} - {vencimento}")
            else:
                registrar_log('FINANCEIRO', f"  → Ignorada (futura): {item.get('plano')} - {vencimento}")
        
        registrar_log('FINANCEIRO', f"Total a exibir: atraso={len(cobrancas_atraso)} + mes_corrente={len(cobrancas_mes_corrente)}")
        
        # Combina as cobranças usando id_cobranca como chave única
        cobrancas_unicas = {}
        
        # Adiciona todas em atraso
        for item in cobrancas_atraso:
            id_cob = item.get('id_cobranca')
            if id_cob:
                cobrancas_unicas[str(id_cob)] = {
                    'id_cobranca': id_cob,
                    'id_cobranca_plano': item.get('id_cobranca_plano'),
                    'nome_plano': item.get('plano', 'Fatura'),
                    'vencimento': item.get('data_vencimento', ''),
                    'periodo': item.get('periodo_prestacao', ''),
                    'valor': item.get('valor_total_a_pagar', item.get('valor', '0.00')),
                    'valor_original': item.get('valor', '0.00'),
                    'qrcode': item.get('qrcode_copy_paste', ''),
                    'codigo_barras': item.get('linha_digitavel', ''),
                    'status': 'atraso'
                }
                registrar_log('FINANCEIRO', f"Adicionado atraso: id_cobranca={id_cob}, plano={item.get('plano')}, venc={item.get('data_vencimento')}, valor={item.get('valor_total_a_pagar')}")
        
        # Adiciona apenas as do mês corrente que não são duplicadas
        for item in cobrancas_mes_corrente:
            id_cob = item.get('id_cobranca')
            if id_cob and str(id_cob) not in cobrancas_unicas:
                cobrancas_unicas[str(id_cob)] = {
                    'id_cobranca': id_cob,
                    'id_cobranca_plano': item.get('id_cobranca_plano'),
                    'nome_plano': item.get('plano', 'Fatura'),
                    'vencimento': item.get('data_vencimento', ''),
                    'periodo': item.get('periodo_prestacao', ''),
                    'valor': item.get('valor_total_a_pagar', item.get('valor', '0.00')),
                    'valor_original': item.get('valor', '0.00'),
                    'qrcode': item.get('qrcode_copy_paste', ''),
                    'codigo_barras': item.get('linha_digitavel', ''),
                    'status': 'pendente'
                }
                registrar_log('FINANCEIRO', f"Adicionado pendente: id_cobranca={id_cob}, plano={item.get('plano')}, venc={item.get('data_vencimento')}, valor={item.get('valor_total_a_pagar')}")
        
        lista_cobrancas = list(cobrancas_unicas.values())
        
        # Ordena por data de vencimento (mais antiga primeiro)
        lista_cobrancas.sort(key=lambda x: x.get('vencimento', ''))
        
        if not lista_cobrancas:
            msg = obter_mensagem_db(cursor, 'msg_financeiro_nada_encontrado')
            enviar_whatsapp(configs, numero, msg)
            cursor.execute("UPDATE atendimentos SET fluxo_atual = 'CLASSIFICACAO', estado_atual = 'AGUARDANDO_MENSAGEM' WHERE id = %s", (atendimento_id,))
            conn.commit()
            return
        
        # Salva no contexto
        ctx['cobrancas'] = lista_cobrancas
        cursor.execute("UPDATE atendimentos SET contexto_json = %s, estado_atual = 'AGUARDANDO_ESCOLHA' WHERE id = %s", (json.dumps(ctx), atendimento_id))
        conn.commit()
        
        # Monta mensagem formatada
        linhas = []
        for i, cob in enumerate(lista_cobrancas, 1):
            if cob['status'] == 'atraso':
                status_texto = "🔴 ATRASADO"
            else:
                status_texto = "🟡 A VENCER"
            
            venc_formatado = formatar_data(cob.get('vencimento', ''))
            nome_plano = cob.get('nome_plano', 'Fatura')
            valor_exibido = cob.get('valor', '0.00')
            
            if len(nome_plano) > 30:
                nome_plano = nome_plano[:27] + '...'
            
            # Mostra período se disponível
            periodo = cob.get('periodo', '')
            if periodo:
                linhas.append(f"{i} - {nome_plano} ({periodo})\n   Vencimento: {venc_formatado}\n   Valor: R$ {valor_exibido} {status_texto}")
            else:
                linhas.append(f"{i} - {nome_plano}\n   Vencimento: {venc_formatado}\n   Valor: R$ {valor_exibido} {status_texto}")
        
        mensagem = "📋 *FATURAS EM ABERTO*\n\n" + "\n\n".join(linhas) + "\n\nDigite o número da fatura que deseja pagar ou *TODAS* para pagar todas:"
        enviar_whatsapp(configs, numero, mensagem)
    
    # Estado: Aguardando escolha da cobrança
    elif estado == 'AGUARDANDO_ESCOLHA':
        resposta = mensagem_bruta.strip().lower()
        cobrancas = ctx.get('cobrancas', [])
        
        if resposta == 'todas':
            ctx['cobrancas_selecionadas'] = list(range(len(cobrancas)))
            cursor.execute("UPDATE atendimentos SET contexto_json = %s, estado_atual = 'AGUARDANDO_PAGAMENTO' WHERE id = %s", (json.dumps(ctx), atendimento_id))
            conn.commit()
            mensagem_opcoes = "💰 *Opções de pagamento*\n\n1 - Pix Copia e Cola\n2 - Código de Barras\n3 - Boleto PDF\n\nDigite o número da opção desejada:"
            enviar_whatsapp(configs, numero, mensagem_opcoes)
        else:
            try:
                escolha = int(resposta) - 1
                if 0 <= escolha < len(cobrancas):
                    ctx['cobrancas_selecionadas'] = [escolha]
                    cursor.execute("UPDATE atendimentos SET contexto_json = %s, estado_atual = 'AGUARDANDO_PAGAMENTO' WHERE id = %s", (json.dumps(ctx), atendimento_id))
                    conn.commit()
                    mensagem_opcoes = "💰 *Opções de pagamento*\n\n1 - Pix Copia e Cola\n2 - Código de Barras\n3 - Boleto PDF\n\nDigite o número da opção desejada:"
                    enviar_whatsapp(configs, numero, mensagem_opcoes)
                else:
                    enviar_whatsapp(configs, numero, "Número inválido. Digite o número correto da fatura ou 'TODAS'.")
            except ValueError:
                enviar_whatsapp(configs, numero, "Digite apenas o número da fatura ou 'TODAS'.")
    
    # Estado: Aguardando opção de pagamento
    elif estado == 'AGUARDANDO_PAGAMENTO':
        opcao = mensagem_bruta.strip()
        cobrancas = ctx.get('cobrancas', [])
        selecionadas = ctx.get('cobrancas_selecionadas', [])
        phone_id = buscar_config(cursor, 'PHONE_NUMBER_ID')
        token = buscar_config(cursor, 'WHATSAPP_TOKEN')
        
        enviados = []
        erros = []
        
        for idx in selecionadas:
            cob = cobrancas[idx]
            
            if opcao == '1':  # Pix
                qrcode = cob.get('qrcode')
                if qrcode:
                    enviar_whatsapp(configs, numero, qrcode)
                    enviados.append(f"Pix da fatura {cob['nome_plano']}")
                    time.sleep(1)
                else:
                    erros.append(f"Pix não disponível para a fatura {cob['nome_plano']}")
            
            elif opcao == '2':  # Código de barras
                codigo = cob.get('codigo_barras')
                if codigo:
                    enviar_whatsapp(configs, numero, codigo)
                    enviados.append(f"Código de barras da fatura {cob['nome_plano']}")
                    time.sleep(1)
                else:
                    erros.append(f"Código de barras não disponível para a fatura {cob['nome_plano']}")
            
            elif opcao == '3':  # PDF
                id_cobranca = cob.get('id_cobranca')
                if id_cobranca:
                    registrar_log('FINANCEIRO', f"Gerando PDF para id_cobranca: {id_cobranca}")
                    resultado = gerar_boleto(cursor, id_cobranca)
                    registrar_log('FINANCEIRO', f"Resultado gerar_boleto: {resultado}")
                    
                    if resultado and isinstance(resultado, dict):
                        url_pdf = resultado.get('rows') or resultado.get('url') or resultado.get('link')
                        if url_pdf:
                            registrar_log('FINANCEIRO', f"URL do PDF obtida: {url_pdf}")
                            headers = {"Authorization": f"Bearer {token}"}
                            payload = {
                                "messaging_product": "whatsapp",
                                "to": numero,
                                "type": "document",
                                "document": {"link": url_pdf, "filename": f"boleto_{id_cobranca}.pdf"}
                            }
                            try:
                                resp = requests.post(f"https://graph.facebook.com/v25.0/{phone_id}/messages", json=payload, headers=headers, timeout=30)
                                if resp.status_code == 200:
                                    enviados.append(f"PDF da fatura {cob['nome_plano']}")
                                    registrar_log('FINANCEIRO', f"PDF enviado com sucesso para {numero}")
                                    time.sleep(2)  # Delay maior para o PDF processar
                                else:
                                    registrar_log('FINANCEIRO', f"Erro ao enviar PDF: HTTP {resp.status_code}")
                                    erros.append(f"Erro ao enviar PDF da fatura {cob['nome_plano']}")
                            except Exception as e:
                                registrar_log('FINANCEIRO', f"Exceção ao enviar PDF: {e}")
                                erros.append(f"Erro ao enviar PDF da fatura {cob['nome_plano']}")
                        else:
                            erros.append(f"PDF não disponível para a fatura {cob['nome_plano']}")
                    else:
                        erros.append(f"Não foi possível gerar o PDF para a fatura {cob['nome_plano']}")
                else:
                    erros.append(f"ID da cobrança não encontrado para {cob['nome_plano']}")
        
        # Aguarda um momento extra para garantir que as mensagens chegaram
        time.sleep(1)
        
        # Exibe erros se houver
        for erro in erros:
            enviar_whatsapp(configs, numero, f"⚠️ {erro}")
        
        # Agora sim pergunta se deseja mais alguma coisa (apenas se algo foi enviado)
        if enviados:
            # Aguarda mais um pouco antes da mensagem de continuação
            time.sleep(1)
            enviar_whatsapp(configs, numero, "✅ " + ", ".join(enviados) + " enviado(s) com sucesso!\n\nDeseja mais alguma coisa? (Responda SIM ou NÃO)")
            cursor.execute("""
                UPDATE atendimentos
                SET estado_atual = 'AGUARDANDO_CONTINUACAO', contexto_json = '{}'
                WHERE id = %s
            """, (atendimento_id,))
            conn.commit()
        elif not erros:
            enviar_whatsapp(configs, numero, "Nenhum pagamento foi processado. Tente novamente.")
    
    # Estado: Aguardando continuação
    elif estado == 'AGUARDANDO_CONTINUACAO':
        resposta = mensagem_bruta.strip().lower()
        if resposta in ['sim', 's', 'yes', 'quero', 'continuar']:
            cursor.execute("""
                UPDATE atendimentos
                SET fluxo_atual = 'CLASSIFICACAO', estado_atual = 'AGUARDANDO_MENSAGEM', contexto_json = '{}'
                WHERE id = %s
            """, (atendimento_id,))
            conn.commit()
            enviar_whatsapp(configs, numero, "O que mais posso fazer por você?")
        else:
            enviar_whatsapp(configs, numero, "Atendimento encerrado. Até logo!")
            cursor.execute("UPDATE atendimentos SET status = 'encerrado' WHERE id = %s", (atendimento_id,))
            conn.commit()
