import { users, type User, type InsertUser, type GenerateWorkoutSchema } from "@shared/schema";
import { z } from "zod";

// modify the interface with any CRUD methods
// you might need
export interface IStorage {
  getUser(id: number): Promise<User | undefined>;
  getUserByUsername(username: string): Promise<User | undefined>;
  createUser(user: InsertUser): Promise<User>;
  generateWorkoutPlan(formData: z.infer<typeof GenerateWorkoutSchema>): any;
}

export class MemStorage implements IStorage {
  private users: Map<number, User>;
  currentId: number;

  constructor() {
    this.users = new Map();
    this.currentId = 1;
  }

  async getUser(id: number): Promise<User | undefined> {
    return this.users.get(id);
  }

  async getUserByUsername(username: string): Promise<User | undefined> {
    return Array.from(this.users.values()).find(
      (user) => user.username === username,
    );
  }

  async createUser(insertUser: InsertUser): Promise<User> {
    const id = this.currentId++;
    const user: User = { ...insertUser, id };
    this.users.set(id, user);
    return user;
  }

  generateWorkoutPlan(formData: z.infer<typeof GenerateWorkoutSchema>) {
    // This is a simplified workout generator for demonstration
    // In a real application, you would use the Qwen.ai API to generate the workout plan
    
    // Define the workout split based on days and experience
    const days = parseInt(formData.days.toString());
    const experience = formData.experience;
    let split: string[] = [];
    
    if (days <= 2) {
      // AB split for beginners or 1-2 days
      split = ["A", "B"];
    } else if (days <= 6) {
      // ABC split for 3-6 days
      split = ["A", "B", "C"];
    } else {
      // ABCD split for 7 days
      split = ["A", "B", "C", "D"];
    }
    
    // Create workout data structure
    const workoutData: Record<string, any> = {};
    
    // Assign day names based on split
    const dayNames: Record<string, string> = {
      "A": days <= 2 ? "Full Body" : "Chest & Back",
      "B": days <= 2 ? "Cardio & Core" : "Legs & Core",
      "C": "Shoulders & Arms",
      "D": "Full Body Functional"
    };
    
    // Generate exercise list for each day
    for (const day of split) {
      // Create a list of exercises for the day
      const exercises = this.getExercisesForDay(day, formData.equipment, formData.experience);
      
      workoutData[day] = {
        id: day,
        name: dayNames[day],
        exercises
      };
    }
    
    // Generate trainer notes
    const notes = this.generateTrainerNotes(formData);
    
    return {
      workoutData,
      notes
    };
  }
  
