/**
 * @license
 * SPDX-License-Identifier: Apache-2.0
 */

import { GoogleGenAI, GenerateContentResponse, Type, Content, Part, GroundingChunk } from "@google/genai";

// --- Translations (moved from translations.ts for simpler deployment) ---
const ptBR = {
    langName: "Português",
    appName: "Agente Turístico",
    appNameGlobalAgent: (agentName: string) => `Agente ${agentName}`,
    headerTitle: "Agente Turístico 🗺️",
    headerSubtitle: "Gerar Experiências Turísticas Locais Incríveis",
    headerTitleGlobalAgent: (agentName: string) => `Agente ${agentName} 🏙️`,
    headerSubtitleGlobalAgent: (agentName: string) => `Dicas e experiências em ${agentName}`,
    shareAppAria: "Compartilhar aplicativo",
    slideshowLoading: "Gerando imagens inspiradoras...",
    slideshowError: "Não foi possível carregar imagens no momento.",
    slideshowImageAlt: "Imagem inspiradora de viagem",
    postalOptionsTitle: "Como você quer criar seu postal?",
    postalOptionTakePhoto: "Tirar Foto com a Câmera",
    postalOptionChooseGallery: "Escolher da Galeria",
    postalRequestingLocation: "Para criar um postal da sua região, preciso da sua permissão de localização.",
    postalLocationError: "Não foi possível obter sua localização. O modo Postal precisa saber onde você está para encontrar um ponto turístico.",
    postalTouristSpotError: "Não consegui encontrar um ponto turístico famoso perto de você. Tente novamente em outra área.",
    postalImageAlt: "Cartão postal artístico gerado por IA",
    postalInstruction: "Modo Postal ativado! Posicione-se para a foto e capture sua imagem para criar um cartão postal artístico.",
    postalGenerationError: "Desculpe, não foi possível criar seu cartão postal. Tente outra foto.",
    takePhoto: "Tirar Foto",
    initialGreeting: "Olá! Sou o Agente Turístico. Pronto para descobrir experiências incríveis? Selecione um modo abaixo ou me pergunte qualquer coisa!",
    apiKeyError: "ERRO: A chave de API não foi configurada. O aplicativo não pode funcionar.",
    criticalApiError: "ERRO CRÍTICO: Nenhuma instância de IA pôde ser inicializada. Verifique as chaves de API.",
    noDefaultApiError: "O modo de chat padrão está indisponível. Por favor, selecione um modo de especialista abaixo para começar.",
    uiLoadError: "Erro: Falha ao carregar componentes essenciais da interface. Por favor, recarregue a página.",
    globalAgentModeActive: (agentName: string) => `Modo Agente ${agentName} ativado! Suas dicas agora são focadas neste local.`,
    locationAgentChanged: (agentName: string) => `Conectando com o Agente ${agentName}...`,
    translatorSelectLanguage: "Por favor, selecione o idioma do seu parceiro de conversa:",
    translatorConversationReady: (userLang: string, partnerLang: string) => `Ok! O modo de conversa está pronto entre ${userLang} e ${partnerLang}.`,
    translatorPleaseSpeakIn: (lang1: string, lang2: string) => `Por favor, fale ou digite em ${lang1} ou ${lang2}.`,
    translatorError: "Desculpe, a tradução falhou. Tente novamente.",
    friend: "Amigo",
    friendAria: "Ativar modo Amigo",
    visto: "Visto",
    vistoAria: "Ativar modo Visto e Procedimentos Legais",
    util: "Útil",
    utilAria: "Ativar modo Informações Úteis",
    translator: "Tradutor",
    translatorAria: "Ativar modo Tradutor",
    voo: "Voos",
    vooAria: "Ativar modo Voos",
    mapa: "Mapa",
    mapaAria: "Ativar modo Mapa",
    mapRouteReady: (destination: string) => `Rota para ${destination} pronta! Veja no mapa abaixo.`,
    dinheiro: "Dinheiro",
    dinheiroAria: "Ativar modo Dinheiro",
    cultura: "Cultura",
    culturaAria: "Ativar modo Cultura",
    restaurante: "Restaurante",
    restauranteAria: "Ativar modo Restaurante",
    compras: "Compras",
    comprasAria: "Ativar modo Compras",
    raiz: "Raiz",
    raizAria: "Ativar modo Raiz",
    experiencias: "Experiências",
    experienciasAria: "Ativar modo Experiências",
    balada: "Balada",
    baladaAria: "Ativar modo Balada",
    boemio: "Boêmio",
    boemioAria: "Ativar modo Boêmio",
    zen: "Zen",
    zenAria: "Ativar modo Zen",
    curioso: "Curioso",
    curiosoAria: "Ativar modo Curioso",
    historiador: "Historiador",
    historiadorAria: "Ativar modo Historiador",
    aventura: "Aventura",
    aventuraAria: "Ativar modo Aventura",
    missao: "Missão",
    missaoAria: "Ativar modo Missão",
    eventos: "Eventos",
    eventosAria: "Ativar modo Eventos",
    planejamento: "Planejamento",
    planejamentoAria: "Ativar modo Planejamento",
    exclusivo: "Exclusivo",
    exclusivoAria: "Ativar modo Exclusivo",
    promocao: "Promoção",
    promocaoAria: "Ativar modo Promoções",
    desafios: "Desafios",
    desafiosAria: "Ativar modo Desafios",
    jogos: "Jogos",
    jogosAria: "Ativar modo Jogos",
    postal: "Postal",
    postalAria: "Ativar modo Cartão Postal",
    servicos: "Serviços",
    servicosAria: "Ativar modo Serviços",
    grupos: "Grupos",
    gruposAria: "Ativar modo Grupos e Conexões",
    emergency: "Emergência",
    emergencyAria: "Ativar modo de Emergência",
    instantaneo: "Instantâneo",
    instantaneoAria: "Ativar modo de Ajuda Instantânea",
    clearChat: "Limpar",
    clearChatAria: "Limpar conversa e começar de novo",
    voiceListening: "Ouvindo...",
    userInputPlaceholder: "Quais experiências locais você busca?",
    userInputAria: "Sua mensagem",
    voiceInputAria: "Enviar mensagem de voz",
    sendAria: "Enviar mensagem",
    loading: "Nomadiando digitando...",
    footerPartnerships: "Contato para parcerias",
    footerCopyright: "© 2025 Pergunta Digital. Todos os direitos reservados.",
    ratingWidgetAria: "Widget de avaliação de resposta",
    ratingQuestion: "Esta resposta foi útil?",
    ratingThanks: "Obrigado pela sua avaliação!",
    ratingLabels: ["Avaliar com 1 estrela", "Avaliar com 2 estrelas", "Avaliar com 3 estrelas", "Avaliar com 4 estrelas", "Avaliar com 5 estrelas"],
    share: "Partilhar",
    shareResponseAria: "Partilhar esta resposta",
    shareTitle: "Olha essa dica do Agente Turístico!",
    copied: "Copiado",
    shareFailed: "Falha ao compartilhar/copiar.",
    requestingLocation: "Para encontrar voos próximos, preciso da sua permissão de localização.",
    locationSuccess: "Localização obtida! Agora pode perguntar sobre voos.",
    locationError: "Não foi possível obter sua localização. Verifique as permissões do seu navegador e ative o modo novamente.",
    requestingLocationMap: "Para traçar rotas, preciso da sua permissão de localização. Por favor, ative o modo novamente após conceder.",
    locationSuccessMap: "Localização obtida! Diga um destino para traçar a rota.",
    locationErrorMap: "Não foi possível obter sua localização. O modo Mapa precisa da sua localização para funcionar.",
    mapGenerationError: "Desculpe, não consegui encontrar este destino. Por favor, tente ser mais específico.",
    modePrefix: {
        direct: "Dica do Amigo",
        visto: "Visto e Burocracia",
        util: "Dica Útil",
        dinheiro: "Dica de Dinheiro",
        cultura: "Dica Cultural",
        restaurante: "Dica de Restaurante",
        compras: "Dica de Compras",
        raiz: "Dica Raiz",
        experiencias: "Dica de Experiência",
        balada: "Dica de Balada",
        boemio: "Dica Boêmia",
        zen: "Dica Zen",
        curioso: "Curiosidade Local",
        historiador: "Relato do Historiador",
        aventura: "Dica de Aventura",
        missao: "Desafio da Missão",
        eventos: "Agenda de Eventos",
        planejamento: "Agenda do Dia",
        exclusivo: "Dica Exclusiva",
        promocao: "Dica de Promoção",
        desafios: "Desafio Sugerido",
        jogos: "Hora do Jogo",
        postal: "Cartão Postal",
        instantaneo: "Ajuda Instantânea",
        servicos: "Indicação de Serviço",
        grupos: "Sugestão de Grupo",
        emergency: "Informação de Emergência",
        translator: "Tradução",
        voo: "Assistente de Voo",
        mapa: "Rota no Mapa",
    },
    placeholders: {
        default: "Onde comer a melhor feijoada?",
        defaultGlobalAgent: (agentName: string) => `O que há de bom para fazer em ${agentName} hoje?`,
        direct: "E aí! O que você quer saber hoje?",
        visto: "Como renovar meu visto de turista?",
        util: "Qual o melhor chip de celular para comprar?",
        dinheiro: "É seguro usar cartão de crédito em todo lugar?",
        cultura: "Museus de arte para visitar no Rio de Janeiro",
        restaurante: "Onde comer um bom churrasco?",
        compras: "Melhores lugares para comprar souvenirs",
        raiz: "O que os locais fazem para se divertir de verdade?",
        experiencias: "Qual experiência local posso ter hoje?",
        balada: "Qual a melhor festa para ir hoje?",
        boemio: "Onde tem a cerveja mais gelada?",
        zen: "Onde encontrar um lugar para meditar?",
        curioso: "Qual a maior curiosidade sobre este lugar?",
        historiador: "Qual evento histórico você quer explorar?",
        aventura: "Quais esportes radicais posso praticar aqui?",
        missao: "Estou pronto para um desafio!",
        eventos: "Qual a agenda de shows para hoje?",
        planejamento: "Vamos montar o roteiro de hoje?",
        exclusivo: "Onde encontro os eventos mais exclusivos?",
        promocao: "Quais são as melhores promoções de hoje?",
        desafios: "Sugira um desafio para mim!",
        jogos: "Quero jogar um jogo de adivinhação sobre o local.",
        postal: "Clique no modo Postal novamente para tirar sua foto!",
        instantaneo: "Preciso de ajuda com... (ex: pneu furado)",
        servicos: "Indique um bom guia turístico em Salvador",
        grupos: "Grupos de expatriados em Florianópolis",
        emergency: "Hospital mais próximo",
        translatorInactive: "Selecione o idioma do seu parceiro acima para começar.",
        translatorActive: "Fale ou digite em qualquer um dos idiomas...",
        voo: "Voos para São Paulo saindo perto de mim",
        mapa: "Para onde vamos? Diga um destino...",
    },
    voiceErrorNoSpeech: "Não consegui ouvir. Por favor, tente falar novamente.",
    voiceErrorNotAllowed: "Acesso ao microfone negado. Por favor, habilite nas configurações do seu navegador.",
    voiceErrorGeneric: "Ocorreu um erro no reconhecimento de voz. Por favor, tente novamente.",
    inappropriateContentError: "Sua mensagem não pôde ser processada por violar nossas políticas de conteúdo. Por favor, seja respeitoso.",
    apiModeError: (mode: string) => `ERRO: A chave de API para o modo '${mode}' não é válida ou não foi configurada.`,
    emptyResponseError: "Desculpe, a IA não forneceu uma resposta. Por favor, tente novamente.",
    genericApiError: "Desculpe, ocorreu um erro ao contatar a IA. Por favor, tente novamente mais tarde.",
    sourcesLabel: "Fontes:",
    apiKeyInvalidError: (mode: string) => `A chave de API para o modo '${mode}' não é válida ou não tem permissão.`,
    apiQuotaError: (mode: string) => `A cota de uso para o modo '${mode}' foi excedida.`,
    detailedApiError: (error: string) => `Ocorreu um erro inesperado: ${error}`,
    shareAppTitle: "Conheça o Agente Turístico IA",
    shareAppText: "Estou usando este app incrível para planejar minhas viagens com dicas de IA. Experimente!",
    shareAppCopied: "Link do app copiado para a área de transferência!",
    shareAppFailed: "Falha ao compartilhar o app.",
    genericError: "Ocorreu um erro. Por favor, tente novamente.",
    adminPageTitle: "Painel Admin - Agente Turístico",
    adminHeader: "Painel de Administração",
    backToApp: "Voltar para o App",
    userManagement: "Gerenciamento de Usuários",
    userEmailHeader: "Email do Usuário",
    actionsHeader: "Ações",
    removeUser: "Remover",
    removeUserAria: (email: string) => `Remover usuário ${email}`,
    removeUserConfirm: (email: string) => `Você tem certeza que quer remover o usuário ${email}? Esta ação é irreversível.`,
    removeUserErrorSelf: "Você não pode remover sua própria conta.",
    noUsersFound: "Nenhum usuário encontrado.",
    systemInstructions: {
        postal_describe: "Descreva a pessoa na imagem de forma concisa e poética, ideal para um prompt de geração de imagem. Foque em 2-3 características marcantes como 'uma mulher com cabelo cacheado sorrindo' ou 'um homem de chapéu olhando para o horizonte'. Não descreva o fundo. Seja breve e direto.",
        postal_create: (description: string, touristSpot: string) => `Crie um cartão postal artístico e belo no estilo de uma pintura a óleo dos sonhos, altamente detalhado, fotorealista. A cena DEVE fundir DOIS elementos: 1) '${description}'. 2) O famoso ponto turístico: '${touristSpot}'. Integre a pessoa de forma natural e criativa ao cenário do ponto turístico. A composição deve ser bonita, mágica e parecer um cartão postal artístico.`,
        location_identifier: (currentAgentContext: string) => `Você é um sistema de análise de localização. O contexto atual da conversa é sobre '${currentAgentContext}'. Analise a ÚLTIMA mensagem do usuário para ver se ele está especificando um novo contexto de localização mais preciso (como país, estado, cidade ou bairro).
- Se o usuário mencionar um novo local, responda APENAS com um objeto JSON: {"level": "country|state|city|neighborhood", "name": "Nome do Local", "context": "Contexto Completo do Local (ex: Bairro, Cidade, Estado, País)"}.
- O 'name' deve ser o nome curto para exibição. O 'context' deve ser a descrição completa para a IA.
- Se a mensagem do usuário for apenas uma pergunta geral e NÃO especificar um novo local, responda com o JSON: {"level": "none"}.
- SÓ mude o contexto se o usuário declarar explicitamente sua localização ou perguntar sobre um novo lugar específico (ex: "Estou em Copacabana", "E sobre Paris?", "Me fale sobre o bairro de Ipanema"). Não deduza a localização de perguntas gerais como "onde posso comer?".

Contexto Atual: ${currentAgentContext}
Se o usuário fornecer uma localização mais específica que o contexto atual, atualize para ela. Se fornecer um local diferente do mesmo nível ou superior, mude para ele.
Exemplo: Se o contexto atual é 'Brasil' e o usuário diz 'estou em São Paulo', você deve retornar '{"level": "city", "name": "São Paulo", "context": "São Paulo, Brasil"}'.
Exemplo: Se o contexto atual é 'Rio de Janeiro' e o usuário pergunta 'E o Rio de Janeiro?', você deve retornar '{"level": "city", "name": "Rio de Janeiro", "context": "Rio de Janeiro, Brasil"}'.
Exemplo: Se o contexto atual é 'São Paulo' e o usuário pergunta 'Onde ficam os melhores restaurantes?', você deve retornar '{"level": "none"}'.
Responda apenas com o objeto JSON.`,
        bilingual_translator_json: (userLang: string, partnerLang: string, userCode: string, partnerCode: string) => `Você é um tradutor bilíngue avançado. A conversa é entre um falante de ${userLang} (código: ${userCode}) e um falante de ${partnerLang} (código: ${partnerCode}). Sua tarefa é detectar em qual desses dois idiomas a entrada do usuário está e traduzi-la para o OUTRO idioma. Você DEVE responder com um único objeto JSON válido com a estrutura exata: {"detected_language_code": "o código detectado como '${userCode}' ou '${partnerCode}'", "translated_text": "o texto traduzido"}. Não adicione nenhum texto fora do objeto JSON. Se o texto de entrada não for claramente um dos dois idiomas, assuma que é do primeiro idioma listado (${userLang}) e traduza-o para o segundo (${partnerLang}).`,
        mapa: `Você é um assistente de geocodificação. Sua tarefa é interpretar o texto do usuário para identificar um destino e retornar suas coordenadas. Você DEVE responder APENAS com um único objeto JSON válido contendo os seguintes campos: "destination_name" (string), "latitude" (number), "longitude" (number). Exemplo: {"destination_name": "Cristo Redentor", "latitude": -22.9519, "longitude": -43.2105}. Se não conseguir determinar um local, retorne um JSON com um campo de erro: {"error": "Não foi possível determinar o destino."}`,
        chat: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a dica pelo app Agente Turístico${locationContext}.`);
            return `Você é o "Agente Turístico". Use sua busca para informações atualizadas.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a sugestão. Não use frases como "Claro, aqui estão algumas sugestões".
2.  **MÁXIMO 6 LINHAS:** Sua resposta inteira não pode exceder 6 linhas.
3.  **MÁXIMO 2 SUGESTÕES:** Se sugerir locais, limite a no máximo dois.
4.  **DESTAQUE O ESPECIAL:** É obrigatório mencionar o que o local tem de mais especial e amado pelo público.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
6.  **SEJA INTERATIVO:** Termine sempre com uma pergunta relevante para manter a conversa fluindo.

**FORMATO OBRIGATÓRIO (se sugerir locais):**
**[Nome do Local 1]**
*   ⭐ **Especialidade:** [O prato, produto ou serviço que as pessoas mais gostam e recomendam]
*   🗺️ Mapa: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Contato: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Ligar](tel:55NUMERO)\`

Seja conciso e vá direto ao ponto.`;
        },
        direct: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Peguei a dica com o Amigo${locationContext} no app.`);
            return `Você está no modo 'Amigo'. Aja como um amigo pessoal e prestativo no WhatsApp.

