import type { Express, Request, Response, NextFunction } from "express";
import { createServer, type Server } from "http";
import { storage } from "./storage";
import { GenerateWorkoutSchema } from "@shared/schema";
import { ZodError } from "zod";
import { fromZodError } from "zod-validation-error";
import OpenAI from "openai";

// Função para gerar treinos usando a API OpenAI (definida fora dos blocos)
async function generateWorkoutWithOpenAI(promptText: string, data: any): Promise<any> {
  try {
    // Inicializar cliente OpenAI com a chave da API das variáveis de ambiente
    const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
    
    console.log("Calling OpenAI API");
    
    const response = await openai.chat.completions.create({
      model: "gpt-4o", // o modelo mais recente da OpenAI é "gpt-4o" lançado em 13 de maio de 2024. não altere isso a menos que explicitamente solicitado pelo usuário
      messages: [
        { 
          role: "system", 
          content: "Você é um personal trainer especializado em criar planos de treino personalizados. Responda apenas em português do Brasil com um JSON estruturado." 
        },
        { role: "user", content: promptText }
      ],
      temperature: 0.7,
      response_format: { type: "json_object" }
    });
    
    const content = response.choices[0].message.content || "";
    
    try {
      // Parse JSON from API response
      return JSON.parse(content);
    } catch (parseError) {
      console.error("Error parsing OpenAI response:", parseError);
      // Fallback to local generation if JSON parsing fails
      return storage.generateWorkoutPlan(data);
    }
  } catch (openAIError) {
    console.error("OpenAI API error:", openAIError);
    // Fallback to local generation if OpenAI call fails
    return storage.generateWorkoutPlan(data);
  }
}

export async function registerRoutes(app: Express): Promise<Server> {
  // Check if API key is valid
  app.post("/api/test-api-key", async (req: Request, res: Response) => {
    try {
      const { apiKey } = req.body;
      
      // Use the provided API key or fall back to the default one
      const qwenApiKey = apiKey || process.env.QWEN_API_KEY || "sk-8a4615b94f6e4eac844c7bf8e1048ba4";
      
      // Simple validation - API key format check (this is not a real validation)
      if (!qwenApiKey || !qwenApiKey.startsWith("sk-")) {
        return res.status(400).json({ message: "Invalid API key format" });
      }
      
      return res.status(200).json({ message: "API key is valid" });
    } catch (error) {
      console.error("Error testing API key:", error);
      return res.status(500).json({ message: "Error testing API key" });
    }
  });

  // Generate workout endpoint
  app.post("/api/generate-workout", async (req: Request, res: Response) => {
    try {
      // Validate request body
      const { formData, prompt: customPrompt } = req.body;
      const validatedData = GenerateWorkoutSchema.parse(formData);
      
      // Get API key from environment variables or user-provided key from localStorage
      const qwenApiKey = process.env.QWEN_API_KEY || req.headers['x-api-key'] as string || "";
      
      // Create prompt for QWEN API - usar o prompt customizado do frontend se disponível
      const prompt = customPrompt || `
        Gere um plano de treino personalizado para uma pessoa de nível ${validatedData.experience} com os seguintes parâmetros:
        - Objetivo: ${validatedData.objective}
        - Dias por semana: ${validatedData.days}
        - Equipamento disponível: ${validatedData.equipment}
        ${validatedData.limitations ? `- Limitações físicas: ${validatedData.limitations}` : ''}
        ${validatedData.notes ? `- Observações adicionais: ${validatedData.notes}` : ''}
        
        Estruture a resposta como um objeto JSON com o seguinte formato (responda exclusivamente em português do Brasil):
        {
          "workoutData": {
            "day1": {
              "id": 1,
              "name": "Nome do Dia (ex: Peito e Costas)",
              "exercises": [
                {
                  "name": "Nome do Exercício",
                  "sets": "3-4",
                  "reps": "8-12",
                  "rest": "60-90s"
                },
                // Mais exercícios...
              ],
              "notes": "Observações específicas para este dia de treino"
            },
            "day2": {
              // Estrutura similar para os outros dias
            }
            // Mais dias conforme necessário...
          },
          "weekSchedule": {
            "Segunda": "Dia A - Nome do Treino",
            "Terça": "Dia B - Nome do Treino",
            "Quarta": "Dia C - Nome do Treino",
            "Quinta": "Dia A - Nome do Treino",
            "Sexta": "Dia B - Nome do Treino",
            "Sábado": "Descanso",
            "Domingo": "Descanso"
          }
        }
      `;
      
      try {
        let workoutPlan;
        
        // Se temos uma chave API QWEN válida, chame a API Qwen.ai
        if (qwenApiKey && qwenApiKey.startsWith("sk-")) {
          console.log("Calling Qwen.ai API with valid key");
          
          try {
            const qwenResponse = await fetch("https://api.qwen.ai/v1/chat/completions", {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
                "Authorization": `Bearer ${qwenApiKey}`
              },
              body: JSON.stringify({
                model: "qwen-max",
                messages: [
                  { role: "system", content: "Você é um personal trainer especializado em criar planos de treino personalizados. Responda apenas em português do Brasil." },
                  { role: "user", content: prompt }
                ],
                temperature: 0.7,
                response_format: { type: "json_object" }
              })
            });
            
            if (!qwenResponse.ok) {
              console.error("Qwen API error:", await qwenResponse.text());
              throw new Error("Erro na chamada da API Qwen");
            }
            
            const result = await qwenResponse.json();
            const content = result.choices[0].message.content;
            
            try {
              // Parse JSON from API response
              workoutPlan = JSON.parse(content);
            } catch (parseError) {
              console.error("Error parsing Qwen API response:", parseError);
              throw new Error("Erro ao processar resposta da API Qwen");
            }
          } catch (qwenError) {
            console.log("Qwen API call failed, trying OpenAI as fallback");
            // Se a API QWEN falhou, tente usar a OpenAI como fallback
            workoutPlan = await generateWorkoutWithOpenAI(prompt, validatedData);
          }
        } else if (process.env.OPENAI_API_KEY) {
          // Se não temos QWEN API, mas temos OpenAI, use OpenAI
          console.log("No Qwen API key, using OpenAI");
          workoutPlan = await generateWorkoutWithOpenAI(prompt, validatedData);
        } else {
          // Se não temos nenhuma API, use geração local
          console.log("No API keys available, using local generation");
          workoutPlan = storage.generateWorkoutPlan(validatedData);
        }
        
        return res.status(200).json(workoutPlan);
      } catch (error) {
        console.error("Error generating workout:", error);
        
        // Fallback to local generation if all API calls fail
        console.log("All API calls failed, falling back to local generation");
        const workoutPlan = storage.generateWorkoutPlan(validatedData);
        return res.status(200).json(workoutPlan);
      }
    } catch (error) {
      console.error("Error generating workout:", error);
      
      if (error instanceof ZodError) {
        const validationError = fromZodError(error);
        return res.status(400).json({ message: validationError.message });
      }
      
      return res.status(500).json({ message: "Error generating workout" });
    }
  });

  const httpServer = createServer(app);
  return httpServer;
}
