import json
from flask import Blueprint, request, jsonify
from app.database import db
from app.auth import login_required

intelligence_bp = Blueprint("intelligence", __name__)

@intelligence_bp.route("/insights", methods=["GET"])
@login_required
def get_insights():
    """Calcula e retorna alertas automáticos de desempenho, playbooks e análise de gargalos."""
    
    # 1. Obter métricas gerais e por operador
    total_records_row = db.execute_query("SELECT COUNT(*) as total FROM atendimentos", fetch="one")
    total_records = total_records_row.get("total", 0) if total_records_row else 0

    if total_records == 0:
        return jsonify({
            "success": True,
            "alerts": [],
            "bottlenecks": [],
            "playbooks": [],
            "team_summary": {}
        })

    # Métricas agregadas por operador
    operators_data_raw = db.execute_query("""
    SELECT 
        operador_nome,
        COUNT(*) as total,
        SUM(CASE WHEN INSTR(qualificacao_lead, 'Convertido') > 0 OR motivo_fechamento IN ('Venda Concluída', 'Proposta Aceita') THEN 1 ELSE 0 END) as convertidos,
        SUM(CASE WHEN motivo_fechamento = 'Somente informações' THEN 1 ELSE 0 END) as perdas_somente_info,
        SUM(CASE WHEN motivo_fechamento = 'Sem retorno do cliente (No-show)' THEN 1 ELSE 0 END) as perdas_no_show,
        SUM(CASE WHEN motivo_fechamento = 'Preço acima do orçamento' THEN 1 ELSE 0 END) as perdas_preco,
        SUM(CASE WHEN motivo_fechamento = 'Veículo fora do perfil / Km alto' THEN 1 ELSE 0 END) as perdas_km_alto
    FROM atendimentos
    WHERE operador_nome IS NOT NULL AND operador_nome != ''
    GROUP BY operador_nome
    """)

    operators_data = []
    for op in operators_data_raw:
        operators_data.append({
            "operador_nome": op["operador_nome"],
            "total": int(op["total"] or 0),
            "convertidos": int(op["convertidos"] or 0),
            "perdas_somente_info": int(op["perdas_somente_info"] or 0),
            "perdas_no_show": int(op["perdas_no_show"] or 0),
            "perdas_preco": int(op["perdas_preco"] or 0),
            "perdas_km_alto": int(op["perdas_km_alto"] or 0)
        })

    # Médias da equipe
    team_total = float(sum(op["total"] for op in operators_data))
    team_conv = float(sum(op["convertidos"] for op in operators_data))
    team_somente_info = float(sum(op["perdas_somente_info"] for op in operators_data))
    team_no_show = float(sum(op["perdas_no_show"] for op in operators_data))
    team_preco = float(sum(op["perdas_preco"] for op in operators_data))

    avg_conv_rate = float((team_conv / team_total * 100)) if team_total > 0 else 0.0
    avg_info_rate = float((team_somente_info / team_total * 100)) if team_total > 0 else 0.0
    avg_no_show_rate = float((team_no_show / team_total * 100)) if team_total > 0 else 0.0
    avg_preco_rate = float((team_preco / team_total * 100)) if team_total > 0 else 0.0

    # 2. Gerar Alertas Automáticos de Desempenho
    alerts = []

    for op in operators_data:
        op_total = op["total"]
        if op_total < 5:
            continue
        
        op_conv_rate = (op["convertidos"] / op_total * 100)
        op_info_rate = ((op["perdas_somente_info"] or 0) / op_total * 100)
        op_no_show_rate = ((op["perdas_no_show"] or 0) / op_total * 100)

        # Alerta: Taxa de "Somente informações" acima da média
        if op_info_rate > avg_info_rate * 1.25 and (op_info_rate - avg_info_rate) > 5:
            diff_pct = round(((op_info_rate - avg_info_rate) / avg_info_rate * 100), 1)
            alerts.append({
                "id": f"ALT-INFO-{op['operador_nome'].replace(' ', '')}",
                "tipo": "desempenho_critico",
                "severidade": "critico",
                "titulo": f"Taxa de Encerramento por 'Somente Informações' Elevada",
                "operador": op["operador_nome"],
                "mensagem": f"O operador <strong>{op['operador_nome']}</strong> está com taxa de encerramento por 'Somente informações' de <strong>{op_info_rate:.1f}%</strong> (<strong>{diff_pct}% acima</strong> da média da equipe de {avg_info_rate:.1f}%).",
                "impacto": f"{op['perdas_somente_info']} leads encerrados sem avanço de proposta",
                "prescricao": "Aplicar o Playbook de Qualificação Investigativa e perguntas abertas de dor antes de fornecer cotações imediatas.",
                "acao_sugerida": "Treinamento em Técnicas de Fechamento & Qualificação SPIN Selling",
                "playbook_link": "PB-QUALIF-01"
            })

        # Alerta: Taxa de No-Show / Sem Retorno acima da média
        if op_no_show_rate > avg_no_show_rate * 1.25 and (op_no_show_rate - avg_no_show_rate) > 4:
            diff_pct = round(((op_no_show_rate - avg_no_show_rate) / avg_no_show_rate * 100), 1)
            alerts.append({
                "id": f"ALT-NOSHOW-{op['operador_nome'].replace(' ', '')}",
                "tipo": "gargalo_operacional",
                "severidade": "alerta",
                "titulo": f"Taxa de Perda por 'Sem Retorno (No-Show)' Acima da Média",
                "operador": op["operador_nome"],
                "mensagem": f"O operador <strong>{op['operador_nome']}</strong> apresenta <strong>{op_no_show_rate:.1f}%</strong> de encerramentos por falta de resposta do cliente (média da equipe: {avg_no_show_rate:.1f}%).",
                "impacto": f"{op['perdas_no_show']} contatos interrompidos sem follow-up ativo",
                "prescricao": "Ativar réguas automatizadas de reengajamento em 2h, 24h e 48h via WhatsApp com ganchos de escassez.",
                "acao_sugerida": "Implementar Cadência de Follow-Up Rápido Duotalk",
                "playbook_link": "PB-FOLLOWUP-02"
            })

        # Alerta: Destaque Positivo em Conversão
        if op_conv_rate > avg_conv_rate * 1.3:
            diff_pct = round(((op_conv_rate - avg_conv_rate) / avg_conv_rate * 100), 1)
            alerts.append({
                "id": f"ALT-STAR-{op['operador_nome'].replace(' ', '')}",
                "tipo": "destaque_positivo",
                "severidade": "sucesso",
                "titulo": f"Alta Performance em Conversão de Leads",
                "operador": op["operador_nome"],
                "mensagem": f"A consultora <strong>{op['operador_nome']}</strong> atingiu taxa de conversão de <strong>{op_conv_rate:.1f}%</strong> (<strong>+{diff_pct}%</strong> em relação à média geral).",
                "impacto": f"{op['convertidos']} vendas concluídas no período",
                "prescricao": "Mapear as transcrições de áudio e texto deste operador para criar o benchmark e treinamento do time.",
                "acao_sugerida": "Adicionar melhores mensagens deste operador à Biblioteca de Scripts Padrão",
                "playbook_link": "PB-CLOSING-03"
            })

    # Alerta de Canal: Webchat vs WhatsApp
    canal_stats = db.execute_query("""
    SELECT 
        canal, 
        COUNT(*) as total,
        SUM(CASE WHEN INSTR(qualificacao_lead, 'Convertido') > 0 OR motivo_fechamento IN ('Venda Concluída', 'Proposta Aceita') THEN 1 ELSE 0 END) as conv
    FROM atendimentos
    GROUP BY canal
    """)
    for cs in canal_stats:
        if cs["canal"] == "Webchat" and cs["total"] > 10:
            c_rate = (cs["conv"] / cs["total"] * 100) if cs["total"] > 0 else 0
            if c_rate < avg_conv_rate * 0.6:
                alerts.append({
                    "id": "ALT-CANAL-WEBCHAT",
                    "tipo": "canal_ineficiente",
                    "severidade": "alerta",
                    "titulo": "Canal Webchat com Fuga Excessiva de Leads",
                    "operador": "Todos os Operadores",
                    "mensagem": f"O canal <strong>Webchat</strong> possui taxa de conversão de apenas <strong>{c_rate:.1f}%</strong> contra <strong>32.4%</strong> no WhatsApp. A maioria dos usuários abandona a aba do navegador.",
                    "impacto": f"{cs['total'] - cs['conv']} potenciais compradores perdidos por atrito de canal",
                    "prescricao": "Ativar gatilho de 'Transbordo Imediato para WhatsApp' solicitando o número do lead no 1º minuto de conversa.",
                    "acao_sugerida": "Configurar Bot de Coleta de WhatsApp no Duotalk",
                    "playbook_link": "PB-TRANSBORDO-04"
                })

    # 3. Análise de Gargalos e Motivos de Perda (Pareto / Impacto Financeiro)
    bottlenecks_query = db.execute_query("""
    SELECT 
        motivo_fechamento,
        COUNT(*) as total_perdas,
        AVG(CASE WHEN canal = 'WhatsApp' THEN 1 ELSE 0 END) * 100 as pct_whatsapp
    FROM atendimentos
    WHERE motivo_fechamento NOT IN ('Venda Concluída', 'Proposta Aceita', 'Test-Drive e Reserva Efetuada', 'Financiamento Aprovado e Pago', 'Em andamento / Proposta enviada')
    GROUP BY motivo_fechamento
    ORDER BY total_perdas DESC
    """)

    valor_medio_ticket = 175000.00 # Valor médio estimado por veículo
    bottlenecks = []
    for b in bottlenecks_query:
        qtd = b["total_perdas"]
        pct = round((qtd / total_records * 100), 1)
        impacto_financeiro = qtd * valor_medio_ticket

        diagnostico = ""
        acao_corretiva = ""
        if "Somente informações" in b["motivo_fechamento"]:
            diagnostico = "O cliente recebe a ficha técnica/preço sem ancoragem de valor ou sem perguntas de diagnóstico, encerrando a conversa prematuramente."
            acao_corretiva = "Aplicar técnica de reciprocidade: responder a dúvida condicionada a agendamento de visita ou simulação personalizada."
        elif "Preço acima" in b["motivo_fechamento"]:
            diagnostico = "Leads sentem a parcela pesada sem conhecer opções de entrada flexível (cartão em 10x) ou planos balão (residual)."
            acao_corretiva = "Apresentar plano de financiamento com parcelas reduzidas e supervalorização do seminovo na troca."
        elif "Sem retorno" in b["motivo_fechamento"]:
            diagnostico = "Falta de contato nos primeiros 5 minutos ou mensagens monótonas que não despertam urgência."
            acao_corretiva = "Implementar áudios curtos personalizados e envio de vídeo de tour do veículo escolhido."
        elif "Km alto" in b["motivo_fechamento"] or "fora do perfil" in b["motivo_fechamento"]:
            diagnostico = "Leads com veículos de alta quilometragem temem desvalorização na troca e desistem do negócio."
            acao_corretiva = "Utilizar o Playbook de Veículos com Alta Quilometragem (foco em custo de manutenção futura vs tranquilidade de garantia de fábrica)."
        else:
            diagnostico = "Atrito na qualificação ou concorrência com ofertas agressivas da mesma região."
            acao_corretiva = "Equalizar condições comerciais com bônus de emplacamento e IPVA 2026 grátis."

        bottlenecks.append({
            "motivo": b["motivo_fechamento"],
            "quantidade": qtd,
            "percentual_volume": pct,
            "impacto_estimado_brl": impacto_financeiro,
            "diagnostico": diagnostico,
            "acao_corretiva": acao_corretiva
        })

    # 4. Playbooks Prescritivos de Abordagem
    playbooks = [
        {
            "id": "PB-KM-ALTO",
            "titulo": "Playbook: Contorno de Objeção para Veículos de Alta KM",
            "gatilho": "Cliente possui usado com mais de 40.000 km e hesita com a desvalorização na troca",
            "categoria": "Seminovos & Troca",
            "foco": "Custo Oportunidade, Manutenção Preventiva & Desvalorização",
            "script_sugerido": "Olá [Nome do Cliente]! Entendo perfeitamente sua preocupação com a avaliação. Porém, um veículo que ultrapassa os 45.000 km entra na curva de manutenção pesada (correia, suspensão, freios e pneus), o que pode custar até R$ 8.000 nos próximos 12 meses. Ao migrar para o [Modelo 0km], você zera esse custo com 3 anos de garantia total e ainda garantimos até 100% da Tabela FIPE no seu usado hoje. Vamos fechar a reserva antes da virada de lote?",
            "metricas_esperadas": "+24% na recuperação de leads com seminovos usados na troca."
        },
        {
            "id": "PB-INFO-TRAP",
            "titulo": "Playbook: Quebra do 'Somente Informações' (SPIN Selling)",
            "gatilho": "Cliente pergunta apenas 'Qual o preço final?' ou 'Tem pronta entrega?'",
            "categoria": "Qualificação & Fechamento",
            "foco": "Ancoragem de Valor antes da revelação do preço",
            "script_sugerido": "Com certeza [Nome]! Consigo te passar a condição exata agora mesmo. Apenas para eu aplicar a melhor tabela de desconto de fábrica disponível hoje: você busca uma versão para uso pessoal diário ou viagem com a família? E você pretende incluir algum veículo na troca para abater a entrada?",
            "metricas_esperadas": "-38% na taxa de encerramento prematuro sem avanço de proposta."
        },
        {
            "id": "PB-NO-SHOW",
            "titulo": "Playbook: Recuperação de Leads Sem Retorno (WhatsApp)",
            "gatilho": "Lead parou de responder há mais de 4 horas após envio de proposta",
            "categoria": "Reengajamento Rápido",
            "foco": "Gatilho de Curiosidade e Escassez Real",
            "script_sugerido": "[Nome], tudo bem? Acabou de abrir uma vaga prioritária de test-drive e liberação de bônus de R$ 6.000 para o [Modelo] aqui na unidade. Como você demonstrou interesse hoje cedo, reservei a condição no seu nome até as 18h. Posso manter sua prioridade ou libero para o próximo da fila?",
            "metricas_esperadas": "41% de taxa de resposta em leads dormentes."
        },
        {
            "id": "PB-FINAN-PARCELA",
            "titulo": "Playbook: Contorno de Parcela Alta no Financiamento",
            "gatilho": "Cliente diz 'a parcela ficou pesada para o meu orçamento'",
            "categoria": "Condições Comerciais & CDC",
            "foco": "Flexibilização com Plano Balão / Entrada Fracionada",
            "script_sugerido": "Entendo 100%, [Nome]! Uma excelente estratégia que nossos clientes utilizam é o Plano Balão: reduzimos a sua parcela mensal em até 35% durante os 24 ou 36 meses, deixando uma parcela residual para o final — que é quitada com a própria valorização do carro na troca futura. Quer que eu faça uma simulação nessa modalidade?",
            "metricas_esperadas": "+19% de conversão em simulações com recusa inicial."
        }
    ]

    return jsonify({
        "success": True,
        "team_summary": {
            "total_records": total_records,
            "avg_conversion_rate": round(avg_conv_rate, 1),
            "avg_somente_info_rate": round(avg_info_rate, 1),
            "avg_no_show_rate": round(avg_no_show_rate, 1),
            "avg_preco_rate": round(avg_preco_rate, 1)
        },
        "alerts": alerts,
        "bottlenecks": bottlenecks,
        "playbooks": playbooks
    })