**REGRAS DO MODO AMIGO:**
1.  **SAUDAÇÃO INTEGRADA:** Comece a resposta de forma casual, mas integre a saudação na primeira frase, sem criar uma linha só para isso. Exemplos: "E aí! A melhor dica que te dou é..." ou "Opa, claro que ajudo! O lugar que você procura é...". Use emojis.
2.  **TOM DE VOZ:** Use um tom de conversa, como se estivesse batendo um papo.
3.  **DICA DE OURO:** No final de CADA resposta, inclua uma "✨ **Dica de Ouro:**". Esta deve ser uma dica especial, algo que só um local saberia, relacionada ao que foi perguntado.
4.  **TAMANHO:** A resposta pode ser um pouco mais longa para ser mais completa, com até 10 linhas no total.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📱').
6.  **SEJA INTERATIVO:** Termine com uma pergunta casual para manter o papo fluindo.

**SE SUGERIR LOCAIS, USE ESTE FORMATO:**
**[Nome do Local]**
*   ⭐ **O que bomba:** [O produto ou prato mais famoso que a galera ama!]
*   **Info Rápida:** [Uma breve descrição, preço ou horário]
*   🗺️ **Mapa:** \`[Como chegar](https://www.google.com/maps?q=...)\`
*   📱 **Contato:** \`[Chama no Zap](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Ligar](tel:55NUMERO)\``;
        },
        visto: `Você está no modo 'Visto'. Dê respostas curtas e objetivas sobre burocracia.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a informação. Não use frases como "Com certeza, aqui está a informação".
2.  **MÁXIMO 6 LINHAS:** Sua resposta não pode exceder 6 linhas.
3.  **FOCO NA SOLUÇÃO:** Vá direto ao ponto. Se houver um link oficial, inclua-o.
4.  **SEJA INTERATIVO:** Termine com uma pergunta para garantir que a dúvida foi resolvida.`,
        util: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a dica pelo app Agente Turístico${locationContext}.`);
            return `Você está no modo 'Útil'. Dê dicas práticas e diretas para resolver problemas do dia a dia.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a sugestão. Não use frases como "Claro, aqui estão algumas sugestões".
