import openai
import json
import numpy as np
import os
from django.conf import settings
from django.contrib.auth.decorators import login_required
from collections import OrderedDict
from .respostas_rapidas import respostas_prontas, resposta_treinamento_aplicativo
from .resposta_coeficientes import resposta_coeficiente_parede



from .fabiano_prompts import (
    system_educacional_carga_termica,
    system_cadastro_projeto,
    system_cadastro_ambiente,
    system_lista_ambiente,
    system_biblioteca,
    system_relatorios,
    system_termo_referencia,
    system_geral
)

EMBEDDINGS_PATH = "/var/www/html/cag/projeto/fabiano_embeddings.json"
EMBEDDINGS_RAPIDAS_PATH = "/var/www/html/cag/projeto/respostas_prontas_embeddings.json"


# Novo cliente OpenAI
client = openai.OpenAI(api_key=settings.OPENAI_API_KEY)

# Dicionário com contextos e palavras-chave associadas
keywords_map  = OrderedDict({
    "system_cadastro_ambiente": [
        "cadastrar ambiente", "quero cadastrar um ambiente", "como cadastrar um ambiente",
        "novo ambiente", "criar ambiente", "formulário de ambiente", "adicionar ambiente",
        "inserir ambiente", "ambiente novo", "preencher ambiente"
    ],
    "system_cadastro_projeto": [
        "cadastrar projeto", "quero cadastrar um projeto", "como cadastrar um projeto",
        "novo projeto", "criar projeto", "inserir projeto", "nome do projeto", "cidade do projeto",
        "coordenadas do projeto", "abrir projeto", "adicionar projeto"
    ],
    "system_termo_referencia": [
        "termo de referência", "termo de referencia", "licitação", "lei 8.666", "compras públicas",
        "documento para compra", "documento oficial", "justificativa técnica", "projeto para edital"
    ],
    "system_relatorios": [
        "relatório", "relatorios", "gráfico", "gráficos", "resultado final", "exportar docx",
        "documentação", "tabela de dados", "resultados do cálculo", "relatório técnico", "arquivo docx"
    ],
    "system_lista_ambiente": [
        "lista de ambientes", "visualizar ambientes", "ver ambientes", "resultados do ambiente",
        "mostrar ambientes", "relatório do ambiente", "ambientes cadastrados", "dados do ambiente"
    ],
    "system_biblioteca": [
        "coeficiente", "coeficientes", "biblioteca", "valores térmicos", "resistência térmica",
        "material de construção", "tabela de valores", "isolamento", "potência térmica",
        "dissipação de calor", "tabela coeficiente", "qual coeficiente", "coeficiente u", "u-value", "valor térmico", "coeficiente térmico", "dissipação de calor",
        "potência térmica", "biblioteca", "resistência térmica", "valores térmicos"
    ],
})

# Dicionário de mapeamento para os prompts reais
prompts_dict = {
    "system_educacional_carga_termica": system_educacional_carga_termica,
    "system_cadastro_projeto": system_cadastro_projeto,
    "system_cadastro_ambiente": system_cadastro_ambiente,
    "system_lista_ambiente": system_lista_ambiente,
    "system_biblioteca": system_biblioteca,
    "system_relatorios": system_relatorios,
    "system_termo_referencia": system_termo_referencia,
}


# Carrega os embeddings
with open(EMBEDDINGS_PATH) as f:
    system_embeddings = json.load(f)

with open(EMBEDDINGS_RAPIDAS_PATH) as f:
    respostas_rapidas_embeddings = json.load(f)

# Gera vetor da pergunta



# Resposta direta para a pergunta-chave de treinamento


from difflib import SequenceMatcher

def resposta_fixa_se_houver(texto):
    texto_normalizado = texto.lower().strip()

    # Verificação direta da pergunta-chave
    if "treinamento" in texto_normalizado and "aplicativo" in texto_normalizado:
        return resposta_treinamento_aplicativo

    # Verificação por similaridade textual com outras respostas prontas
    melhor_chave = None
    maior_similaridade = 0.0
    for chave in respostas_prontas.keys():
        sim = SequenceMatcher(None, texto_normalizado, chave).ratio()
        if sim > maior_similaridade:
            melhor_chave = chave
            maior_similaridade = sim

    if maior_similaridade > 0.75:
        return respostas_prontas[melhor_chave]

    return None