@intelligence_bp.route("/language-analysis", methods=["GET"])
@login_required
def get_language_analysis():
    """Auditoria em tempo real de expressões passivas/negativas e prescrições de linguagem."""
    try:
        rows = db.execute_query("SELECT id, id_duotalk, nome_chat, operador_nome, criado_em, payload_bruto FROM atendimentos WHERE payload_bruto IS NOT NULL") or []

        # Dicionário de regras de auditoria de linguagem
        rules = [
            {
                "phrase_key": "nao_tem_como",
                "label": "não tem como / não dá",
                "keywords": ["não tem como", "nao tem como", "não dá", "nao da"],
                "categoria": "Bloqueio Sem Solução",
                "severidade": "critico",
                "impacto": "Gera objeção imediata e encerra o diálogo sem buscar alternativas",
                "recomendacao": "Substituir por foco na solução: 'O caminho ideal que podemos seguir é...' ou 'Vou consultar a melhor alternativa para você.'",
                "frase_sugerida": "Vou verificar a melhor alternativa disponível para atendê-lo(a)."
            },
            {
                "phrase_key": "infelizmente",
                "label": "infelizmente",
                "keywords": ["infelizmente"],
                "categoria": "Linguagem Negativa",
                "severidade": "alerta",
                "impacto": "Prematura uma resposta negativa antes de apresentar valor ou opções",
                "recomendacao": "Evitar iniciar frases com tom de lamento. Apresentar imediatamente o que É possível fazer.",
                "frase_sugerida": "Para que possamos resolver da melhor forma..."
            },
            {
                "phrase_key": "vou_ver",
                "label": "vou ver / vou olhar",
                "keywords": ["vou ver", "vou olhar", "vou checar se consigo", "vou dar uma olhada"],
                "categoria": "Falta de Clareza e Agilidade",
                "severidade": "moderado",
                "impacto": "Transmite hesitação e falta de autoridade no atendimento",
                "recomendacao": "Demonstrar agilidade proativa e prazo claro de resposta.",
                "frase_sugerida": "Estou consultando nosso sistema agora mesmo e te confirmo em 2 minutos."
            },
            {
                "phrase_key": "nao_e_possivel",
                "label": "não é possível",
                "keywords": ["não é possível", "nao e possivel", "não temos autorização"],
                "categoria": "Recusa Direta",
                "severidade": "critico",
                "impacto": "Cria barreira com o cliente sem construir uma contraproposta",
                "recomendacao": "Oferecer alternativas equivalentes ou encaminhar para validação de supervisão.",
                "frase_sugerida": "Vou levar sua solicitação para a gerência para buscar uma condição especial."
            },
            {
                "phrase_key": "nao_sei",
                "label": "não sei / não tenho essa informação",
                "keywords": ["não sei", "nao sei", "não tenho informação", "não faço ideia"],
                "categoria": "Insegurança Técnica",
                "severidade": "critico",
                "impacto": "Reduz a confiança do cliente no conhecimento da concessionária",
                "recomendacao": "Assumir a busca da resposta com especialista dedicado.",
                "frase_sugerida": "Vou me informar imediatamente com nosso especialista técnico e te trago o detalhe exato."
            },
            {
                "phrase_key": "demora",
                "label": "demora / vai demorar",
                "keywords": ["demora", "demorado", "demorar"],
                "categoria": "Expectativa Negativa",
                "severidade": "moderado",
                "impacto": "Cria percepção de lentidão antes da execução do serviço",
                "recomendacao": "Especificar prazos reais com tom positivo e agendamento prioritário.",
                "frase_sugerida": "Nosso tempo médio para este serviço é super rápido e já podemos agendar seu horário exclusivo."
            }
        ]

        analysis_results = []
        total_evitaveis_detectadas = 0

        for r in rules:
            rule_item = {
                "phrase_key": r["phrase_key"],
                "label": r["label"],
                "categoria": r["categoria"],
                "severidade": r["severidade"],
                "impacto": r["impacto"],
                "recomendacao": r["recomendacao"],
                "frase_sugerida": r["frase_sugerida"],
                "count": 0,
                "operadores_afetados": set(),
                "exemplos_reais": []
            }

            for row in rows:
                p = row.get("payload_bruto")
                if not isinstance(p, dict):
                    continue

                cust_name = p.get("nome") or row.get("nome_chat") or p.get("nomeChatbot") or "Cliente Visitante"
                op_name = row.get("operador_nome") or p.get("operador") or "-"
                
                mh = str(p.get("messageHistory") or "")
                mg = str(p.get("mensagem") or "")
                transcript_text = mh if ("(" in mh and ")" in mh) else (mg if ("(" in mg and ")" in mg) else (mh or mg))

                if not transcript_text.strip():
                    continue

                # Status de atendimento
                tp_raw = str(row.get("tipo_integracao") or p.get("tipoIntegracao") or "abertura").strip().lower()
                status_atendimento = "Encerrado" if ("fech" in tp_raw or "encerr" in tp_raw) else "Aberto"

                # Importação lazy para evitar circular import
                from app.routes.api_conversations import parse_duotalk_transcript, adjust_cuiaba_time
                parsed_msgs = parse_duotalk_transcript(transcript_text, cust_name, op_name)

                # Considerar SOMENTE escritas de nossa parte (atendente/bot), ignorando o cliente
                our_msgs = [m for m in parsed_msgs if m.get("sender") in ["agent", "bot"]]
                if our_msgs:
                    our_text = " ".join(m["text"] for m in our_msgs).lower()
                else:
                    # Fallback: filtra linhas do transcript que não pertençam ao cliente
                    lines = transcript_text.split("\n")
                    our_lines = [l for l in lines if cust_name.lower() not in l.lower()]
                    our_text = " ".join(our_lines).lower()

                if not our_text.strip():
                    continue

                for kw in r["keywords"]:
                    if kw in our_text:
                        rule_item["count"] += 1
                        if op_name and op_name != "-":
                            rule_item["operadores_afetados"].add(op_name)

                        # Extrai trecho real do diálogo do nosso lado
                        snippet = ""
                        if our_msgs:
                            for m in our_msgs:
                                if kw in m["text"].lower():
                                    snippet = m["text"].strip()
                                    break
                        if not snippet:
                            for line in transcript_text.split("\n"):
                                if kw in line.lower() and cust_name.lower() not in line.lower():
                                    snippet = line.strip()
                                    break
                        if not snippet:
                            snippet = f"Trecho com expressão '{kw}' identificado no atendimento."

                        # Limpa snippet longo
                        if len(snippet) > 180:
                            snippet = snippet[:177] + "..."

                        criado_cuiaba = adjust_cuiaba_time(str(row.get("criado_em") or (p.get("timestamp") or "")))

                        if len(rule_item["exemplos_reais"]) < 5:
                            rule_item["exemplos_reais"].append({
                                "id": row.get("id"),
                                "id_duotalk": row.get("id_duotalk") or f"DT-{row.get('id')}",
                                "nome_chat": row.get("nome_chat") or p.get("nomeChatbot") or "Atendimento",
                                "cliente_nome": cust_name,
                                "operador_nome": op_name,
                                "status_atendimento": status_atendimento,
                                "criado_em": criado_cuiaba,
                                "trecho_real": snippet
                            })
                        break

            rule_item["operadores_afetados"] = list(rule_item["operadores_afetados"])
            total_evitaveis_detectadas += rule_item["count"]
            analysis_results.append(rule_item)

        # Ordenar por contagem decrescente
        analysis_results.sort(key=lambda x: x["count"], reverse=True)

        return jsonify({
            "success": True,
            "total_evitaveis": total_evitaveis_detectadas,
            "expressions": analysis_results
        })

    except Exception as e:
        print(f"[LANGUAGE ANALYSIS ERROR] {e}")
        return jsonify({"success": False, "error": str(e), "expressions": []}), 200