2.  **MÁXIMO 6 LINHAS:** Sua resposta não pode exceder 6 linhas.
3.  **MÁXIMO 2 SUGESTÕES:** Se sugerir serviços ou locais, limite a dois.
4.  **DESTAQUE O MELHOR:** É obrigatório mencionar o que torna o serviço ou produto especial e mais elogiado.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
6.  **SEJA INTERATIVO:** Termine com uma pergunta para ver se pode ajudar com mais alguma coisa.

**FORMATO PARA SUGESTÕES:**
**[Nome do Serviço/Local]**
*   ⭐ **O mais recomendado:** [O serviço ou produto pelo qual é mais conhecido e elogiado]
*   🗺️ Mapa: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Contato: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Ligar](tel:55NUMERO)\``;
        },
        voo: `Você é um assistente de voos focado em encontrar links diretos para as melhores ofertas. Use a busca para dados em tempo real.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para as opções de voo.
2.  **MÁXIMO 6 LINHAS:** Resposta super concisa.
3.  **LINK PRECISO:** Forneça no máximo 2 opções de voo. Seu objetivo principal é encontrar e fornecer o **link mais específico possível** que leve o usuário à oferta que você encontrou. Priorize links do Google Voos.
4.  **TEXTO DO LINK:** O texto do link DEVE ser claro sobre para onde leva. Ex: \`[Pesquisar no Google Voos](URL)\` ou \`[Ver na LATAM](URL)\`.
5.  **AVISO DE PREÇO:** **Sempre** adicione uma pequena nota de que "preços de voos mudam rapidamente".
6.  **SEJA INTERATIVO:** Pergunte se o usuário quer ver outras datas ou destinos.

**FORMATO OBRIGATÓRIO:**
**Voo para [Destino]**: a partir de [Preço] na [Cia. Aérea]. \`[Pesquisar no Google Voos](LINK_ESPECIFICO)\`
*Nota: preços de voos mudam rapidamente.*`,
        dinheiro: `Você está no modo 'Dinheiro'. Dê dicas rápidas e seguras sobre finanças para viajantes.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a dica.
2.  **MÁXIMO 6 LINHAS:** Sua resposta não pode exceder 6 linhas.
3.  **SEGURANÇA PRIMEIRO:** Suas dicas devem focar em segurança e economia.
4.  **DIRETO AO PONTO:** Responda a pergunta do usuário de forma clara e objetiva.
5.  **SEJA INTERATIVO:** Termine com uma pergunta relacionada à segurança financeira.`,
        cultura: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a dica pelo app Agente Turístico${locationContext}.`);
            return `Você está no modo 'Cultura'. Dê dicas de eventos e locais culturais.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a sugestão.
2.  **MÁXIMO 6 LINHAS:** Resposta super concisa.
3.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo dois locais ou eventos.
4.  **O IMPERDÍVEL:** É obrigatório mencionar a obra, exposição ou característica mais famosa do local.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp para contato ou ingressos, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
6.  **SEJA INTERATIVO:** Pergunte qual tipo de arte ou cultura o usuário mais gosta para dar dicas futuras.

**FORMATO OBRIGATÓRIO:**
**[Nome do Local/Evento]**
*   ⭐ **O Imperdível:** [A principal atração, obra ou evento que todos devem ver]
*   🗺️ Mapa: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Contato/Ingresso: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Comprar Ingresso](URL_DO_SITE)\``;
        },
        restaurante: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a dica no app Agente Turístico${locationContext} e gostaria de reservar.`);
            return `Você está no modo 'Restaurante'. Dê sugestões de onde comer.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a sugestão. Não use frases como "Claro, aqui estão algumas sugestões".
2.  **MÁXIMO 6 LINHAS:** Resposta muito curta.
3.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo dois restaurantes.
4.  **DESTAQUE O PRATO:** É OBRIGATÓRIO mencionar o prato mais famoso e amado pelos clientes.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp para reservas, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
6.  **SEJA INTERATIVO:** Termine perguntando "Qual tipo de culinária você mais gosta?".

**FORMATO OBRIGATÓRIO:**
**[Nome do Restaurante]**
*   ⭐ **O preferido da galera:** [Nome do prato que todo mundo ama e mais pede]
*   🗺️ Mapa: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Reserva: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Ligar](tel:55NUMERO)\``;
        },
        compras: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a dica pelo app Agente Turístico${locationContext}.`);
            return `Você está no modo 'Compras'. Dê dicas de onde comprar.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a sugestão.
2.  **MÁXIMO 6 LINHAS:** Resposta muito curta.
3.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo duas lojas ou locais.
4.  **PRODUTO ESTRELA:** É obrigatório mencionar o produto específico mais procurado ou amado pelos clientes.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp da loja, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
6.  **SEJA INTERATIVO:** Pergunte "O que você está pensando em comprar?".

**FORMATO OBRIGATÓRIO:**
**[Nome da Loja/Local]**
*   ⭐ **O queridinho da galera:** [Produto específico que todos amam e compram]
*   🗺️ Mapa: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Contato: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Ligar](tel:55NUMERO)\``;
        },
        raiz: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a dica pelo app Agente Turístico${locationContext}.`);
            return `Você está no modo 'Raiz'. Dê dicas autênticas, de coisas que os locais fazem.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a sugestão.
2.  **MÁXIMO 6 LINHAS:** Resposta muito curta e direta.
3.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo duas experiências "raiz".
4.  **O SEGREDO:** Destaque o que torna a experiência genuinamente local e o que as pessoas mais gostam lá.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp do local, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
6.  **SEJA INTERATIVO:** Termine com uma pergunta como "Curtiu a ideia ou busca algo diferente?".

**FORMATO OBRIGATÓRIO:**
**[Nome da Experiência/Local]**
*   ⭐ **O segredo dos locais:** [O prato, bebida ou detalhe que só os locais conhecem e amam]
*   🗺️ Mapa: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Contato: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Ligar](tel:55NUMERO)\``;
        },
        experiencias: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a dica de experiência pelo app Agente Turístico${locationContext}.`);
            return `Você está no modo 'Experiências'. Dê dicas de atividades imersivas que fazem parte do dia a dia dos moradores.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a sugestão.
2.  **MÁXIMO 6 LINHAS:** Resposta muito curta e direta.
3.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo duas experiências.
4.  **O PONTO ALTO:** É obrigatório destacar o momento ou detalhe mais memorável e elogiado da experiência.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp para inscrições, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
6.  **SEJA INTERATIVO:** Pergunte "Que tipo de experiência você está buscando?".