  private getExercisesForDay(day: string, equipment: string, experience: string) {
    // Sample exercises based on workout day and equipment
    const exerciseTemplates: Record<string, Array<any>> = {
      "A": [ // Chest & Back Day
        { name: "Bench Press", target: "Chest", sets: "4", reps: "8-10", rest: "90 sec" },
        { name: "Lat Pulldown", target: "Upper Back", sets: "4", reps: "10-12", rest: "60 sec" },
        { name: "Dumbbell Chest Fly", target: "Inner Chest", sets: "3", reps: "12-15", rest: "45 sec" },
        { name: "Cable Seated Row", target: "Mid Back", sets: "4", reps: "10-12", rest: "60 sec" },
        { name: "Push-Ups", target: "Chest, Triceps", sets: "3", reps: "15-20", rest: "45 sec" }
      ],
      "B": [ // Legs & Core Day
        { name: "Barbell Squat", target: "Quadriceps, Glutes", sets: "4", reps: "8-10", rest: "120 sec" },
        { name: "Romanian Deadlift", target: "Hamstrings", sets: "3", reps: "10-12", rest: "90 sec" },
        { name: "Leg Press", target: "Quadriceps", sets: "3", reps: "12-15", rest: "60 sec" },
        { name: "Plank", target: "Core", sets: "3", reps: "30-60 sec", rest: "45 sec" },
        { name: "Calf Raises", target: "Calves", sets: "4", reps: "15-20", rest: "30 sec" }
      ],
      "C": [ // Shoulders & Arms Day
        { name: "Overhead Press", target: "Shoulders", sets: "4", reps: "8-10", rest: "90 sec" },
        { name: "Bicep Curls", target: "Biceps", sets: "3", reps: "10-12", rest: "60 sec" },
        { name: "Tricep Pushdowns", target: "Triceps", sets: "3", reps: "12-15", rest: "60 sec" },
        { name: "Lateral Raises", target: "Side Delts", sets: "3", reps: "12-15", rest: "45 sec" },
        { name: "Face Pulls", target: "Rear Delts", sets: "3", reps: "15-20", rest: "45 sec" }
      ],
      "D": [ // Full Body Functional Day
        { name: "Deadlift", target: "Back, Hamstrings", sets: "4", reps: "6-8", rest: "120 sec" },
        { name: "Pull-Ups", target: "Back, Biceps", sets: "3", reps: "8-12", rest: "90 sec" },
        { name: "Lunges", target: "Quadriceps, Glutes", sets: "3", reps: "10-12 each", rest: "60 sec" },
        { name: "Dips", target: "Chest, Triceps", sets: "3", reps: "10-15", rest: "60 sec" },
        { name: "Medicine Ball Slams", target: "Full Body", sets: "3", reps: "15-20", rest: "45 sec" }
      ]
    };
    
    // Adjust for equipment type
    if (equipment === "bodyweight") {
      return this.getBodyweightExercises(day);
    } else if (equipment === "dumbbells_only") {
      return this.getDumbbellExercises(day);
    } else if (equipment === "resistance_bands") {
      return this.getResistanceBandExercises(day);
    } else if (equipment === "home_basic") {
      return this.getHomeExercises(day);
    }
    
    // Assign IDs to exercises
    return exerciseTemplates[day].map((exercise, index) => ({
      id: `${day}-ex${index + 1}`,
      ...exercise
    }));
  }
  
  private getBodyweightExercises(day: string) {
    // Bodyweight exercise variations
    const bodyweightExercises: Record<string, Array<any>> = {
      "A": [
        { name: "Push-Ups", target: "Chest, Triceps", sets: "4", reps: "10-15", rest: "60 sec" },
        { name: "Pull-Ups", target: "Back, Biceps", sets: "4", reps: "8-10", rest: "90 sec" },
        { name: "Dips", target: "Chest, Triceps", sets: "3", reps: "8-12", rest: "60 sec" },
        { name: "Superman Holds", target: "Lower Back", sets: "3", reps: "20-30 sec", rest: "45 sec" },
        { name: "Diamond Push-Ups", target: "Inner Chest, Triceps", sets: "3", reps: "10-15", rest: "60 sec" }
      ],
      "B": [
        { name: "Bodyweight Squats", target: "Quadriceps, Glutes", sets: "4", reps: "15-20", rest: "60 sec" },
        { name: "Lunges", target: "Quadriceps, Glutes", sets: "3", reps: "12-15 each", rest: "60 sec" },
        { name: "Mountain Climbers", target: "Core, Cardio", sets: "3", reps: "30 sec", rest: "30 sec" },
        { name: "Glute Bridges", target: "Glutes, Hamstrings", sets: "3", reps: "15-20", rest: "45 sec" },
        { name: "Calf Raises", target: "Calves", sets: "4", reps: "20-25", rest: "30 sec" }
      ],
      "C": [
        { name: "Pike Push-Ups", target: "Shoulders", sets: "4", reps: "10-12", rest: "60 sec" },
        { name: "Chin-Ups", target: "Biceps, Back", sets: "3", reps: "8-10", rest: "90 sec" },
        { name: "Tricep Dips", target: "Triceps", sets: "3", reps: "12-15", rest: "60 sec" },
        { name: "Shoulder Taps", target: "Shoulders, Core", sets: "3", reps: "12-15 each", rest: "45 sec" },
        { name: "Plank to Push-Up", target: "Core, Shoulders", sets: "3", reps: "8-10 each", rest: "45 sec" }
      ],
      "D": [
        { name: "Burpees", target: "Full Body", sets: "4", reps: "10-15", rest: "60 sec" },
        { name: "Jump Squats", target: "Legs, Cardio", sets: "3", reps: "12-15", rest: "45 sec" },
        { name: "Mountain Climbers", target: "Core, Cardio", sets: "3", reps: "30 sec", rest: "30 sec" },
        { name: "Plank", target: "Core", sets: "3", reps: "45-60 sec", rest: "30 sec" },
        { name: "High Knees", target: "Cardio, Core", sets: "3", reps: "30 sec", rest: "30 sec" }
      ]
    };
    
    return bodyweightExercises[day].map((exercise, index) => ({
      id: `${day}-ex${index + 1}`,
      ...exercise
    }));
  }
  
