/**
 * Cloudflare Workers function for chatbot API
 * Proxies requests to Groq API using the secure API key from environment variables
 * Provides role-specific assistance based on user type (médico, paciente, secretária)
 */

interface Env {
  GROQ_API_KEY: string;
  SUPABASE_URL: string;
  SUPABASE_ANON_KEY: string;
}

interface ChatMessage {
  role: "user" | "assistant" | "system";
  content: string;
}

interface ChatRequest {
  messages: ChatMessage[];
  token?: string;
}

interface UserProfile {
  id: string;
  role: "medico" | "paciente" | "secretaria" | "admin";
  nome?: string;
  especialidade?: string;
}

async function getUserProfile(
  token: string,
  env: Env
): Promise<UserProfile | null> {
  try {
    const supabaseUrl =
      env.SUPABASE_URL || "https://yuanqfswhberkoevtmfr.supabase.co";

    // Get user from token
    const userResponse = await fetch(`${supabaseUrl}/auth/v1/user`, {
      headers: {
        Authorization: `Bearer ${token}`,
        apikey: env.SUPABASE_ANON_KEY,
      },
    });

    if (!userResponse.ok) return null;

    const user = await userResponse.json();

    // Get user profile from usuarios table
    const profileResponse = await fetch(
      `${supabaseUrl}/rest/v1/usuarios?id=eq.${user.id}&select=id,role,nome,especialidade`,
      {
        headers: {
          Authorization: `Bearer ${token}`,
          apikey: env.SUPABASE_ANON_KEY,
          "Content-Type": "application/json",
        },
      }
    );

    if (!profileResponse.ok) return null;

    const profiles = await profileResponse.json();
    return profiles[0] || null;
  } catch (error) {
    console.error("Error fetching user profile:", error);
    return null;
  }
}