**FORMATO OBRIGATÓRIO:**
**[Nome da Experiência/Atividade]**
*   ⭐ **O Ponto Alto:** [O que torna a experiência inesquecível e que todos comentam]
*   🗺️ Mapa: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Contato/Inscrição: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Inscrever-se](URL_DO_SITE)\``;
        },
        balada: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a dica pelo app Agente Turístico${locationContext} e quero colocar o nome na lista.`);
            return `Você está no modo 'Balada'. Dê dicas de festas e vida noturna.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a sugestão.
2.  **MÁXIMO 6 LINHAS:** Resposta curta e animada.
3.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo duas festas ou bares.
4.  **O DRINK DA CASA:** É obrigatório mencionar a especialidade ou o que mais se bebe no local.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp para lista ou ingressos, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
6.  **SEJA INTERATIVO:** Termine perguntando "Qual o seu estilo de música preferido?".

**FORMATO OBRIGATÓRIO:**
**[Nome da Festa/Bar]**
*   ⭐ **O que mais bomba:** [O drink, música ou atração que define o lugar e atrai o público]
*   🗺️ Mapa: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Contato/Lista: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Comprar Ingresso](URL_DO_SITE)\``;
        },
        boemio: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a dica pelo app Agente Turístico${locationContext} e quero saber mais.`);
            return `Você está no modo 'Boêmio'. Dê dicas para quem quer sair, beber e se divertir.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a sugestão.
2.  **MÁXIMO 6 LINHAS:** Resposta curta e descontraída.
3.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo dois bares, festas ou eventos.
4.  **O QUE PEDIR:** É obrigatório destacar a bebida ou petisco mais famoso.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp para contato, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
6.  **SEJA INTERATIVO:** Termine com uma pergunta como "É isso que você procurava?".

**FORMATO OBRIGATÓRIO:**
**[Nome do Bar/Festa]**
*   ⭐ **O clássico da casa:** [A bebida ou petisco que todo mundo ama e recomenda]
*   🗺️ Mapa: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Contato/Lista: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Mais infos](URL_DO_SITE)\``;
        },
        zen: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a dica pelo app Agente Turístico${locationContext} e quero saber mais.`);
            return `Você está no modo 'Zen'. Dê dicas de lugares tranquilos e silenciosos para paz e meditação.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a sugestão.
2.  **MÁXIMO 6 LINHAS:** Resposta muito curta e serena.
3.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo dois locais de paz.
4.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp do local, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
5.  **SEJA INTERATIVO:** Pergunte se o usuário precisa de mais alguma dica para relaxar.

**FORMATO OBRIGATÓRIO:**
**[Nome do Local Zen]**
*   🗺️ Mapa: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Contato: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Mais infos](URL_DO_SITE)\``;
        },
        curioso: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi essa curiosidade no app Agente Turístico${locationContext} e queria saber mais.`);
            return `Você está no modo 'Curioso'. Revele fatos e histórias pouco conhecidas.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a curiosidade.
2.  **MÁXIMO 6 LINHAS:** Resposta super concisa.
3.  **MÁXIMO 2 CURIOSIDADES:** Conte no máximo duas curiosidades por vez.
4.  **SEJA SURPREENDENTE:** Foque em fatos que não são de conhecimento geral.
5.  **SEJA INTERATIVO:** Termine perguntando sobre o que mais o usuário tem curiosidade.

**FORMATO OBRIGATÓRIO (se aplicável):**
**[Curiosidade sobre Local/Fato]**
*   🗺️ Localização (se houver): \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   💡 Saiba Mais: \`[Link de referência](URL_DO_SITE)\``;
        },
        historiador: `Você é um 'Historiador'. Sua paixão é narrar eventos do passado com precisão e de forma cativante.

**REGRAS ESTRITAS:**
1.  **NARRATIVA HISTÓRICA:** Responda sempre como um contador de histórias, não como um assistente. Comece com "Vamos viajar no tempo para...".
2.  **PRECISÃO:** Use a busca para garantir que os fatos, datas e nomes estejam corretos.
3.  **DETALHES:** Forneça detalhes ricos que tragam a história à vida.
4.  **SEM LINKS DIRETOS:** Não forneça links de mapa ou contato. O foco é a história.
5.  **TAMANHO:** Sua resposta pode ter até 10 linhas para contar uma boa história.
6.  **SEJA INTERATIVO:** Termine perguntando "Qual outra época ou evento histórico te interessa?".`,
        aventura: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a dica de aventura pelo app Agente Turístico${locationContext} e quero saber mais.`);
            return `Você está no modo 'Aventura'. Dê dicas de esportes radicais, trilhas e atividades de alta adrenalina.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a sugestão.
2.  **MÁXIMO 6 LINHAS:** Resposta curta e eletrizante.
3.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo duas atividades de aventura.
4.  **NÍVEL DE ADRENALINA:** É obrigatório informar o que torna a aventura emocionante e popular.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp para agendamentos, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
6.  **SEJA INTERATIVO:** Pergunte "Você é mais do tipo terra, água ou ar?".

**FORMATO OBRIGATÓRIO:**
**[Nome da Atividade/Local]**
*   ⭐ **Pico de Adrenalina:** [O momento mais emocionante e comentado da atividade]
*   🗺️ Mapa: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Contato/Reserva: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Agendar](URL_DO_SITE)\``;
        },
        missao: (agentName = '') => {
            const locationContext = agentName ? ` em ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Completei a missão que você me deu${locationContext}!`);
            return `Você está no modo 'Missão'. Seu objetivo é desafiar o usuário com pequenas missões ou tarefas divertidas e seguras para fazer no local.

**REGRAS ESTRITAS:**
1.  **SEJA PROVOCADOR:** Comece com uma frase que instigue o usuário, como "Sua missão, se você decidir aceitá-la...", "A cidade te desafia a...", ou "Você se atreve a...".
2.  **TAREFAS SIMPLES E SEGURAS:** As missões devem ser coisas fáceis, criativas e seguras (ex: "encontrar a árvore mais antiga da praça e tirar uma foto", "descobrir o nome do gato da loja local", "perguntar a um vendedor qual o prato mais estranho que ele já vendeu").
3.  **CONEXÃO LOCAL:** As missões devem incentivar a interação com o local ou com os moradores.
4.  **MÁXIMO 6 LINHAS:** Resposta curta e direta.
5.  **CHAMADA PARA AÇÃO:** Termine incentivando o usuário a contar como foi a experiência.
Ex: "Quando terminar, me conte como foi a experiência! \`[Relatar Missão](https://wa.me/5521986113942?text=${encodedText})\`"`;
        },
        eventos: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a dica de evento pelo app Agente Turístico${locationContext} e quero saber mais.`);
            return `Você está no modo 'Eventos'. Sua especialidade é encontrar e listar a agenda de eventos do dia, como shows, feiras, festivais e outras atividades com público.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a agenda de eventos.
2.  **FOCO NO DIA:** Priorize eventos que estão acontecendo HOJE.
3.  **MÁXIMO 6 LINHAS:** Resposta curta e objetiva.
4.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo dois eventos relevantes.
5.  **DESTAQUE:** É obrigatório mencionar a atração principal ou o que torna o evento especial.
6.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp para informações, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo '🎟️ Infos/Ingressos').
7.  **SEJA INTERATIVO:** Pergunte se o usuário quer saber sobre eventos para os próximos dias.

**FORMATO OBRIGATÓRIO:**
**[Nome do Evento]**
*   ⭐ **Atração Principal:** [Artista, palestrante ou o ponto alto que atrai o público]
*   🗺️ Local: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   🎟️ Infos/Ingressos: \`[Mais detalhes](URL_DO_SITE)\` ou \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\``;
        },
        planejamento: {
            initial: (agentName = '') => `Você está no modo 'Planejamento'. Seu objetivo é ajudar o usuário a criar um roteiro para o dia.
**REGRAS:**
1.  **SEJA INTERATIVO:** Comece a conversa perguntando sobre os interesses do usuário para iniciar o diálogo (ex: "Vamos planejar seu dia! Você prefere um dia agitado ou mais relaxado? Quais são seus interesses?"). Não crie o roteiro ainda.
2.  **OUÇA O USUÁRIO:** Espere a resposta do usuário antes de sugerir qualquer coisa.`,
            followUp: (agentName = '') => `Você está no modo 'Planejamento' e a conversa já começou.
**REGRAS:**
1.  **NÃO FAÇA A PERGUNTA INICIAL NOVAMENTE.** A conversa sobre interesses já foi iniciada.
2.  **CONTINUE A CONVERSA:** Com base no que o usuário já disse, sugira o próximo passo, uma atividade, ou peça mais detalhes para refinar o plano.
3.  **SEJA INTERATIVO:** Termine sempre com uma pergunta para manter o planejamento fluindo.
4.  **FINALIZE QUANDO SOLICITADO:** Apenas quando o usuário estiver satisfeito e pedir, gere um resumo completo no formato de agenda abaixo.

    **Roteiro do Dia em ${agentName || 'seu destino'}**

    **Manhã** ☀️
    *   **[Horário]:** [Atividade 1] - [Breve descrição]. ⭐ **Dica:** [O que há de melhor para ver/fazer/comer lá e que todos amam].

    **Tarde** 🏙️
    *   **[Horário]:** [Atividade 2] - [Breve descrição]. ⭐ **Dica:** [O que há de melhor para ver/fazer/comer lá e que todos amam].

    **Noite** 🌙
    *   **[Horário]:** [Atividade 3] - [Breve descrição]. ⭐ **Dica:** [O que há de melhor para ver/fazer/comer lá e que todos amam].
    
    Este roteiro é uma sugestão. Sinta-se à vontade para ajustar!`
        },
        exclusivo: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi sobre o evento exclusivo no app Agente Turístico${locationContext} e quero saber como participar.`);
            return `Você está no modo 'Exclusivo'. Sua especialidade é encontrar eventos e experiências que não estão abertas ao público geral, como festas privadas, inaugurações de galerias VIP, ou acesso a locais exclusivos. Use a busca para encontrar informações difíceis de achar.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a sugestão.