  private getDumbbellExercises(day: string) {
    // Dumbbell exercise variations
    const dumbbellExercises: Record<string, Array<any>> = {
      "A": [
        { name: "Dumbbell Bench Press", target: "Chest", sets: "4", reps: "8-10", rest: "90 sec" },
        { name: "Dumbbell Rows", target: "Back", sets: "4", reps: "10-12", rest: "60 sec" },
        { name: "Dumbbell Chest Fly", target: "Inner Chest", sets: "3", reps: "12-15", rest: "45 sec" },
        { name: "Dumbbell Pullovers", target: "Lats, Chest", sets: "3", reps: "10-12", rest: "60 sec" },
        { name: "Push-Ups", target: "Chest, Triceps", sets: "3", reps: "12-15", rest: "45 sec" }
      ],
      "B": [
        { name: "Dumbbell Squats", target: "Quadriceps, Glutes", sets: "4", reps: "10-12", rest: "90 sec" },
        { name: "Dumbbell Romanian Deadlift", target: "Hamstrings", sets: "3", reps: "10-12", rest: "60 sec" },
        { name: "Dumbbell Lunges", target: "Quadriceps, Glutes", sets: "3", reps: "10-12 each", rest: "60 sec" },
        { name: "Dumbbell Russian Twist", target: "Obliques", sets: "3", reps: "12-15 each", rest: "45 sec" },
        { name: "Dumbbell Calf Raises", target: "Calves", sets: "4", reps: "15-20", rest: "30 sec" }
      ],
      "C": [
        { name: "Dumbbell Shoulder Press", target: "Shoulders", sets: "4", reps: "8-10", rest: "90 sec" },
        { name: "Dumbbell Bicep Curls", target: "Biceps", sets: "3", reps: "10-12", rest: "60 sec" },
        { name: "Dumbbell Tricep Extensions", target: "Triceps", sets: "3", reps: "12-15", rest: "60 sec" },
        { name: "Dumbbell Lateral Raises", target: "Side Delts", sets: "3", reps: "12-15", rest: "45 sec" },
        { name: "Dumbbell Front Raises", target: "Front Delts", sets: "3", reps: "12-15", rest: "45 sec" }
      ],
      "D": [
        { name: "Dumbbell Thrusters", target: "Full Body", sets: "4", reps: "10-12", rest: "60 sec" },
        { name: "Renegade Rows", target: "Back, Core", sets: "3", reps: "8-10 each", rest: "60 sec" },
        { name: "Dumbbell Clean & Press", target: "Full Body", sets: "3", reps: "8-10", rest: "90 sec" },
        { name: "Dumbbell Farmer's Walk", target: "Grip, Core", sets: "3", reps: "40-50 steps", rest: "60 sec" },
        { name: "Dumbbell Deadlifts", target: "Back, Hamstrings", sets: "3", reps: "10-12", rest: "60 sec" }
      ]
    };
    
    return dumbbellExercises[day].map((exercise, index) => ({
      id: `${day}-ex${index + 1}`,
      ...exercise
    }));
  }
  