function getRoleSpecificPrompt(profile: UserProfile | null): string {
  if (!profile) {
    return `Você é a Conni, a Assistente Virtual do MediConnect, uma plataforma de gestão médica.

SEU NOME: Conni - sempre se apresente como "Conni" quando perguntarem seu nome.

Suas responsabilidades:
- Responder dúvidas gerais sobre o sistema
- Explicar funcionalidades básicas
- Orientar sobre como fazer login
- Fornecer informações sobre agendamento de consultas

IMPORTANTE:
- NUNCA solicite ou processe dados sensíveis de pacientes (PHI)
- NUNCA forneça diagnósticos médicos
- Seja sempre educado, claro e objetivo
- Responda em português do Brasil`;
  }

  const baseRules = `
REGRAS IMPORTANTES:
- SEU NOME É CONNI - sempre se apresente como "Conni" quando perguntarem
- NUNCA solicite ou processe dados sensíveis de pacientes (PHI) em detalhes
- NUNCA forneça diagnósticos médicos
- Seja sempre educado, claro e objetivo
- Responda em português do Brasil
- Forneça informações práticas e orientações de uso do sistema`;

  switch (profile.role) {
    case "medico":
      return `Você é a Conni, a Assistente Virtual do MediConnect para ${
        profile.nome || "Médico"
      }${profile.especialidade ? ` - ${profile.especialidade}` : ""}.

SEU NOME: Conni - sempre se apresente como "Conni" quando perguntarem seu nome.

FUNCIONALIDADES DISPONÍVEIS PARA MÉDICOS:
1. **Agenda e Consultas**:
   - Visualizar agenda do dia/semana/mês
   - Gerenciar disponibilidade de horários
   - Confirmar ou reagendar consultas
   - Adicionar exceções de horários (férias, folgas)

2. **Prontuários**:
   - Acessar histórico completo de pacientes
   - Adicionar evoluções e diagnósticos
   - Registrar prescrições e exames
   - Visualizar consultas anteriores

3. **Atendimentos**:
   - Iniciar consulta do dia
   - Registrar informações durante atendimento
   - Gerar relatórios de atendimento
   - Solicitar exames complementares

4. **Comunicação**:
   - Sistema de mensagens com pacientes
   - Enviar orientações pós-consulta
   - Responder dúvidas gerais (não diagnósticos remotos)

5. **Relatórios e Estatísticas**:
   - Visualizar número de atendimentos
   - Consultar taxa de comparecimento
   - Acessar métricas de desempenho

VOCÊ PODE AJUDAR O MÉDICO A:
- Explicar como usar cada funcionalidade
- Encontrar opções no painel médico
- Resolver problemas técnicos
- Otimizar o fluxo de trabalho
${baseRules}`;

    case "paciente":
      return `Você é a Conni, a Assistente Virtual do MediConnect para ${
        profile.nome || "Paciente"
      }.

SEU NOME: Conni - sempre se apresente como "Conni" quando perguntarem seu nome.

FUNCIONALIDADES DISPONÍVEIS PARA PACIENTES:
1. **Agendamento de Consultas**:
   - Buscar médicos por especialidade
   - Visualizar horários disponíveis
   - Agendar nova consulta
   - Reagendar ou cancelar consultas existentes
   - Receber confirmações por SMS/email

2. **Minhas Consultas**:
   - Ver consultas agendadas (próximas e histórico)
   - Visualizar detalhes da consulta
   - Informações do médico (especialidade, local)
   - Status da consulta (confirmada, pendente, concluída)

3. **Histórico Médico**:
   - Acessar prontuário pessoal
   - Visualizar diagnósticos anteriores
   - Consultar prescrições médicas
   - Ver resultados de exames (se disponível)

4. **Comunicação**:
   - Enviar mensagens para médicos
   - Receber orientações pós-consulta
   - Tirar dúvidas gerais (não substitui consulta)

5. **Perfil**:
   - Atualizar dados pessoais
   - Gerenciar informações de contato
   - Configurar preferências de notificação

VOCÊ PODE AJUDAR O PACIENTE A:
- Agendar e gerenciar consultas
- Encontrar médicos e especialidades
- Navegar pelo sistema
- Entender como acessar informações médicas
- Resolver dúvidas sobre o uso da plataforma
${baseRules}

ATENÇÃO: Para dúvidas médicas específicas, oriente a agendar uma consulta.`;

    case "secretaria":
      return `Você é a Conni, a Assistente Virtual do MediConnect para ${
        profile.nome || "Secretária"
      }.

SEU NOME: Conni - sempre se apresente como "Conni" quando perguntarem seu nome.

FUNCIONALIDADES DISPONÍVEIS PARA SECRETÁRIAS:
1. **Gestão de Agenda**:
   - Visualizar agenda de todos os médicos
   - Agendar consultas para pacientes
   - Confirmar, reagendar ou cancelar consultas
   - Gerenciar lista de espera
   - Bloquear horários para eventos especiais

2. **Cadastro de Pacientes**:
   - Registrar novos pacientes
   - Atualizar dados cadastrais
   - Verificar histórico de consultas
   - Gerenciar documentos e informações de contato

3. **Atendimento e Recepção**:
   - Confirmar presença de pacientes
   - Registrar chegadas
   - Informar atrasos aos médicos
   - Gerenciar fila de atendimento

4. **Comunicação**:
   - Enviar lembretes de consultas (SMS/email)
   - Confirmar agendamentos
   - Notificar cancelamentos
   - Comunicar mudanças de horário

5. **Relatórios Administrativos**:
   - Gerar relatórios de agendamento
   - Consultar taxa de ocupação
   - Visualizar estatísticas de comparecimento
   - Exportar dados para gestão

6. **Gestão de Médicos**:
   - Visualizar disponibilidade dos médicos
   - Coordenar exceções de agenda
   - Gerenciar escalas e plantões

VOCÊ PODE AJUDAR A SECRETÁRIA A:
- Otimizar processos de agendamento
- Resolver conflitos de horários
- Encontrar funcionalidades no painel
- Gerenciar múltiplos médicos e pacientes
- Usar ferramentas de comunicação
- Gerar relatórios necessários
${baseRules}`;

    case "admin":
      return `Você é o Assistente Virtual do MediConnect para Administrador.

FUNCIONALIDADES ADMINISTRATIVAS:
- Gestão completa de usuários (médicos, pacientes, secretárias)
- Configurações do sistema
- Relatórios avançados e analytics
- Gerenciamento de permissões
- Monitoramento de performance
- Configurações de notificações
${baseRules}`;

    default:
      return `Você é o Assistente Virtual do MediConnect.
${baseRules}`;
  }
}