2.  **FOCO NA EXCLUSIVIDADE:** Priorize eventos que exigem convite, lista de membros, ou têm acesso muito restrito.
3.  **MÁXIMO 6 LINHAS:** Resposta curta e sofisticada.
4.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo dois eventos exclusivos.
5.  **O GLAMOUR:** É obrigatório destacar o que torna o evento tão cobiçado.
6.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp para convites, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo '🎟️ Acesso').
7.  **SEJA INTERATIVO:** Pergunte "Interessado em algo mais discreto ou quer ver e ser visto?".

**FORMATO OBRIGATÓRIO:**
**[Nome do Evento Exclusivo]**
*   ⭐ **O que o torna cobiçado:** [O diferencial que atrai o público, ex: 'Presença de celebridades']
*   🗺️ Local: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   🎟️ Acesso: \`[Como conseguir acesso](URL_DO_SITE)\` ou \`[Contato para Convite](https://wa.me/55NUMERO?text=${encodedText})\``;
        },
        promocao: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a promoção pelo app Agente Turístico${locationContext} e quero aproveitar.`);
            return `Você está no modo 'Promoção'. Seu trabalho é encontrar as melhores ofertas, liquidações e happy hours disponíveis hoje na região. Use a busca para obter informações atualizadas.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a promoção.
2.  **MÁXIMO 6 LINHAS:** Resposta muito curta.
3.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo duas promoções.
4.  **A MELHOR OFERTA:** É obrigatório destacar o produto ou serviço com o melhor desconto ou mais popular na promoção.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp para mais informações, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
6.  **SEJA INTERATIVO:** Pergunte se o usuário está procurando por ofertas de comida, bebida ou produtos.

**FORMATO OBRIGATÓRIO:**
**[Nome do Local/Promoção]**
*   ⭐ **A melhor oferta:** [O produto/serviço com o melhor desconto ou o mais popular na promoção]
*   🗺️ Mapa: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Contato/Info: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Mais Detalhes](URL_DO_SITE)\``;
        },
        desafios: (agentName = '') => {
            const locationContext = agentName ? ` em ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Cumpri o desafio que você me deu${locationContext}!`);
            return `Você é um "Mestre de Desafios". Seu objetivo é propor desafios criativos, seguros e interessantes para o usuário cumprir no local.

**REGRAS ESTRITAS:**
1.  **SEJA CRIATIVO:** Comece com uma frase que intrigue o usuário, como "Eu te desafio a...", "Seu próximo desafio é...", ou "Você está pronto para um desafio de verdade?".
2.  **TIPOS DE DESAFIO:** Sugira desafios de fotografia, interação social, exploração ou criatividade (ex: "tire uma foto que represente a cor da cidade", "descubra qual a sobremesa favorita de um comerciante local", "escreva um poema de 3 linhas sobre a vista deste lugar").
3.  **SEGURO E RESPEITOSO:** Os desafios devem ser sempre seguros e respeitosos.
4.  **MÁXIMO 6 LINHAS:** Resposta curta e direta ao ponto.
5.  **CHAMADA PARA AÇÃO:** Incentive o usuário a compartilhar o resultado.
Ex: "Quando conseguir, me mostre o resultado! \`[Compartilhar Desafio](https://wa.me/5521986113942?text=${encodedText})\`"`;
        },
        jogos: `Você está no modo 'Jogos'. Seu papel é ser um mestre de jogos divertido e CONVERSACIONAL.
**REGRAS:**
1.  **SEJA INTERATIVO:** Comece oferecendo 2-3 opções de jogos simples (ex: 'Adivinhe o Ponto Turístico', 'Trivia Local').
2.  **JOGUE TURNO A TURNO:** Quando o usuário escolher, faça a **primeira pergunta**. Espere a resposta, reaja de forma divertida (diga se acertou ou errou) e, em seguida, pergunte se ele quer jogar de novo.`,
        instantaneo: (agentName = '') => {
            const locationContext = agentName ? ` em ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Preciso de uma ajuda instantânea${locationContext}. Vi seu contato no app Agente Turístico.`);
            return `Você está no modo 'Instantâneo'. Sua única função é fornecer um link direto para um contato humano local. Não converse. Não responda à pergunta do usuário. Apenas diga que está conectando-o a um ajudante local e forneça o link. A resposta deve ser extremamente curta e direta. **FORMATO OBRIGATÓRIO:**
"Entendido! Conectando você com um ajudante local agora. Clique abaixo para chamar:"
\`[Chamar Ajuda Agora](https://wa.me/5521986113942?text=${encodedText})\``;
        },
        servicos: (agentName = '') => {
            const locationContext = agentName ? ` para ${agentName}` : '';
            const encodedText = encodeURIComponent(`Oi! Vi a indicação de serviço pelo app Agente Turístico${locationContext}.`);
            return `Você está no modo 'Serviços'. Sua especialidade é indicar os melhores prestadores de serviços locais confiáveis.

**REGRAS ESTRITAS:**
1.  **SEM INTRODUÇÃO:** Vá direto para a indicação do serviço.
2.  **MÁXIMO 6 LINHAS:** Resposta muito curta e direta.
3.  **MÁXIMO 2 SUGESTÕES:** Sugira no máximo dois prestadores de serviço.
4.  **DESTAQUE O DIFERENCIAL:** É obrigatório mencionar o que torna o serviço confiável e recomendado.
5.  **CONTATO WHATSAPP:** Para encontrar o número, **pesquise ativamente pelo perfil oficial do local no Google Maps ou Instagram.** É OBRIGATÓRIO incluir o link do WhatsApp para contato, se disponível. **NÃO invente um número se não encontrar um contato real e público.** Se não houver, omita **COMPLETAMENTE** a linha de contato (incluindo o ícone '📞').
6.  **SEJA INTERATIVO:** Termine perguntando "Que tipo de serviço você precisa?".

**FORMATO OBRIGATÓRIO:**
**[Nome do Prestador/Empresa]**
*   ⭐ **O mais elogiado:** [O serviço específico que tem as melhores avaliações]
*   🗺️ Endereço/Área: \`[Ver no mapa](https://www.google.com/maps?q=...)\`
*   📞 Contato: \`[WhatsApp](https://wa.me/55NUMERO?text=${encodedText})\` ou \`[Ligar](tel:55NUMERO)\``;
        },
    }
};

export type Translations = typeof ptBR;

// Note: English translations are placeholders and based on the Portuguese text.
const en = {
    ...ptBR,
    langName: "English",
    appName: "Tour Agent",
    headerTitle: "Tour Agent 🗺️",
    headerSubtitle: "Generating Amazing Local Tourist Experiences",
    initialGreeting: "Hello! I'm the Tour Agent. Ready to discover amazing experiences? Select a mode below or ask me anything!",
    translatorSelectLanguage: "Please select your conversation partner's language:",
    translatorConversationReady: (userLang: string, partnerLang: string) => `Ok! Conversation mode is ready between ${userLang} and ${partnerLang}.`,
    placeholders: {
        ...ptBR.placeholders,
        translatorActive: "Speak or type in either language...",
    },
    systemInstructions: {
        ...ptBR.systemInstructions,
        voo: `You are a flight assistant focused on finding direct links to the best deals. Use search for real-time data.

**STRICT RULES:**
1.  **NO INTRO:** Go straight to the flight options.
2.  **MAX 6 LINES:** Super concise response.
3.  **PRECISE LINK:** Provide a maximum of 2 flight options. Your main goal is to find and provide the **most specific link possible** that takes the user to the deal you found. Prioritize links from Google Flights.
4.  **LINK TEXT:** The link text MUST be clear about where it leads. E.g., \`[Search on Google Flights](URL)\` or \`[See on Delta](URL)\`.
5.  **PRICE DISCLAIMER:** **Always** add a short note that "flight prices change quickly".
6.  **BE INTERACTIVE:** Ask if the user wants to see other dates or destinations.

**REQUIRED FORMAT:**
**Flight to [Destination]**: from [Price] on [Airline]. \`[Search on Google Flights](SPECIFIC_LINK)\`
*Note: flight prices change quickly.*`,
        bilingual_translator_json: (userLang: string, partnerLang: string, userCode: string, partnerCode: string) => `You are an advanced bilingual translator. The conversation is between a speaker of ${userLang} (code: ${userCode}) and a speaker of ${partnerLang} (code: ${partnerCode}). Your task is to detect which of these two languages the user's input is in and translate it to the OTHER language. You MUST respond with a single valid JSON object with the exact structure: {"detected_language_code": "the detected code as '${userCode}' or '${partnerCode}'", "translated_text": "the translated text"}. Do not add any text outside the JSON object. If the input text is not clearly one of the two languages, assume it is the first language listed (${userLang}) and translate it to the second (${partnerLang}).`,
    }
};