  private getResistanceBandExercises(day: string) {
    // Resistance band exercise variations
    const bandExercises: Record<string, Array<any>> = {
      "A": [
        { name: "Band Push-Ups", target: "Chest", sets: "4", reps: "10-12", rest: "60 sec" },
        { name: "Band Rows", target: "Back", sets: "4", reps: "12-15", rest: "60 sec" },
        { name: "Band Chest Fly", target: "Inner Chest", sets: "3", reps: "15-20", rest: "45 sec" },
        { name: "Band Pull-Aparts", target: "Upper Back", sets: "3", reps: "15-20", rest: "45 sec" },
        { name: "Band Push-Downs", target: "Triceps", sets: "3", reps: "15-20", rest: "45 sec" }
      ],
      "B": [
        { name: "Band Squats", target: "Quadriceps, Glutes", sets: "4", reps: "15-20", rest: "60 sec" },
        { name: "Band Deadlifts", target: "Hamstrings, Back", sets: "3", reps: "12-15", rest: "60 sec" },
        { name: "Band Lateral Walks", target: "Glutes", sets: "3", reps: "12-15 each", rest: "45 sec" },
        { name: "Band Leg Curls", target: "Hamstrings", sets: "3", reps: "15-20", rest: "45 sec" },
        { name: "Band Calf Raises", target: "Calves", sets: "4", reps: "20-25", rest: "30 sec" }
      ],
      "C": [
        { name: "Band Shoulder Press", target: "Shoulders", sets: "4", reps: "12-15", rest: "60 sec" },
        { name: "Band Bicep Curls", target: "Biceps", sets: "3", reps: "15-20", rest: "45 sec" },
        { name: "Band Tricep Extensions", target: "Triceps", sets: "3", reps: "15-20", rest: "45 sec" },
        { name: "Band Lateral Raises", target: "Side Delts", sets: "3", reps: "15-20", rest: "45 sec" },
        { name: "Band Face Pulls", target: "Rear Delts", sets: "3", reps: "15-20", rest: "45 sec" }
      ],
      "D": [
        { name: "Band Jumping Jacks", target: "Full Body", sets: "4", reps: "20-25", rest: "45 sec" },
        { name: "Band Woodchoppers", target: "Core, Obliques", sets: "3", reps: "12-15 each", rest: "45 sec" },
        { name: "Band Overhead Press", target: "Shoulders", sets: "3", reps: "12-15", rest: "60 sec" },
        { name: "Band Russian Twists", target: "Obliques", sets: "3", reps: "15-20 each", rest: "45 sec" },
        { name: "Band Mountain Climbers", target: "Core, Cardio", sets: "3", reps: "30 sec", rest: "30 sec" }
      ]
    };
    
    return bandExercises[day].map((exercise, index) => ({
      id: `${day}-ex${index + 1}`,
      ...exercise
    }));
  }
  
  private getHomeExercises(day: string) {
    // Home basic equipment exercise variations
    const homeExercises: Record<string, Array<any>> = {
      "A": [
        { name: "Push-Ups (Varied Grip)", target: "Chest, Triceps", sets: "4", reps: "12-15", rest: "60 sec" },
        { name: "Dumbbell Rows", target: "Back", sets: "4", reps: "10-12", rest: "60 sec" },
        { name: "Dumbbell Chest Press", target: "Chest", sets: "3", reps: "10-12", rest: "60 sec" },
        { name: "Resistance Band Lat Pulldowns", target: "Upper Back", sets: "3", reps: "12-15", rest: "45 sec" },
        { name: "Close Grip Push-Ups", target: "Inner Chest, Triceps", sets: "3", reps: "12-15", rest: "45 sec" }
      ],
      "B": [
        { name: "Goblet Squats", target: "Quadriceps, Glutes", sets: "4", reps: "12-15", rest: "60 sec" },
        { name: "Dumbbell Romanian Deadlift", target: "Hamstrings", sets: "3", reps: "10-12", rest: "60 sec" },
        { name: "Walking Lunges", target: "Quads, Glutes", sets: "3", reps: "12 each", rest: "60 sec" },
        { name: "Russian Twists", target: "Obliques", sets: "3", reps: "15 each", rest: "45 sec" },
        { name: "Calf Raises", target: "Calves", sets: "4", reps: "20", rest: "30 sec" }
      ],
      "C": [
        { name: "Dumbbell Shoulder Press", target: "Shoulders", sets: "4", reps: "10-12", rest: "60 sec" },
        { name: "Dumbbell Curls", target: "Biceps", sets: "3", reps: "12-15", rest: "45 sec" },
        { name: "Tricep Dips", target: "Triceps", sets: "3", reps: "12-15", rest: "45 sec" },
        { name: "Lateral Raises", target: "Side Delts", sets: "3", reps: "12-15", rest: "45 sec" },
        { name: "Rear Delt Flys", target: "Rear Delts", sets: "3", reps: "12-15", rest: "45 sec" }
      ],
      "D": [
        { name: "Burpees", target: "Full Body", sets: "4", reps: "10-15", rest: "45 sec" },
        { name: "Dumbbell Thrusters", target: "Full Body", sets: "3", reps: "10-12", rest: "60 sec" },
        { name: "Mountain Climbers", target: "Core, Cardio", sets: "3", reps: "30 sec", rest: "30 sec" },
        { name: "Plank", target: "Core", sets: "3", reps: "45-60 sec", rest: "30 sec" },
        { name: "Jump Squats", target: "Legs, Cardio", sets: "3", reps: "15", rest: "45 sec" }
      ]
    };
    
    return homeExercises[day].map((exercise, index) => ({
      id: `${day}-ex${index + 1}`,
      ...exercise
    }));
  }
  