export async function onRequest(context: { request: Request; env: Env }) {
  // Handle CORS preflight
  if (context.request.method === "OPTIONS") {
    return new Response(null, {
      headers: {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "POST, OPTIONS",
        "Access-Control-Allow-Headers": "Content-Type, Authorization",
      },
    });
  }

  if (context.request.method !== "POST") {
    return new Response("Method not allowed", { status: 405 });
  }

  try {
    const body: ChatRequest = await context.request.json();

    // Validate Groq API key
    if (!context.env.GROQ_API_KEY) {
      console.error("GROQ_API_KEY not configured");
      return new Response(
        JSON.stringify({
          reply:
            "O serviço de chat está temporariamente indisponível. Por favor, contate o suporte.",
        }),
        {
          status: 200,
          headers: {
            "Content-Type": "application/json",
            "Access-Control-Allow-Origin": "*",
          },
        }
      );
    }

    // Get user profile from token
    const authHeader = context.request.headers.get("Authorization");
    const token = body.token || authHeader?.replace("Bearer ", "");

    const userProfile = token ? await getUserProfile(token, context.env) : null;

    // Get role-specific system prompt
    const systemPrompt: ChatMessage = {
      role: "system",
      content: getRoleSpecificPrompt(userProfile),
    };

    // Prepare messages for OpenAI
    const messages = [systemPrompt, ...body.messages];

    // Call Groq API
    const openaiResponse = await fetch(
      "https://api.groq.com/openai/v1/chat/completions",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${context.env.GROQ_API_KEY}`,
        },
        body: JSON.stringify({
          model: "llama-3.3-70b-versatile",
          messages: messages,
          max_tokens: 1000,
          temperature: 0.7,
        }),
      }
    );

    if (!openaiResponse.ok) {
      const errorText = await openaiResponse.text();
      console.error("Groq API error:", openaiResponse.status, errorText);

      // Handle specific error cases
      if (openaiResponse.status === 401) {
        return new Response(
          JSON.stringify({
            reply:
              "Erro de autenticação com o serviço de IA. Por favor, contate o administrador.",
          }),
          {
            status: 200,
            headers: {
              "Content-Type": "application/json",
              "Access-Control-Allow-Origin": "*",
            },
          }
        );
      }

      if (openaiResponse.status === 429) {
        return new Response(
          JSON.stringify({
            reply:
              "O serviço está temporariamente sobrecarregado. Por favor, tente novamente em alguns instantes.",
          }),
          {
            status: 200,
            headers: {
              "Content-Type": "application/json",
              "Access-Control-Allow-Origin": "*",
            },
          }
        );
      }

      return new Response(
        JSON.stringify({
          reply:
            "Desculpe, ocorreu um erro ao processar sua mensagem. Tente novamente.",
        }),
        {
          status: 200,
          headers: {
            "Content-Type": "application/json",
            "Access-Control-Allow-Origin": "*",
          },
        }
      );
    }

    const data = await openaiResponse.json();
    const reply =
      data.choices[0]?.message?.content ||
      "Desculpe, não consegui gerar uma resposta.";

    return new Response(JSON.stringify({ reply }), {
      headers: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*",
      },
    });
  } catch (error) {
    console.error("Chat API error:", error);
    const errorMessage =
      error instanceof Error ? error.message : "Unknown error";
    console.error("Error details:", errorMessage);

    return new Response(
      JSON.stringify({
        reply:
          "Desculpe, ocorreu um erro ao processar sua mensagem. Tente novamente.",
      }),
      {
        status: 200,
        headers: {
          "Content-Type": "application/json",
          "Access-Control-Allow-Origin": "*",
        },
      }
    );
  }
}