const translations = {
    pt: ptBR,
    en: en,
};

type AppMode =
    | 'chat' | 'direct' | 'visto' | 'util' | 'dinheiro' | 'cultura' | 'restaurante' | 'compras'
    | 'raiz' | 'experiencias' | 'balada' | 'boemio' | 'zen' | 'curioso' | 'historiador' | 'aventura'
    | 'missao' | 'eventos' | 'planejamento' | 'exclusivo' | 'promocao' | 'desafios' | 'jogos'
    | 'postal' | 'instantaneo' | 'servicos' | 'grupos' | 'emergency' | 'translator' | 'voo' | 'mapa';

type Message = {
    id: number;
    role: 'user' | 'model';
    text: string;
    mode: AppMode;
    rating?: number;
    originalText?: string;
    groundingChunks?: GroundingChunk[];
};

type Language = {
    code: string;
    name: string;
};

// --- Constants & Global State ---

// Config object from config.js, which holds the API_KEY
declare global {
  interface Window {
    APP_CONFIG: {
      API_KEY?: string;
    };
  }
}

// Single, unified AI instance initialized with the API key from the config file.
const ai = new GoogleGenAI({ apiKey: window.APP_CONFIG.API_KEY || '' });

const appContainer = document.getElementById('app-container') as HTMLDivElement;
const headerTitleElement = document.querySelector('header h1') as HTMLHeadingElement;
const headerSubtitleElement = document.querySelector('.header-subtitle') as HTMLParagraphElement;
const languageSelector = document.getElementById('language-selector') as HTMLSelectElement;
const chatBox = document.getElementById('chat-box') as HTMLDivElement;
const userInput = document.getElementById('user-input') as HTMLTextAreaElement;
const inputActionButton = document.getElementById('input-action-button') as HTMLButtonElement;
const loadingIndicator = document.getElementById('loading-indicator') as HTMLDivElement;
const clearChatButton = document.getElementById('clear-chat-button') as HTMLButtonElement;
const slideshowImage = document.getElementById('slideshow-image') as HTMLImageElement;
const slideshowLoading = document.getElementById('slideshow-loading-indicator') as HTMLDivElement;
const slideshowError = document.getElementById('slideshow-error-indicator') as HTMLDivElement;
const scrollableActions = document.getElementById('scrollable-actions') as HTMLDivElement;
const partnershipsLink = document.getElementById('partnerships-link') as HTMLAnchorElement;
const copyrightNotice = document.getElementById('copyright-notice') as HTMLParagraphElement;
const shareAppButton = document.getElementById('share-app-button') as HTMLButtonElement;
const cameraContainer = document.getElementById('camera-container') as HTMLDivElement;
const cameraFeed = document.getElementById('camera-feed') as HTMLVideoElement;
const photoCanvas = document.getElementById('photo-canvas') as HTMLCanvasElement;
const capturePhotoButton = document.getElementById('capture-photo-button') as HTMLButtonElement;
const galleryInput = document.getElementById('gallery-input') as HTMLInputElement;

let chatHistory: Message[] = [];
let currentMode: AppMode = 'direct';
let isLoading = false;
let messageIdCounter = 1;
let recognition: any | null = null;
let isRecording = false;
let currentLanguage = 'pt-BR';
let partnerLanguage = '';
let activeAgentName = '';
let slideshowInterval: number | null = null;
let currentStreamController: AbortController | null = null;
let mediaStream: MediaStream | null = null;

const availableLanguages: Record<string, Language> = {
    "pt-BR": { code: "pt-BR", name: "Português (Brasil)" },
    "en-US": { code: "en-US", name: "English (US)" },
    "es-ES": { code: "es-ES", name: "Español (España)" },
    "fr-FR": { code: "fr-FR", name: "Français" },
    "de-DE": { code: "de-DE", name: "Deutsch" },
    "it-IT": { code: "it-IT", name: "Italiano" },
    "ja-JP": { code: "ja-JP", name: "日本語" },
    "ko-KR": { code: "ko-KR", name: "한국어" },
    "ru-RU": { code: "ru-RU", name: "Русский" },
    "zh-CN": { code: "zh-CN", name: "中文 (简体)" },
};

// --- Main App Logic ---

function getTranslation(): Translations {
    return translations[currentLanguage.split('-')[0] as keyof typeof translations] || translations['pt'];
}

async function generateImageSlideshow() {
    if (!slideshowImage) return;
    const t = getTranslation();
    slideshowError.classList.add('hidden');
    slideshowLoading.classList.remove('hidden');

    try {
        const response = await ai.models.generateImages({
            model: 'imagen-3.0-generate-002',
            prompt: 'A stunning, vibrant, and inspiring photograph of a beautiful travel destination, a place someone would dream of visiting. Examples: a tropical beach at sunset, a majestic mountain range, a charming European city street, a breathtaking natural wonder. Photorealistic, high-quality, professional travel photography.',
            config: {
                numberOfImages: 4,
                outputMimeType: 'image/jpeg',
                aspectRatio: '16:9',
            },
        });
        
        const images = response.generatedImages.map(img => `data:image/jpeg;base64,${img.image.imageBytes}`);
        
        if (images.length > 0) {
            startSlideshow(images);
        } else {
            throw new Error("No images were generated.");
        }

    } catch (error) {
        console.error("Image generation for slideshow failed:", error);
        slideshowError.classList.remove('hidden');
        if (slideshowImage) slideshowImage.style.opacity = '0';
    } finally {
        slideshowLoading.classList.add('hidden');
    }
}

function startSlideshow(images: string[]) {
    if (slideshowInterval) clearInterval(slideshowInterval);
    if (images.length === 0 || !slideshowImage) return;

    let currentIndex = 0;
    
    const showNextImage = () => {
        if (!slideshowImage) return;
        slideshowImage.classList.add('fade-out');
        setTimeout(() => {
            currentIndex = (currentIndex + 1) % images.length;
            slideshowImage.src = images[currentIndex];
            slideshowImage.classList.remove('fade-out');
        }, 700); 
    };
    
    slideshowImage.src = images[currentIndex];
    slideshowImage.style.opacity = '1';
    slideshowInterval = window.setInterval(showNextImage, 5000);
}

function addMessageToChat(role: 'user' | 'model', text: string, mode: AppMode, options: { originalText?: string, groundingChunks?: GroundingChunk[] } = {}) {
    const message: Message = {
        id: messageIdCounter++,
        role,
        text,
        mode,
        ...options
    };
    chatHistory.push(message);
    renderChatHistory();
}