  private generateTrainerNotes(formData: z.infer<typeof GenerateWorkoutSchema>) {
    // Generate trainer notes based on the form data
    const objective = formData.objective;
    const experience = formData.experience;
    const equipment = formData.equipment;
    
    let notes = "";
    
    if (objective === "muscle_gain") {
      notes = "This workout focuses on progressive overload to stimulate muscle growth. Ensure proper nutrition with a caloric surplus and adequate protein intake (1.6-2g/kg of bodyweight). Rest 48-72 hours between training the same muscle group.";
    } else if (objective === "fat_loss") {
      notes = "This workout combines resistance training with shorter rest periods to maximize calorie burn. Complement with proper nutrition in a slight caloric deficit (300-500 calories below maintenance) and include 2-3 cardio sessions per week.";
    } else if (objective === "strength") {
      notes = "This strength-focused program emphasizes compound movements with heavier weights. Focus on perfect form, and consider using a spotter for heavier sets. Track your progress and aim to increase weight gradually.";
    } else if (objective === "endurance") {
      notes = "This endurance program uses higher repetitions and shorter rest periods. Add 1-2 steady-state cardio sessions (30-45 minutes) per week to improve overall endurance capacity.";
    } else {
      notes = "This general fitness program provides a balanced approach to improve overall health and fitness. Focus on proper form and consistency rather than maximal weights. Add variety to your routine every 4-6 weeks to prevent plateaus.";
    }
    
    // Additional notes based on experience level
    if (experience === "beginner") {
      notes += " As a beginner, focus on learning proper technique before adding weight. Start with lighter weights and increase gradually as your form improves.";
    } else if (experience === "intermediate") {
      notes += " At your intermediate level, focus on progressive overload and periodization to continue making gains. Monitor your recovery and adjust training volume as needed.";
    } else {
      notes += " At your advanced level, consider incorporating techniques like drop sets, supersets, and periodization to overcome plateaus. Pay close attention to recovery and consider deload weeks every 6-8 weeks.";
    }
    
    // Equipment specific notes
    if (equipment === "bodyweight") {
      notes += " With bodyweight training, focus on increasing repetitions, decreasing rest times, or using more challenging variations to progress.";
    } else if (equipment === "dumbbells_only") {
      notes += " With dumbbells, you can still perform most major movement patterns. Focus on unilateral (single-arm/leg) exercises to address imbalances.";
    } else if (equipment === "resistance_bands") {
      notes += " Resistance bands provide variable resistance throughout the range of motion. Ensure proper anchoring and maintain tension throughout each movement.";
    } else if (equipment === "home_basic") {
      notes += " Make the most of your limited equipment by focusing on exercise variations and adjusting tempo, rest periods, and volume to progress.";
    }
    
    return notes;
  }
}

export const storage = new MemStorage();
