import gradio as gr
from transformers import AutoTokenizer, AutoModelForQuestionAnswering
import torch
import logging
import warnings
from typing import List, Tuple, Dict
import random
import hashlib

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
warnings.filterwarnings('ignore')

# Banco de exemplos e respostas pré-definidas
BIBLICAL_EXAMPLES = {
    "casamento": [
        {
            "pergunta": "Como resolver conflitos no casamento?",
            "passagem": "Efésios 4:26-32",
            "texto": """Não se ponha o sol sobre a vossa ira. Não deis lugar ao diabo. Toda amargura, cólera, ira, gritaria e blasfêmia sejam tiradas dentre vós, bem como toda malícia. Antes, sede bondosos uns para com os outros, compassivos, perdoando uns aos outros, como também Deus vos perdoou em Cristo.""",
            "resposta_base": """O princípio bíblico para resolução de conflitos no casamento envolve três aspectos fundamentais: não deixar a ira se prolongar, comunicar-se com amor e praticar o perdão mútuo. A Palavra nos ensina que devemos resolver os conflitos rapidamente, não permitindo que o sol se ponha sobre nossa ira.""",
            "aplicacao": "Resolução diária de conflitos, perdão e reconciliação"
        },
        {
            "pergunta": "Como manter um casamento forte espiritualmente?",
            "passagem": "Eclesiastes 4:9-12",
            "texto": """É melhor serem dois do que um, porque têm melhor paga do seu trabalho. Porque se um cair, o outro levanta o seu companheiro; mas ai do que estiver só; pois, caindo, não haverá outro que o levante. Também, se dois dormirem juntos, eles se aquentarão; mas um só, como se aquentará? E, se alguém prevalecer contra um, os dois lhe resistirão; e o cordão de três dobras não se quebra tão depressa.""",
            "resposta_base": """A força espiritual do casamento vem da união em três dimensões: o marido, a esposa e Deus. Como um cordão de três dobras, esta união proporciona apoio mútuo, fortalecimento espiritual e resistência nas adversidades.""",
            "aplicacao": "Desenvolvimento espiritual conjunto e oração em casal"
        },
        {
            "pergunta": "Qual o papel do perdão no casamento?",
            "passagem": "Colossenses 3:13-14",
            "texto": """Suportando-vos uns aos outros, e perdoando-vos uns aos outros, se alguém tiver queixa contra outro; assim como Cristo vos perdoou, assim fazei vós também. E, sobre tudo isto, revesti-vos de amor, que é o vínculo da perfeição.""",
            "resposta_base": """O perdão no casamento reflete o perdão que recebemos de Cristo. É um ato contínuo de amor que fortalece o vínculo conjugal e promove a cura emocional. Devemos perdoar assim como fomos perdoados.""",
            "aplicacao": "Prática do perdão e cultivo do amor sacrificial"
        },
        {
            "pergunta": "Como manter a fidelidade no casamento?",
            "passagem": "Hebreus 13:4",
            "texto": """Venerado seja entre todos o matrimônio e o leito sem mácula; porém aos que se dão à prostituição e aos adúlteros, Deus os julgará.""",
            "resposta_base": """A fidelidade no casamento é um mandamento divino que requer compromisso, respeito mútuo e temor a Deus. O matrimônio deve ser honrado por todos, mantendo a pureza e a santidade da união conjugal.""",
            "aplicacao": "Compromisso com a fidelidade e pureza conjugal"
        },
        {
            "pergunta": "Como lidar com diferenças no casamento?",
            "passagem": "1 Pedro 3:8-9",
            "texto": """Finalmente, sede todos de um mesmo sentimento, compassivos, amando os irmãos, entranhavelmente misericordiosos e humildes. Não tornando mal por mal, ou injúria por injúria; antes, pelo contrário, bendizendo.""",
            "resposta_base": """As diferenças no casamento devem ser tratadas com compreensão, humildade e respeito mútuo. A unidade não significa uniformidade, mas harmonia nas diferenças através do amor e da compaixão.""",
            "aplicacao": "Respeito às diferenças e busca da harmonia"
        }
    ],
    "criacao_filhos": [
        # [Exemplos similares para outros temas...]
    ]
}