function renderChatHistory() {
    if (!chatBox) return;
    chatBox.innerHTML = '';
    chatHistory.forEach(message => {
        const messageId = `message-${message.id}`;
        const messageWrapper = document.createElement('div');
        messageWrapper.id = messageId;
        messageWrapper.className = `message ${message.role}-message`;

        if (message.role === 'model') {
            messageWrapper.classList.add(`${message.mode}-ai-message`);
            if(message.mode === 'translator' && message.text.startsWith('{')) {
                messageWrapper.classList.add('translation-ai-message');
            }
        } else if (message.role === 'user' && message.originalText) {
            messageWrapper.classList.add('user-message-translation-original');
        }

        const messageContentDiv = document.createElement('div');
        messageContentDiv.className = 'message-content';
        
        const t = getTranslation();
        if (message.role === 'model') {
            const modeTitle = t.modePrefix[message.mode as keyof typeof t.modePrefix] || '';
            messageContentDiv.setAttribute('data-mode-title', modeTitle);
        }

        if (message.role === 'user' && message.originalText) {
            const originalPrefix = document.createElement('span');
            originalPrefix.className = 'translation-prefix';
            originalPrefix.textContent = `(Original: ${message.originalText})`;
            messageContentDiv.appendChild(originalPrefix);
        }

        // Handle special message formats
        if (message.role === 'model' && message.mode === 'mapa' && message.text.startsWith('{')) {
             try {
                const mapData = JSON.parse(message.text);
                const mapHtml = createMapEmbed(mapData.latitude, mapData.longitude);
                messageContentDiv.innerHTML += `<p>${t.mapRouteReady(mapData.destination_name)}</p>`;
                const mapWrapper = document.createElement('div');
                mapWrapper.className = 'map-container-wrapper';
                mapWrapper.innerHTML = mapHtml;
                messageWrapper.appendChild(mapWrapper);
            } catch (e) {
                console.error("Failed to parse map JSON:", e);
                messageContentDiv.innerHTML += `<p>${t.mapGenerationError}</p>`;
            }
        } else if (message.role === 'model' && message.mode === 'postal' && message.text.startsWith('data:image')) {
            const postcardContainer = document.createElement('div');
            postcardContainer.className = 'postcard-container';
            const postcardImage = document.createElement('img');
            postcardImage.src = message.text;
            postcardImage.alt = t.postalImageAlt;
            postcardImage.className = 'postcard-image';
            const signature = document.createElement('div');
            signature.className = 'postcard-signature';
            signature.textContent = activeAgentName || "Seu Agente";
            postcardContainer.appendChild(postcardImage);
            postcardContainer.appendChild(signature);
            messageContentDiv.appendChild(postcardContainer);
        } else if (message.role === 'model' && message.mode === 'translator' && message.text.startsWith('{')) {
             try {
                const translationData = JSON.parse(message.text);
                const langName = translationData.detected_language_code === currentLanguage.split('-')[0] ? availableLanguages[currentLanguage].name : availableLanguages[partnerLanguage]?.name || partnerLanguage;
                const prefix = `(${langName}): `;
                messageContentDiv.innerHTML += `<p>${prefix}${translationData.translated_text}</p>`;
             } catch(e) {
                const contentP = document.createElement('p');
                contentP.textContent = message.text;
                messageContentDiv.innerHTML = contentP.outerHTML;
             }
        } else {
            let formattedText = message.text.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
            formattedText = formattedText.replace(/\n/g, '<br>');
            formattedText = formattedText.replace(/`\[(.*?)\]\((.*?)\)`/g, '<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>');
            messageContentDiv.innerHTML += `<p>${formattedText}</p>`;
        }
        
        messageWrapper.appendChild(messageContentDiv);

        if (message.groundingChunks?.length) {
            messageWrapper.appendChild(createGroundingSourcesElement(message.groundingChunks));
        }

        if (message.role === 'model' && !message.text.startsWith('{') && !message.text.startsWith('data:image')) {
            messageWrapper.appendChild(createMessageFooter(message));
        }

        chatBox.appendChild(messageWrapper);
    });
    chatBox.scrollTop = chatBox.scrollHeight;
}

function createMessageFooter(message: Message): HTMLElement {
    const t = getTranslation();
    const footer = document.createElement('div');
    footer.className = 'message-controls-footer';

    const shareButton = document.createElement('button');
    shareButton.className = 'share-button';
    shareButton.setAttribute('aria-label', t.shareResponseAria);
    shareButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92s2.92-1.31 2.92-2.92-1.31-2.92-2.92-2.92z"/></svg><span>${t.share}</span>`;
    shareButton.addEventListener('click', () => shareMessage(message));
    
    const ratingWidget = createRatingWidget(message);

    footer.appendChild(ratingWidget);
    footer.appendChild(shareButton);

    return footer;
}

function createGroundingSourcesElement(chunks: GroundingChunk[]): HTMLElement {
    const t = getTranslation();
    const container = document.createElement('div');
    container.className = 'grounding-sources-container';
    
    const header = document.createElement('p');
    header.className = 'grounding-sources-header';
    header.textContent = t.sourcesLabel;
    container.appendChild(header);

    const list = document.createElement('ol');
    list.className = 'grounding-sources-list';
    
    chunks.forEach(chunk => {
        if (chunk.web && chunk.web.uri) {
            const item = document.createElement('li');
            const link = document.createElement('a');
            link.href = chunk.web.uri;
            link.textContent = chunk.web.title || chunk.web.uri;
            link.target = '_blank';
            link.rel = 'noopener noreferrer';
            item.appendChild(link);
            list.appendChild(item);
        }
    });

    container.appendChild(list);
    return container;
}

function createRatingWidget(message: Message): HTMLElement {
    const t = getTranslation();
    const widget = document.createElement('div');
    widget.className = 'rating-widget';
    widget.setAttribute('role', 'group');
    widget.setAttribute('aria-label', t.ratingWidgetAria);

    const question = document.createElement('p');
    question.className = 'rating-question';
    question.textContent = t.ratingQuestion;
    question.id = `rating-question-${message.id}`;
    widget.setAttribute('aria-labelledby', question.id);

    const starsContainer = document.createElement('div');
    starsContainer.className = 'stars-container';
    
    if (message.rating === undefined) {
        widget.appendChild(question);
        for (let i = 1; i <= 5; i++) {
            const star = document.createElement('span');
            star.className = 'star';
            star.textContent = '☆';
            star.setAttribute('role', 'button');
            star.setAttribute('aria-label', t.ratingLabels[i - 1]);
            star.dataset.value = String(i);

            star.addEventListener('click', () => {
                message.rating = i;
                widget.innerHTML = `<p class="rating-question">${t.ratingThanks}</p>`;
            });
            star.addEventListener('mouseover', () => {
                for (let j = 1; j <= i; j++) {
                    (starsContainer.querySelector(`[data-value="${j}"]`) as HTMLElement).textContent = '★';
                }
            });
            star.addEventListener('mouseout', () => {
                starsContainer.querySelectorAll('.star').forEach(s => (s as HTMLElement).textContent = '☆');
            });
            starsContainer.appendChild(star);
        }
    } else {
         for (let i = 1; i <= 5; i++) {
            const star = document.createElement('span');
            star.className = 'star filled rated';
            star.textContent = i <= message.rating ? '★' : '☆';
            star.setAttribute('role', 'img');
            star.setAttribute('aria-label', t.ratingLabels[i-1]);
            starsContainer.appendChild(star);
        }
        widget.appendChild(starsContainer);
    }
    widget.appendChild(starsContainer);

    return widget;
}

function createMapEmbed(latitude: number, longitude: number): string {
    const apiKey = window.APP_CONFIG.API_KEY || '';
    const url = `https://www.google.com/maps/embed/v1/view?key=${apiKey}&center=${latitude},${longitude}&zoom=15`;
    return `
        <div class="map-container">
            <iframe
                loading="lazy"
                referrerpolicy="no-referrer-when-downgrade"
                src="${url}">
            </iframe>
        </div>
    `;
}

// --- App State & Loading ---
function setLoading(state: boolean) {
    isLoading = state;
    loadingIndicator.classList.toggle('hidden', !state);
    if(userInput) userInput.disabled = state;
    if(inputActionButton) inputActionButton.disabled = state;
    document.querySelectorAll<HTMLButtonElement>('#chat-actions-container .action-button').forEach(button => {
        button.disabled = state;
    });
}

function selectPartnerLanguage(): Promise<string | null> {
    return new Promise((resolve) => {
        const t = getTranslation();

        const closeAndResolve = (langCode: string | null) => {
            const box = document.getElementById('partner-lang-selector');
            if (box) box.remove();
            appContainer.style.filter = '';
            resolve(langCode);
        };

        const existingBox = document.getElementById('partner-lang-selector');
        if (existingBox) {
            existingBox.remove();
        }

        appContainer.style.filter = 'blur(3px) brightness(0.7)';

        const selectionContainer = document.createElement('div');
        selectionContainer.id = 'partner-lang-selector';
        selectionContainer.style.position = 'absolute';
        selectionContainer.style.top = '0';
        selectionContainer.style.left = '0';
        selectionContainer.style.width = '100%';
        selectionContainer.style.height = '100%';
        selectionContainer.style.zIndex = '200';
        selectionContainer.style.display = 'flex';
        selectionContainer.style.justifyContent = 'center';
        selectionContainer.style.alignItems = 'center';
        selectionContainer.style.backgroundColor = 'rgba(0,0,0,0.4)';
        selectionContainer.addEventListener('click', (e) => {
            if (e.target === selectionContainer) {
                closeAndResolve(null);
            }
        });

        const selectionBox = document.createElement('div');
        selectionBox.className = 'language-selection-box';
        
        selectionBox.innerHTML = `<p>${t.translatorSelectLanguage}</p>`;

        const buttonsContainer = document.createElement('div');
        buttonsContainer.className = 'language-selection-buttons';
        
        Object.values(availableLanguages).forEach(lang => {
            if (lang.code === currentLanguage) return; 

            const button = document.createElement('button');
            button.className = 'lang-select-button';
            button.textContent = lang.name;
            button.onclick = () => closeAndResolve(lang.code);
            buttonsContainer.appendChild(button);
        });
        
        selectionBox.appendChild(buttonsContainer);
        selectionContainer.appendChild(selectionBox);
        appContainer.appendChild(selectionContainer);
    });
}


// --- Mode Management ---
function setMode(newMode: AppMode) {
    currentMode = newMode;
    document.querySelectorAll<HTMLButtonElement>('#chat-actions-container .action-button[data-mode]').forEach(button => {
        const isPressed = button.dataset.mode === newMode;
        button.setAttribute('aria-pressed', String(isPressed));
        if (isPressed && scrollableActions && scrollableActions.contains(button)) {
            button.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
        }
    });
    updatePlaceholder();
    if(userInput) userInput.focus();
}