def gerar_embedding(texto):
    response = client.embeddings.create(
        input=texto,
        model="text-embedding-ada-002"
    )
    return np.array(response.data[0].embedding)

# Busca a resposta pronta mais similar

def buscar_resposta_rapida(texto):
    pergunta_vec = gerar_embedding(texto)
    similaridades = {}

    for pergunta, emb in respostas_rapidas_embeddings.items():
        emb_vec = np.array(emb)
        sim = np.dot(pergunta_vec, emb_vec) / (np.linalg.norm(pergunta_vec) * np.linalg.norm(emb_vec))
        similaridades[pergunta] = sim

    melhor = max(similaridades, key=similaridades.get)
    if similaridades[melhor] > 0.85:
        return respostas_prontas.get(melhor)
    return None

# Detecta o contexto com base nas últimas mensagens

def detectar_contexto(historico_mensagens):
    if len(historico_mensagens) >= 2:
        pergunta_composta = historico_mensagens[-2]["content"] + " " + historico_mensagens[-1]["content"]
    else:
        pergunta_composta = historico_mensagens[-1]["content"]

    pergunta_vec = gerar_embedding(pergunta_composta)
    similaridades = {}

    for nome, emb in system_embeddings.items():
        emb_vec = np.array(emb)
        sim = np.dot(pergunta_vec, emb_vec) / (np.linalg.norm(pergunta_vec) * np.linalg.norm(emb_vec))
        similaridades[nome] = sim

    melhor = max(similaridades, key=similaridades.get)
    return prompts_dict.get(melhor, system_geral)

# View principal
@login_required
def responder_pergunta_termo_ia(request, historico_mensagens):
    user_mensagem = historico_mensagens[-1]["content"]
    resposta_pronta = buscar_resposta_rapida(user_mensagem)

    if resposta_pronta:
        return resposta_pronta

    system_prompt = detectar_contexto(historico_mensagens)
    mensagens = [system_prompt, historico_mensagens[-1]]

    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=mensagens,
        temperature=0.3
    )

    return response.choices[0].message.content




# def executar_acao_projeto(usuario, texto):
#     """
#     Analisa o texto enviado pelo usuário e, se a intenção for cadastrar um projeto,
#     extrai os dados e chama a função criar_projeto_por_ia().
#     """

#     import re
#     from projeto.models import Projeto
#     from .views import criar_projeto_por_ia  # lazy import evita import circular

#     # Lista de palavras-chave para identificar a intenção
#     palavras_chave = [
#         "cadastrar projeto", "criar projeto", "novo projeto",
#         "projeto chamado", "projeto nomeado", "nome do projeto"
#     ]

#     if not any(p in texto.lower() for p in palavras_chave):
#         return None  # Não parece ser uma ação de cadastro de projeto

#     # Extrair nome do projeto (ex: "cadastrar projeto chamado Biblioteca Central")
#     nome_match = re.search(r"projeto (?:chamado|nomeado|de nome)?\s*([A-ZÁÉÍÓÚÃÕÂÊÎÔÛ][\w\s\-]+)", texto, re.IGNORECASE)

#     # Extrair cidade (ex: "em Belo Horizonte", "cidade Salvador")
#     cidade_match = re.search(r"(?:cidade|em|localizado em)\s+([A-ZÁÉÍÓÚÃÕÂÊÎÔÛ][\w\s\-]+)", texto, re.IGNORECASE)

#     nome_projeto = nome_match.group(1).strip() if nome_match else None
#     cidade = cidade_match.group(1).strip() if cidade_match else None

#     # Respostas guiadas para fluxos incompletos
#     if not nome_projeto and not cidade:
#         return "Por favor, informe o nome do projeto e a cidade."

#     elif not nome_projeto:
#         return "Qual o nome do projeto que você deseja cadastrar?"

#     elif not cidade:
#         return f"Certo, o nome do projeto é '{nome_projeto}'. Agora, em qual cidade ele está localizado?"

#     # Verifica se já existe
#     if Projeto.objects.filter(nome_projeto__iexact=nome_projeto, cidade__iexact=cidade, tenant=usuario.tenant).exists():
#         return f"Já existe um projeto chamado '{nome_projeto}' em '{cidade}' no seu tenant."

#     # Criação via função já existente
#     projeto, msg = criar_projeto_por_ia(usuario, nome_projeto, cidade)
#     return msg or "Projeto criado com sucesso!"