class DiverseBiblicalCounselor:
    def __init__(self):
        logger.info("Inicializando conselheiro bíblico...")
        self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
        self.model_name = "pierreguillou/bert-base-cased-squad-v1.1-portuguese"
        
        try:
            self.tokenizer = AutoTokenizer.from_pretrained(self.model_name)
            self.model = AutoModelForQuestionAnswering.from_pretrained(self.model_name)
            self.model.to(self.device)
            logger.info(f"Modelo carregado com sucesso no dispositivo: {self.device}")
        except Exception as e:
            logger.error(f"Erro ao carregar modelo: {str(e)}")
            raise

    def get_unique_response(self, question: str, theme: str) -> Tuple[str, Dict]:
        """Gera uma resposta única baseada na pergunta e tema"""
        
        # Gera um hash da pergunta para garantir consistência
        question_hash = hashlib.md5(question.lower().encode()).hexdigest()
        
        # Seleciona exemplo baseado no hash
        examples = BIBLICAL_EXAMPLES.get(theme, [])
        if not examples:
            return "Tema não encontrado", {}
            
        # Usa o hash para selecionar um exemplo de forma determinística
        selected_index = int(question_hash, 16) % len(examples)
        example = examples[selected_index]
        
        # Prepara o contexto para o modelo
        inputs = self.tokenizer.encode_plus(
            question,
            example["texto"],
            return_tensors="pt",
            max_length=512,
            truncation=True,
            padding="max_length"
        ).to(self.device)

        # Gera a resposta
        with torch.no_grad():
            outputs = self.model(**inputs)
        
        answer_start = torch.argmax(outputs.start_logits)
        answer_end = torch.argmax(outputs.end_logits)
        
        tokens = self.tokenizer.convert_ids_to_tokens(inputs["input_ids"][0])
        model_answer = tokens[answer_start:answer_end + 1]
        model_answer = self.tokenizer.convert_tokens_to_string(model_answer)

        # Formata a resposta final
        response = f"""
🕊️ Conselho Bíblico:
{example['resposta_base']}

📖 Passagem Bíblica:
{example['passagem']}: {example['texto']}

✝️ Aplicação Prática:
{example['aplicacao']}

💭 Reflexão Adicional:
{model_answer}
"""

        metadata = {
            "passagem": example['passagem'],
            "contexto": "Baseado em princípios bíblicos para " + theme.replace('_', ' '),
            "aplicacao": example['aplicacao']
        }

        return response, metadata

def create_interface():
    counselor = DiverseBiblicalCounselor()

    with gr.Blocks(theme=gr.themes.Soft()) as demo:
        gr.Markdown("""
        # 🕊️ Conselheiro Bíblico
        ### Orientação Bíblica Personalizada
        """)

        with gr.Row():
            with gr.Column():
                theme = gr.Dropdown(
                    choices=list(BIBLICAL_EXAMPLES.keys()),
                    label="Tema",
                    value="casamento"
                )
                question = gr.Textbox(
                    label="Sua Pergunta",
                    placeholder="Digite sua pergunta...",
                    lines=3
                )
                submit_btn = gr.Button("🙏 Buscar Orientação")

            with gr.Column():
                answer_output = gr.Textbox(
                    label="Resposta",
                    lines=10
                )
                metadata_output = gr.Textbox(
                    label="Referências",
                    lines=3
                )

        # Exemplos
        gr.Examples(
            examples=[
                ["casamento", "Como resolver conflitos no casamento?"],
                ["casamento", "Como manter um casamento forte espiritualmente?"],
                ["casamento", "Qual o papel do perdão no casamento?"],
                ["casamento", "Como manter a fidelidade no casamento?"],
                ["casamento", "Como lidar com diferenças no casamento?"]
            ],
            inputs=[theme, question],
            outputs=[answer_output, metadata_output],
            fn=lambda t, q: counselor.get_unique_response(q, t),
            label="Exemplos de Perguntas"
        )

        submit_btn.click(
            fn=lambda t, q: counselor.get_unique_response(q, t),
            inputs=[theme, question],
            outputs=[answer_output, metadata_output]
        )

    return demo

if __name__ == "__main__":
    try:
        logger.info("Iniciando aplicação...")
        demo = create_interface()
        demo.launch(
            server_name="0.0.0.0",
            share=True,
            show_error=True
        )
    except Exception as e:
        logger.error(f"Erro ao iniciar aplicação: {str(e)}")
        raise