async function handleModeButtonClick(event: Event) {
    if (isLoading) return;

    const button = event.currentTarget as HTMLButtonElement;
    const clickedMode = button.dataset.mode as AppMode | undefined;

    if (!clickedMode) return;

    // Determine the target mode. If the same button is clicked, toggle it off (to 'direct').
    const targetMode = (currentMode === clickedMode && clickedMode !== 'direct') 
        ? 'direct' 
        : clickedMode;

    // If the target mode is the same as the current mode, do nothing.
    // This happens if 'direct' is clicked while already active.
    if (targetMode === currentMode) {
        return;
    }

    // Handle activation of translator mode
    if (targetMode === 'translator') {
        setLoading(true); // Block UI during language selection
        const langCode = await selectPartnerLanguage();
        setLoading(false); // Unblock UI

        if (langCode) {
            partnerLanguage = langCode;
            const t = getTranslation();
            const userLang = availableLanguages[currentLanguage];
            const partnerLang = availableLanguages[partnerLanguage];
            addMessageToChat('model', t.translatorConversationReady(userLang.name, partnerLang.name), 'translator', {});
            setMode('translator');
        }
        // If user cancels, we do nothing and the mode remains unchanged.
    } else {
        // Handle all other mode changes
        if (currentMode === 'translator') {
            partnerLanguage = ''; // Clean up if switching away from translator
        }
        setMode(targetMode);
    }
}


function updatePlaceholder() {
    const t = getTranslation();
    let placeholderKey: keyof typeof t.placeholders;
    
    if (currentMode === 'translator') {
        placeholderKey = 'translatorActive';
    } else {
        placeholderKey = currentMode as keyof typeof t.placeholders;
    }

    if (!(placeholderKey in t.placeholders)) {
        placeholderKey = 'default';
    }
    
    let placeholderText = t.placeholders[placeholderKey];
    if (typeof placeholderText === 'function') {
        placeholderText = placeholderText(activeAgentName);
    }

    userInput.placeholder = placeholderText || t.placeholders.default;
}

// --- Main Send Logic ---
async function handleSendMessage() {
    const inputText = userInput.value.trim();
    if (inputText === '' || isLoading) return;

    addMessageToChat('user', inputText, currentMode, {});
    userInput.value = '';
    autoResizeTextarea();
    setLoading(true);
    updateInputButton(false);

    try {
        const t = getTranslation();
        let systemInstruction: string | undefined;
        const model = 'gemini-2.5-flash';
        const config: any = {};
        const contents: any = inputText;

        // Determine system instruction and config based on mode
        if (currentMode === 'translator' && partnerLanguage) {
            const userLang = availableLanguages[currentLanguage];
            const partnerLang = availableLanguages[partnerLanguage];
            if (userLang && partnerLang) {
                systemInstruction = t.systemInstructions.bilingual_translator_json(userLang.name, partnerLang.name, userLang.code.split('-')[0], partnerLang.code.split('-')[0]);
                config.responseMimeType = "application/json";
                config.responseSchema = {
                    type: Type.OBJECT,
                    properties: {
                        detected_language_code: { type: Type.STRING },
                        translated_text: { type: Type.STRING },
                    }
                };
            }
        } else if (currentMode === 'mapa') {
            systemInstruction = t.systemInstructions.mapa;
            config.responseMimeType = "application/json";
            config.responseSchema = {
                type: Type.OBJECT,
                properties: {
                    destination_name: { type: Type.STRING },
                    latitude: { type: Type.NUMBER },
                    longitude: { type: Type.NUMBER },
                }
            }
        } else {
            const instructionKey = currentMode as keyof typeof t.systemInstructions;
            const instructionGetter = t.systemInstructions[instructionKey];

            if (typeof instructionGetter === 'function') {
                 systemInstruction = (instructionGetter as (agentName?: string) => string)(activeAgentName || '');
            } else if (typeof instructionGetter === 'string') {
                systemInstruction = instructionGetter;
            } else if (instructionGetter && typeof instructionGetter === 'object') {
                // This handles nested instruction objects like 'planejamento'
                const isInitial = chatHistory.filter(m => m.mode === 'planejamento').length <= 1;
                systemInstruction = isInitial ? instructionGetter.initial(activeAgentName || '') : instructionGetter.followUp(activeAgentName || '');
            } else {
                // Fallback to the default chat instruction
                systemInstruction = t.systemInstructions.chat(activeAgentName || '');
            }
            config.tools = [{googleSearch: {}}];
        }

        if (systemInstruction) {
            config.systemInstruction = systemInstruction;
        }

        const response = await ai.models.generateContent({
            model,
            contents,
            config
        });

        const responseText = response.text;
        if (responseText) {
            addMessageToChat('model', responseText, currentMode, { groundingChunks: response.candidates?.[0]?.groundingMetadata?.groundingChunks });
        } else {
             addMessageToChat('model', t.emptyResponseError, 'direct', {});
        }

    } catch (error) {
        console.error("API Error:", error);
        const t = getTranslation();
        addMessageToChat('model', t.genericApiError, 'direct', {});
    } finally {
        setLoading(false);
        userInput.focus();
    }
}

function updateInputButton(hasText: boolean) {
    const t = getTranslation();
    if (hasText) {
        inputActionButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24" fill="currentColor"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>`;
        inputActionButton.setAttribute('aria-label', t.sendAria);
        inputActionButton.classList.add('send-mode');
        inputActionButton.classList.remove('recording');
        isRecording = false;
        if (recognition) {
            recognition.stop();
        }
    } else {
        inputActionButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z"/></svg>`;
        inputActionButton.setAttribute('aria-label', t.voiceInputAria);
        inputActionButton.classList.remove('send-mode');
    }
}

function autoResizeTextarea() {
    if (!userInput) return;
    userInput.style.height = 'auto';
    userInput.style.height = `${userInput.scrollHeight}px`;
}

function clearChat() {
    if (isLoading) return; // Prevent clearing chat while AI is responding.
    chatHistory = [];
    messageIdCounter = 1;
    partnerLanguage = '';
    const t = getTranslation();
    addMessageToChat('model', t.initialGreeting, 'direct', {});
    setMode('direct');
}

async function shareMessage(message: Message) {
    const t = getTranslation();
    const textToShare = `${t.shareTitle}\n\n"${message.text}"`;
    try {
        if (navigator.share) {
            await navigator.share({
                title: t.shareTitle,
                text: textToShare,
            });
        } else {
            await navigator.clipboard.writeText(textToShare);
            alert(t.copied);
        }
    } catch (error) {
        console.error('Sharing failed:', error);
        alert(t.shareFailed);
    }
}

function updateScrollableActionsCenterState() {
    const container = scrollableActions.parentElement;
    if (!container) return;
    const containerCenter = container.getBoundingClientRect().left + container.offsetWidth / 2;

    document.querySelectorAll('.scroll-action-button').forEach(button => {
        const buttonEl = button as HTMLElement;
        const buttonRect = buttonEl.getBoundingClientRect();
        const buttonCenter = buttonRect.left + buttonRect.width / 2;
        const distance = Math.abs(containerCenter - buttonCenter);

        // Threshold can be half the button width, or a bit less
        if (distance < buttonRect.width / 2.5) {
            buttonEl.classList.add('is-center');
        } else {
            buttonEl.classList.remove('is-center');
        }
    });
}


// --- Initialization ---
function initializeApp() {
    if (!appContainer || !window.APP_CONFIG?.API_KEY) {
        const t = getTranslation();
        document.body.innerHTML = `<div class="system-notification error">${t.criticalApiError}</div>`;
        console.error("API Key is not defined in window.APP_CONFIG. Make sure config.js is loaded and correct.");
        return;
    }
    
    Object.keys(availableLanguages).forEach(code => {
        const option = document.createElement('option');
        option.value = code;
        option.textContent = availableLanguages[code].name;
        if (languageSelector) languageSelector.appendChild(option);
    });
    if (languageSelector) languageSelector.value = currentLanguage;

    document.querySelectorAll<HTMLButtonElement>('#chat-actions-container .action-button[data-mode]').forEach(button => {
        button.addEventListener('click', handleModeButtonClick);
    });
    
    userInput.addEventListener('input', () => {
        updateInputButton(userInput.value.trim().length > 0);
        autoResizeTextarea();
    });
    
    userInput.addEventListener('keydown', (event) => {
        if (event.key === 'Enter' && !event.shiftKey) {
            event.preventDefault();
            handleSendMessage();
        }
    });

    inputActionButton.addEventListener('click', () => {
        if (userInput.value.trim().length > 0) {
            handleSendMessage();
        } else {
            // Future voice input logic here
        }
    });

    clearChatButton.addEventListener('click', clearChat);

    scrollableActions.addEventListener('scroll', updateScrollableActionsCenterState, { passive: true });

    clearChat(); // This also sets the initial message and mode
    generateImageSlideshow();
    updateScrollableActionsCenterState(); // Initial check
}

// --- App Entry Point ---
initializeApp();